Page MenuHomec4science

No OneTemporary

File Metadata

Created
Thu, Apr 17, 18:19
This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/doc/Eqs/angle_charmm.jpg b/doc/Eqs/angle_charmm.jpg
index 430fff27c..c6e6c297d 100644
Binary files a/doc/Eqs/angle_charmm.jpg and b/doc/Eqs/angle_charmm.jpg differ
diff --git a/doc/Eqs/angle_class2.jpg b/doc/Eqs/angle_class2.jpg
index 02c873d0c..f0f2a5152 100644
Binary files a/doc/Eqs/angle_class2.jpg and b/doc/Eqs/angle_class2.jpg differ
diff --git a/doc/Eqs/angle_cosine.jpg b/doc/Eqs/angle_cosine.jpg
index 891aeab6e..23b9b6431 100644
Binary files a/doc/Eqs/angle_cosine.jpg and b/doc/Eqs/angle_cosine.jpg differ
diff --git a/doc/Eqs/angle_cosine_delta.jpg b/doc/Eqs/angle_cosine_delta.jpg
index dca7d7393..e39b62471 100644
Binary files a/doc/Eqs/angle_cosine_delta.jpg and b/doc/Eqs/angle_cosine_delta.jpg differ
diff --git a/doc/Eqs/angle_cosine_periodic.jpg b/doc/Eqs/angle_cosine_periodic.jpg
index 32bbaf88b..a9d7d50cb 100644
Binary files a/doc/Eqs/angle_cosine_periodic.jpg and b/doc/Eqs/angle_cosine_periodic.jpg differ
diff --git a/doc/Eqs/angle_cosine_shift.jpg b/doc/Eqs/angle_cosine_shift.jpg
index 1f0bb5685..d9929939c 100644
Binary files a/doc/Eqs/angle_cosine_shift.jpg and b/doc/Eqs/angle_cosine_shift.jpg differ
diff --git a/doc/Eqs/angle_cosine_shift_exp.jpg b/doc/Eqs/angle_cosine_shift_exp.jpg
index 1a3cc05bd..294986de4 100644
Binary files a/doc/Eqs/angle_cosine_shift_exp.jpg and b/doc/Eqs/angle_cosine_shift_exp.jpg differ
diff --git a/doc/Eqs/angle_cosine_squared.jpg b/doc/Eqs/angle_cosine_squared.jpg
index 71cf80d91..b992398b7 100644
Binary files a/doc/Eqs/angle_cosine_squared.jpg and b/doc/Eqs/angle_cosine_squared.jpg differ
diff --git a/doc/Eqs/angle_harmonic.jpg b/doc/Eqs/angle_harmonic.jpg
index ef27177d7..352be0b54 100644
Binary files a/doc/Eqs/angle_harmonic.jpg and b/doc/Eqs/angle_harmonic.jpg differ
diff --git a/doc/Eqs/bond_class2.jpg b/doc/Eqs/bond_class2.jpg
index 7fb129bdb..493048100 100644
Binary files a/doc/Eqs/bond_class2.jpg and b/doc/Eqs/bond_class2.jpg differ
diff --git a/doc/Eqs/bond_fene.jpg b/doc/Eqs/bond_fene.jpg
index b4360f7b3..e8b909c08 100644
Binary files a/doc/Eqs/bond_fene.jpg and b/doc/Eqs/bond_fene.jpg differ
diff --git a/doc/Eqs/bond_fene_expand.jpg b/doc/Eqs/bond_fene_expand.jpg
index 72854dfa6..1d04acec3 100644
Binary files a/doc/Eqs/bond_fene_expand.jpg and b/doc/Eqs/bond_fene_expand.jpg differ
diff --git a/doc/Eqs/bond_harmonic.jpg b/doc/Eqs/bond_harmonic.jpg
index 3180399a0..fe9ef5619 100644
Binary files a/doc/Eqs/bond_harmonic.jpg and b/doc/Eqs/bond_harmonic.jpg differ
diff --git a/doc/Eqs/bond_harmonic_shift.jpg b/doc/Eqs/bond_harmonic_shift.jpg
index cac7bcdbb..3e66d853a 100644
Binary files a/doc/Eqs/bond_harmonic_shift.jpg and b/doc/Eqs/bond_harmonic_shift.jpg differ
diff --git a/doc/Eqs/bond_harmonic_shift_cut.jpg b/doc/Eqs/bond_harmonic_shift_cut.jpg
index 821db256d..06640e4fe 100644
Binary files a/doc/Eqs/bond_harmonic_shift_cut.jpg and b/doc/Eqs/bond_harmonic_shift_cut.jpg differ
diff --git a/doc/Eqs/bond_morse.jpg b/doc/Eqs/bond_morse.jpg
index 794a7e98d..6795c9e52 100644
Binary files a/doc/Eqs/bond_morse.jpg and b/doc/Eqs/bond_morse.jpg differ
diff --git a/doc/Eqs/bond_nonlinear.jpg b/doc/Eqs/bond_nonlinear.jpg
index 09020019a..0f18d8e73 100644
Binary files a/doc/Eqs/bond_nonlinear.jpg and b/doc/Eqs/bond_nonlinear.jpg differ
diff --git a/doc/Eqs/bond_quartic.jpg b/doc/Eqs/bond_quartic.jpg
index 4f333aefb..9d092883b 100644
Binary files a/doc/Eqs/bond_quartic.jpg and b/doc/Eqs/bond_quartic.jpg differ
diff --git a/doc/Eqs/box.jpg b/doc/Eqs/box.jpg
index df1c2bfce..4cb43df95 100644
Binary files a/doc/Eqs/box.jpg and b/doc/Eqs/box.jpg differ
diff --git a/doc/Eqs/box_inverse.jpg b/doc/Eqs/box_inverse.jpg
index 1815bba23..5d0895b87 100644
Binary files a/doc/Eqs/box_inverse.jpg and b/doc/Eqs/box_inverse.jpg differ
diff --git a/doc/Eqs/centro_symmetry.jpg b/doc/Eqs/centro_symmetry.jpg
index 4817ea14f..1e89d11a1 100644
Binary files a/doc/Eqs/centro_symmetry.jpg and b/doc/Eqs/centro_symmetry.jpg differ
diff --git a/doc/Eqs/cna_cutoff1.jpg b/doc/Eqs/cna_cutoff1.jpg
index 7f9526b43..fae5c6b63 100644
Binary files a/doc/Eqs/cna_cutoff1.jpg and b/doc/Eqs/cna_cutoff1.jpg differ
diff --git a/doc/Eqs/cna_cutoff2.jpg b/doc/Eqs/cna_cutoff2.jpg
index 1e6792d04..744b61e9b 100644
Binary files a/doc/Eqs/cna_cutoff2.jpg and b/doc/Eqs/cna_cutoff2.jpg differ
diff --git a/doc/Eqs/compute_gyration.jpg b/doc/Eqs/compute_gyration.jpg
index 0e195374f..228544443 100644
Binary files a/doc/Eqs/compute_gyration.jpg and b/doc/Eqs/compute_gyration.jpg differ
diff --git a/doc/Eqs/dihedral_charmm.jpg b/doc/Eqs/dihedral_charmm.jpg
index 5ab8a3555..810afa3cd 100644
Binary files a/doc/Eqs/dihedral_charmm.jpg and b/doc/Eqs/dihedral_charmm.jpg differ
diff --git a/doc/Eqs/dihedral_class2.jpg b/doc/Eqs/dihedral_class2.jpg
index c05090527..6a6780e76 100644
Binary files a/doc/Eqs/dihedral_class2.jpg and b/doc/Eqs/dihedral_class2.jpg differ
diff --git a/doc/Eqs/dihedral_cosine_shift_exp.jpg b/doc/Eqs/dihedral_cosine_shift_exp.jpg
index 646bb52a6..ea0a7550f 100644
Binary files a/doc/Eqs/dihedral_cosine_shift_exp.jpg and b/doc/Eqs/dihedral_cosine_shift_exp.jpg differ
diff --git a/doc/Eqs/dihedral_harmonic.jpg b/doc/Eqs/dihedral_harmonic.jpg
index 8a395b043..cb5c16a8c 100644
Binary files a/doc/Eqs/dihedral_harmonic.jpg and b/doc/Eqs/dihedral_harmonic.jpg differ
diff --git a/doc/Eqs/dihedral_helix.jpg b/doc/Eqs/dihedral_helix.jpg
index 073a18a9c..01a0ec982 100644
Binary files a/doc/Eqs/dihedral_helix.jpg and b/doc/Eqs/dihedral_helix.jpg differ
diff --git a/doc/Eqs/dihedral_multi_harmonic.jpg b/doc/Eqs/dihedral_multi_harmonic.jpg
index a53ae3dca..d066cd212 100644
Binary files a/doc/Eqs/dihedral_multi_harmonic.jpg and b/doc/Eqs/dihedral_multi_harmonic.jpg differ
diff --git a/doc/Eqs/dihedral_opls.jpg b/doc/Eqs/dihedral_opls.jpg
index 719a14ecb..0546aebfd 100644
Binary files a/doc/Eqs/dihedral_opls.jpg and b/doc/Eqs/dihedral_opls.jpg differ
diff --git a/doc/Eqs/eff_KE.jpg b/doc/Eqs/eff_KE.jpg
index 9fe9c0692..40eed0df6 100644
Binary files a/doc/Eqs/eff_KE.jpg and b/doc/Eqs/eff_KE.jpg differ
diff --git a/doc/Eqs/eff_NN.jpg b/doc/Eqs/eff_NN.jpg
index f70768bf1..c3c52e19b 100644
Binary files a/doc/Eqs/eff_NN.jpg and b/doc/Eqs/eff_NN.jpg differ
diff --git a/doc/Eqs/eff_Ne.jpg b/doc/Eqs/eff_Ne.jpg
index 1ce103df6..e23ceacc8 100644
Binary files a/doc/Eqs/eff_Ne.jpg and b/doc/Eqs/eff_Ne.jpg differ
diff --git a/doc/Eqs/eff_Pauli.jpg b/doc/Eqs/eff_Pauli.jpg
index 82b2c18c2..61bb8652e 100644
Binary files a/doc/Eqs/eff_Pauli.jpg and b/doc/Eqs/eff_Pauli.jpg differ
diff --git a/doc/Eqs/eff_ee.jpg b/doc/Eqs/eff_ee.jpg
index 25871e9b4..aef84d0fd 100644
Binary files a/doc/Eqs/eff_ee.jpg and b/doc/Eqs/eff_ee.jpg differ
diff --git a/doc/Eqs/eff_energy_expression.jpg b/doc/Eqs/eff_energy_expression.jpg
index e5ff7a185..e06fe8ff2 100644
Binary files a/doc/Eqs/eff_energy_expression.jpg and b/doc/Eqs/eff_energy_expression.jpg differ
diff --git a/doc/Eqs/fix_box_relax1.jpg b/doc/Eqs/fix_box_relax1.jpg
index a4b6dda6e..d42552604 100644
Binary files a/doc/Eqs/fix_box_relax1.jpg and b/doc/Eqs/fix_box_relax1.jpg differ
diff --git a/doc/Eqs/fix_box_relax2.jpg b/doc/Eqs/fix_box_relax2.jpg
index 5ab0dd93b..8fac42e0f 100644
Binary files a/doc/Eqs/fix_box_relax2.jpg and b/doc/Eqs/fix_box_relax2.jpg differ
diff --git a/doc/Eqs/fix_gyration.jpg b/doc/Eqs/fix_gyration.jpg
deleted file mode 100644
index 0e195374f..000000000
Binary files a/doc/Eqs/fix_gyration.jpg and /dev/null differ
diff --git a/doc/Eqs/fix_gyration.tex b/doc/Eqs/fix_gyration.tex
deleted file mode 100644
index 97204f1de..000000000
--- a/doc/Eqs/fix_gyration.tex
+++ /dev/null
@@ -1,9 +0,0 @@
-\documentstyle[12pt]{article}
-
-\begin{document}
-
-$$
- {R_g}^2 = \frac{1}{M} \sum_i m_i (r_i - r_{cm})^2
-$$
-
-\end{document}
\ No newline at end of file
diff --git a/doc/Eqs/fix_nh1.jpg b/doc/Eqs/fix_nh1.jpg
index 929f97a8c..db59dbc43 100644
Binary files a/doc/Eqs/fix_nh1.jpg and b/doc/Eqs/fix_nh1.jpg differ
diff --git a/doc/Eqs/fix_nphug.jpg b/doc/Eqs/fix_nphug.jpg
index beed5ed5c..a3a67e7b7 100644
Binary files a/doc/Eqs/fix_nphug.jpg and b/doc/Eqs/fix_nphug.jpg differ
diff --git a/doc/Eqs/fix_orient_fcc.jpg b/doc/Eqs/fix_orient_fcc.jpg
index 1645312d2..b22e6c9c2 100644
Binary files a/doc/Eqs/fix_orient_fcc.jpg and b/doc/Eqs/fix_orient_fcc.jpg differ
diff --git a/doc/Eqs/fix_spring_rg.jpg b/doc/Eqs/fix_spring_rg.jpg
index 421b39478..313844f55 100644
Binary files a/doc/Eqs/fix_spring_rg.jpg and b/doc/Eqs/fix_spring_rg.jpg differ
diff --git a/doc/Eqs/fix_ttm.jpg b/doc/Eqs/fix_ttm.jpg
index 68f7fdb12..8d9fac3fe 100644
Binary files a/doc/Eqs/fix_ttm.jpg and b/doc/Eqs/fix_ttm.jpg differ
diff --git a/doc/Eqs/fix_wall_colloid.jpg b/doc/Eqs/fix_wall_colloid.jpg
index df6b654ef..e18aa70cd 100644
Binary files a/doc/Eqs/fix_wall_colloid.jpg and b/doc/Eqs/fix_wall_colloid.jpg differ
diff --git a/doc/Eqs/fix_wall_harmonic.jpg b/doc/Eqs/fix_wall_harmonic.jpg
index fdf308b22..3c605690c 100644
Binary files a/doc/Eqs/fix_wall_harmonic.jpg and b/doc/Eqs/fix_wall_harmonic.jpg differ
diff --git a/doc/Eqs/fix_wall_lj93.jpg b/doc/Eqs/fix_wall_lj93.jpg
index 985a5c188..18e502cfb 100644
Binary files a/doc/Eqs/fix_wall_lj93.jpg and b/doc/Eqs/fix_wall_lj93.jpg differ
diff --git a/doc/Eqs/fld.jpg b/doc/Eqs/fld.jpg
index 6ae18718d..3d80d436f 100644
Binary files a/doc/Eqs/fld.jpg and b/doc/Eqs/fld.jpg differ
diff --git a/doc/Eqs/fld2.jpg b/doc/Eqs/fld2.jpg
index ff88680b7..42de943c9 100644
Binary files a/doc/Eqs/fld2.jpg and b/doc/Eqs/fld2.jpg differ
diff --git a/doc/Eqs/heat_flux_J.jpg b/doc/Eqs/heat_flux_J.jpg
index 67633dad6..cf3e220ca 100644
Binary files a/doc/Eqs/heat_flux_J.jpg and b/doc/Eqs/heat_flux_J.jpg differ
diff --git a/doc/Eqs/heat_flux_k.jpg b/doc/Eqs/heat_flux_k.jpg
index f028e5245..2fd4a19e5 100644
Binary files a/doc/Eqs/heat_flux_k.jpg and b/doc/Eqs/heat_flux_k.jpg differ
diff --git a/doc/Eqs/improper_class2.jpg b/doc/Eqs/improper_class2.jpg
index 331f4ff8c..ca0604f8d 100644
Binary files a/doc/Eqs/improper_class2.jpg and b/doc/Eqs/improper_class2.jpg differ
diff --git a/doc/Eqs/improper_cvff.jpg b/doc/Eqs/improper_cvff.jpg
index 4b8b73b19..14be3ffa0 100644
Binary files a/doc/Eqs/improper_cvff.jpg and b/doc/Eqs/improper_cvff.jpg differ
diff --git a/doc/Eqs/improper_harmonic.jpg b/doc/Eqs/improper_harmonic.jpg
index 48252b24f..c2c1eb466 100644
Binary files a/doc/Eqs/improper_harmonic.jpg and b/doc/Eqs/improper_harmonic.jpg differ
diff --git a/doc/Eqs/improper_umbrella.jpg b/doc/Eqs/improper_umbrella.jpg
index efef6c06b..8d6cbf81e 100644
Binary files a/doc/Eqs/improper_umbrella.jpg and b/doc/Eqs/improper_umbrella.jpg differ
diff --git a/doc/Eqs/min_energy.jpg b/doc/Eqs/min_energy.jpg
index b949216a5..7925d268a 100644
Binary files a/doc/Eqs/min_energy.jpg and b/doc/Eqs/min_energy.jpg differ
diff --git a/doc/Eqs/pair_adp.jpg b/doc/Eqs/pair_adp.jpg
index c2ad8deb2..bc1b84703 100644
Binary files a/doc/Eqs/pair_adp.jpg and b/doc/Eqs/pair_adp.jpg differ
diff --git a/doc/Eqs/pair_adp.tex b/doc/Eqs/pair_adp.tex
index 08f227a57..4ba8ad76e 100644
--- a/doc/Eqs/pair_adp.tex
+++ b/doc/Eqs/pair_adp.tex
@@ -1,16 +1,26 @@
\documentclass[12pt]{article}
\begin{document}
\begin{eqnarray*}
E_{i} & = & F_{\alpha} \left( \sum_{j \ne i} \rho(r_{ij}) \right) +
\frac{1}{2} \sum_{j \ne i} \phi_{\alpha \beta} (r_{ij}) +
\frac{1}{2} \sum_{i,s} \left( \mu_{i}^{s} \right)^2 +
\sum_{i,s,t} \left( \lambda_{i}^{st} \right)^2 - \frac{1}{6} \nu_{i} \\
\mu_{i}^{s} & = & \sum_{i \ne j} u(r_{ij}) r_{ij}^{s} \\
\lambda_{i}^{st} & = & \sum_{i \ne j} w(r_{ij}) r_{ij}^{s} r_{ij}^{t} \\
\nu_{i} & = & \sum_{s} \lambda_{i}^{ss}
\end{eqnarray*}
+\begin{eqnarray*}
+E_i & = & F_\alpha \left( \sum_{j\neq i} \rho_\beta (r_{ij}) \right) + \frac{1}{2} \sum_{j\neq i}\phi_{\alpha\beta}(r_{ij})+ \frac{1}{2} \sum_s (\mu_i^s)^2 + \frac{1}{2} \sum_{s,t} (\lambda_i^{st})^2 - \frac{1}{6} \nu_i^2 \\
+%
+\mu_i^s & = & \sum_{j\neq i}u_{\alpha\beta}(r_{ij})r_{ij}^s\\
+%
+\lambda_i^{st} & = & \sum_{j\neq i}w_{\alpha\beta}(r_{ij})r_{ij}^sr_{ij}^t\\
+%
+\nu_i & = & \sum_s\lambda_i^{ss}
+\end{eqnarray*}
+
\end{document}
diff --git a/doc/Eqs/pair_airebo.jpg b/doc/Eqs/pair_airebo.jpg
index 6416d6d7e..a3259879f 100644
Binary files a/doc/Eqs/pair_airebo.jpg and b/doc/Eqs/pair_airebo.jpg differ
diff --git a/doc/Eqs/pair_born.jpg b/doc/Eqs/pair_born.jpg
index 24e846f09..5e6b6a729 100644
Binary files a/doc/Eqs/pair_born.jpg and b/doc/Eqs/pair_born.jpg differ
diff --git a/doc/Eqs/pair_buck.jpg b/doc/Eqs/pair_buck.jpg
index d66980b51..aaa5f7659 100644
Binary files a/doc/Eqs/pair_buck.jpg and b/doc/Eqs/pair_buck.jpg differ
diff --git a/doc/Eqs/pair_charmm.jpg b/doc/Eqs/pair_charmm.jpg
index 85bc839d2..7d6c709ce 100644
Binary files a/doc/Eqs/pair_charmm.jpg and b/doc/Eqs/pair_charmm.jpg differ
diff --git a/doc/Eqs/pair_class2.jpg b/doc/Eqs/pair_class2.jpg
index c0a7aefef..abec072e7 100644
Binary files a/doc/Eqs/pair_class2.jpg and b/doc/Eqs/pair_class2.jpg differ
diff --git a/doc/Eqs/pair_cmm.jpg b/doc/Eqs/pair_cmm.jpg
index f97a47393..1ec60f730 100644
Binary files a/doc/Eqs/pair_cmm.jpg and b/doc/Eqs/pair_cmm.jpg differ
diff --git a/doc/Eqs/pair_colloid_cc.jpg b/doc/Eqs/pair_colloid_cc.jpg
index 36f0b23b1..a64094dda 100644
Binary files a/doc/Eqs/pair_colloid_cc.jpg and b/doc/Eqs/pair_colloid_cc.jpg differ
diff --git a/doc/Eqs/pair_colloid_cs.jpg b/doc/Eqs/pair_colloid_cs.jpg
index 3931e40ee..8f5948fa5 100644
Binary files a/doc/Eqs/pair_colloid_cs.jpg and b/doc/Eqs/pair_colloid_cs.jpg differ
diff --git a/doc/Eqs/pair_colloid_ss.jpg b/doc/Eqs/pair_colloid_ss.jpg
index de61125d9..4ce19ba1e 100644
Binary files a/doc/Eqs/pair_colloid_ss.jpg and b/doc/Eqs/pair_colloid_ss.jpg differ
diff --git a/doc/Eqs/pair_comb1.jpg b/doc/Eqs/pair_comb1.jpg
index 9fbe18ef1..0e7fc4e35 100644
Binary files a/doc/Eqs/pair_comb1.jpg and b/doc/Eqs/pair_comb1.jpg differ
diff --git a/doc/Eqs/pair_comb2.jpg b/doc/Eqs/pair_comb2.jpg
index 1a71f95e4..206046000 100644
Binary files a/doc/Eqs/pair_comb2.jpg and b/doc/Eqs/pair_comb2.jpg differ
diff --git a/doc/Eqs/pair_coul_diel.jpg b/doc/Eqs/pair_coul_diel.jpg
new file mode 100644
index 000000000..70cb84f7a
Binary files /dev/null and b/doc/Eqs/pair_coul_diel.jpg differ
diff --git a/doc/Eqs/pair_coul_diel.tex b/doc/Eqs/pair_coul_diel.tex
new file mode 100644
index 000000000..f0b893d88
--- /dev/null
+++ b/doc/Eqs/pair_coul_diel.tex
@@ -0,0 +1,9 @@
+\documentclass[12pt]{article}
+\pagestyle{empty}
+\begin{document}
+
+\begin{eqnarray*}
+ E & = & \frac{Cq_iq_j}{\epsilon r} \left( \frac{\epsilon}{\epsilon_D(r)}-1\right) \qquad r < r_c \\
+ \epsilon_D(r) & = & \frac{5.2+\epsilon}{2} + \frac{\epsilon-5.2}{2}\tanh\left(\frac{r-r_{me}}{\sigma_e}\right)
+\end{eqnarray*}
+\end{document}
diff --git a/doc/Eqs/pair_coul_wolf.jpg b/doc/Eqs/pair_coul_wolf.jpg
new file mode 100644
index 000000000..fd64cb6c0
Binary files /dev/null and b/doc/Eqs/pair_coul_wolf.jpg differ
diff --git a/doc/Eqs/pair_coul_wolf.tex b/doc/Eqs/pair_coul_wolf.tex
new file mode 100644
index 000000000..4a6592638
--- /dev/null
+++ b/doc/Eqs/pair_coul_wolf.tex
@@ -0,0 +1,11 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+$$
+ E_i = \frac{1}{2} \sum_{j \neq i}
+ \frac{q_i q_j {\rm erfc}(\alpha r_{ij})}{r_{ij}} +
+ \frac{1}{2} \sum_{j \neq i}
+ \frac{q_i q_j {\rm erf}(\alpha r_{ij})}{r_{ij}} \qquad r < r_c
+$$
+
+\end{document}
diff --git a/doc/Eqs/pair_coulomb.jpg b/doc/Eqs/pair_coulomb.jpg
index 0b4994092..39aaebac3 100644
Binary files a/doc/Eqs/pair_coulomb.jpg and b/doc/Eqs/pair_coulomb.jpg differ
diff --git a/doc/Eqs/pair_debye.jpg b/doc/Eqs/pair_debye.jpg
index 664c8bc5e..42bcb5cc6 100644
Binary files a/doc/Eqs/pair_debye.jpg and b/doc/Eqs/pair_debye.jpg differ
diff --git a/doc/Eqs/pair_dipole.jpg b/doc/Eqs/pair_dipole.jpg
index cb2036ce8..e106c17c9 100644
Binary files a/doc/Eqs/pair_dipole.jpg and b/doc/Eqs/pair_dipole.jpg differ
diff --git a/doc/Eqs/pair_dipole_sf.jpg b/doc/Eqs/pair_dipole_sf.jpg
index 536ea7f2c..c59153455 100644
Binary files a/doc/Eqs/pair_dipole_sf.jpg and b/doc/Eqs/pair_dipole_sf.jpg differ
diff --git a/doc/Eqs/pair_dipole_sf2.jpg b/doc/Eqs/pair_dipole_sf2.jpg
index f45f58373..b9e57becf 100644
Binary files a/doc/Eqs/pair_dipole_sf2.jpg and b/doc/Eqs/pair_dipole_sf2.jpg differ
diff --git a/doc/Eqs/pair_dpd.jpg b/doc/Eqs/pair_dpd.jpg
index 77eb96897..e9bb8a69a 100644
Binary files a/doc/Eqs/pair_dpd.jpg and b/doc/Eqs/pair_dpd.jpg differ
diff --git a/doc/Eqs/pair_eam.jpg b/doc/Eqs/pair_eam.jpg
index 50e991d8c..95c86b4ce 100644
Binary files a/doc/Eqs/pair_eam.jpg and b/doc/Eqs/pair_eam.jpg differ
diff --git a/doc/Eqs/pair_eam.tex b/doc/Eqs/pair_eam.tex
index 05c2085d4..2ea20b219 100644
--- a/doc/Eqs/pair_eam.tex
+++ b/doc/Eqs/pair_eam.tex
@@ -1,10 +1,10 @@
\documentclass[12pt]{article}
\begin{document}
$$
- E_i = F_\alpha \left(\sum_{j \neq i}\ \rho_\alpha (r_{ij})\right) +
+ E_i = F_\alpha \left(\sum_{j \neq i}\ \rho_\beta (r_{ij})\right) +
\frac{1}{2} \sum_{j \neq i} \phi_{\alpha\beta} (r_{ij})
$$
-\end{document}
\ No newline at end of file
+\end{document}
diff --git a/doc/Eqs/pair_eam_fs.jpg b/doc/Eqs/pair_eam_fs.jpg
index fecab0e10..fa72f8fc7 100644
Binary files a/doc/Eqs/pair_eam_fs.jpg and b/doc/Eqs/pair_eam_fs.jpg differ
diff --git a/doc/Eqs/pair_edip.jpg b/doc/Eqs/pair_edip.jpg
index 9e7a8d77d..393328048 100644
Binary files a/doc/Eqs/pair_edip.jpg and b/doc/Eqs/pair_edip.jpg differ
diff --git a/doc/Eqs/pair_eim1.jpg b/doc/Eqs/pair_eim1.jpg
index 9e4a560b1..c243120b2 100644
Binary files a/doc/Eqs/pair_eim1.jpg and b/doc/Eqs/pair_eim1.jpg differ
diff --git a/doc/Eqs/pair_eim2.jpg b/doc/Eqs/pair_eim2.jpg
index accb638d9..4896f658f 100644
Binary files a/doc/Eqs/pair_eim2.jpg and b/doc/Eqs/pair_eim2.jpg differ
diff --git a/doc/Eqs/pair_eim3.jpg b/doc/Eqs/pair_eim3.jpg
index 8e3b47d2a..57366bc15 100644
Binary files a/doc/Eqs/pair_eim3.jpg and b/doc/Eqs/pair_eim3.jpg differ
diff --git a/doc/Eqs/pair_gauss.jpg b/doc/Eqs/pair_gauss.jpg
index c6c4b6a52..b09ad9545 100644
Binary files a/doc/Eqs/pair_gauss.jpg and b/doc/Eqs/pair_gauss.jpg differ
diff --git a/doc/Eqs/pair_gauss_cut.jpg b/doc/Eqs/pair_gauss_cut.jpg
new file mode 100644
index 000000000..e47bb8cc0
Binary files /dev/null and b/doc/Eqs/pair_gauss_cut.jpg differ
diff --git a/doc/Eqs/pair_gauss_cut.tex b/doc/Eqs/pair_gauss_cut.tex
new file mode 100644
index 000000000..5d0bb430f
--- /dev/null
+++ b/doc/Eqs/pair_gauss_cut.tex
@@ -0,0 +1,8 @@
+\documentclass[12pt]{article}
+\pagestyle{empty}
+\begin{document}
+
+\begin{eqnarray*}
+ E = & \frac{H}{\sigma_h\sqrt{2\pi}} \exp\left[-\frac{(r-r_{mh})^2}{2\sigma_h^2}\right]
+\end{eqnarray*}
+\end{document}
diff --git a/doc/Eqs/pair_gayberne.jpg b/doc/Eqs/pair_gayberne.jpg
index 70862bd22..e9b1f3ca9 100644
Binary files a/doc/Eqs/pair_gayberne.jpg and b/doc/Eqs/pair_gayberne.jpg differ
diff --git a/doc/Eqs/pair_gayberne2.jpg b/doc/Eqs/pair_gayberne2.jpg
index 2e849a4b3..a4e6c6f70 100644
Binary files a/doc/Eqs/pair_gayberne2.jpg and b/doc/Eqs/pair_gayberne2.jpg differ
diff --git a/doc/Eqs/pair_gran_hertz.jpg b/doc/Eqs/pair_gran_hertz.jpg
index 96a6d8ab6..733875fee 100644
Binary files a/doc/Eqs/pair_gran_hertz.jpg and b/doc/Eqs/pair_gran_hertz.jpg differ
diff --git a/doc/Eqs/pair_gran_hooke.jpg b/doc/Eqs/pair_gran_hooke.jpg
index 174543835..36f34db6c 100644
Binary files a/doc/Eqs/pair_gran_hooke.jpg and b/doc/Eqs/pair_gran_hooke.jpg differ
diff --git a/doc/Eqs/pair_gromacs.jpg b/doc/Eqs/pair_gromacs.jpg
index 4902fe016..675b399c6 100644
Binary files a/doc/Eqs/pair_gromacs.jpg and b/doc/Eqs/pair_gromacs.jpg differ
diff --git a/doc/Eqs/pair_hbond_dreiding.jpg b/doc/Eqs/pair_hbond_dreiding.jpg
index cb1e38ba4..b93044ed3 100644
Binary files a/doc/Eqs/pair_hbond_dreiding.jpg and b/doc/Eqs/pair_hbond_dreiding.jpg differ
diff --git a/doc/Eqs/pair_lj.jpg b/doc/Eqs/pair_lj.jpg
index e767e0b3a..49cf7f5eb 100644
Binary files a/doc/Eqs/pair_lj.jpg and b/doc/Eqs/pair_lj.jpg differ
diff --git a/doc/Eqs/pair_lj96.jpg b/doc/Eqs/pair_lj96.jpg
index a4f51537d..6462de180 100644
Binary files a/doc/Eqs/pair_lj96.jpg and b/doc/Eqs/pair_lj96.jpg differ
diff --git a/doc/Eqs/pair_lj_cubic.jpg b/doc/Eqs/pair_lj_cubic.jpg
index 25ffe2cbf..69ec4f6e8 100644
Binary files a/doc/Eqs/pair_lj_cubic.jpg and b/doc/Eqs/pair_lj_cubic.jpg differ
diff --git a/doc/Eqs/pair_lj_expand.jpg b/doc/Eqs/pair_lj_expand.jpg
index 64776d21d..e27481889 100644
Binary files a/doc/Eqs/pair_lj_expand.jpg and b/doc/Eqs/pair_lj_expand.jpg differ
diff --git a/doc/Eqs/pair_lj_sf.jpg b/doc/Eqs/pair_lj_sf.jpg
index 620331667..a70224000 100644
Binary files a/doc/Eqs/pair_lj_sf.jpg and b/doc/Eqs/pair_lj_sf.jpg differ
diff --git a/doc/Eqs/pair_lj_smooth.jpg b/doc/Eqs/pair_lj_smooth.jpg
index 71e3b41e8..d380fd345 100644
Binary files a/doc/Eqs/pair_lj_smooth.jpg and b/doc/Eqs/pair_lj_smooth.jpg differ
diff --git a/doc/Eqs/pair_lubricate.jpg b/doc/Eqs/pair_lubricate.jpg
index 54bbd199d..560591765 100644
Binary files a/doc/Eqs/pair_lubricate.jpg and b/doc/Eqs/pair_lubricate.jpg differ
diff --git a/doc/Eqs/pair_meam.jpg b/doc/Eqs/pair_meam.jpg
index 013d41f39..f6de50a99 100644
Binary files a/doc/Eqs/pair_meam.jpg and b/doc/Eqs/pair_meam.jpg differ
diff --git a/doc/Eqs/pair_morse.jpg b/doc/Eqs/pair_morse.jpg
index d236a54e0..5ebcdb2e1 100644
Binary files a/doc/Eqs/pair_morse.jpg and b/doc/Eqs/pair_morse.jpg differ
diff --git a/doc/Eqs/pair_resquared.jpg b/doc/Eqs/pair_resquared.jpg
index de3e0fa88..c290c68df 100644
Binary files a/doc/Eqs/pair_resquared.jpg and b/doc/Eqs/pair_resquared.jpg differ
diff --git a/doc/Eqs/pair_resquared2.jpg b/doc/Eqs/pair_resquared2.jpg
index deec54782..d2ed21a62 100644
Binary files a/doc/Eqs/pair_resquared2.jpg and b/doc/Eqs/pair_resquared2.jpg differ
diff --git a/doc/Eqs/pair_resquared3.jpg b/doc/Eqs/pair_resquared3.jpg
index 8e58c660e..3916062a1 100644
Binary files a/doc/Eqs/pair_resquared3.jpg and b/doc/Eqs/pair_resquared3.jpg differ
diff --git a/doc/Eqs/pair_resquared4.jpg b/doc/Eqs/pair_resquared4.jpg
index a654952d2..79ad067fa 100644
Binary files a/doc/Eqs/pair_resquared4.jpg and b/doc/Eqs/pair_resquared4.jpg differ
diff --git a/doc/Eqs/pair_soft.jpg b/doc/Eqs/pair_soft.jpg
index 19e6ca37f..e8a654e1e 100644
Binary files a/doc/Eqs/pair_soft.jpg and b/doc/Eqs/pair_soft.jpg differ
diff --git a/doc/Eqs/pair_sph_ideal.jpg b/doc/Eqs/pair_sph_ideal.jpg
index ad9760d5e..370b75fe9 100644
Binary files a/doc/Eqs/pair_sph_ideal.jpg and b/doc/Eqs/pair_sph_ideal.jpg differ
diff --git a/doc/Eqs/pair_sph_tait.jpg b/doc/Eqs/pair_sph_tait.jpg
index 96adab38e..8bbfe8051 100644
Binary files a/doc/Eqs/pair_sph_tait.jpg and b/doc/Eqs/pair_sph_tait.jpg differ
diff --git a/doc/Eqs/pair_sw.jpg b/doc/Eqs/pair_sw.jpg
index a9cd3a528..f60f07fd2 100644
Binary files a/doc/Eqs/pair_sw.jpg and b/doc/Eqs/pair_sw.jpg differ
diff --git a/doc/Eqs/pair_tersoff_1.jpg b/doc/Eqs/pair_tersoff_1.jpg
index c34bd55b1..79600b499 100644
Binary files a/doc/Eqs/pair_tersoff_1.jpg and b/doc/Eqs/pair_tersoff_1.jpg differ
diff --git a/doc/Eqs/pair_tersoff_2.jpg b/doc/Eqs/pair_tersoff_2.jpg
index d18ea3df2..6cb8778a0 100644
Binary files a/doc/Eqs/pair_tersoff_2.jpg and b/doc/Eqs/pair_tersoff_2.jpg differ
diff --git a/doc/Eqs/pair_tersoff_zbl.jpg b/doc/Eqs/pair_tersoff_zbl.jpg
index 4309f995b..ac80bba44 100644
Binary files a/doc/Eqs/pair_tersoff_zbl.jpg and b/doc/Eqs/pair_tersoff_zbl.jpg differ
diff --git a/doc/Eqs/pair_yukawa.jpg b/doc/Eqs/pair_yukawa.jpg
index f50280e22..103edc604 100644
Binary files a/doc/Eqs/pair_yukawa.jpg and b/doc/Eqs/pair_yukawa.jpg differ
diff --git a/doc/Eqs/pair_yukawa_colloid.jpg b/doc/Eqs/pair_yukawa_colloid.jpg
index db6e2ea81..1d8362475 100644
Binary files a/doc/Eqs/pair_yukawa_colloid.jpg and b/doc/Eqs/pair_yukawa_colloid.jpg differ
diff --git a/doc/Eqs/pressure.jpg b/doc/Eqs/pressure.jpg
index 69a92daa0..0ed674775 100644
Binary files a/doc/Eqs/pressure.jpg and b/doc/Eqs/pressure.jpg differ
diff --git a/doc/Eqs/pressure_tensor.jpg b/doc/Eqs/pressure_tensor.jpg
index f11e8ac3b..b5abf0ce4 100644
Binary files a/doc/Eqs/pressure_tensor.jpg and b/doc/Eqs/pressure_tensor.jpg differ
diff --git a/doc/Eqs/stress_tensor.jpg b/doc/Eqs/stress_tensor.jpg
index 1be5dc872..f6ec0eeef 100644
Binary files a/doc/Eqs/stress_tensor.jpg and b/doc/Eqs/stress_tensor.jpg differ
diff --git a/doc/Manual.html b/doc/Manual.html
index abdc33945..afd2d10ff 100644
--- a/doc/Manual.html
+++ b/doc/Manual.html
@@ -1,401 +1,401 @@
<HTML>
<HEAD>
<TITLE>LAMMPS Users Manual</TITLE>
<META NAME="docnumber" CONTENT="Large-scale Atomic/Molecular Massively Parallel Simulator">
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
</HEAD>
<BODY>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H1></H1>
<CENTER><H3>LAMMPS Documentation
</H3></CENTER>
<H4>Version info:
</H4>
<P>The LAMMPS "version" is the date when it was released, such as 1 May
2010. LAMMPS is updated continuously. Whenever we fix a bug or add a
feature, we release it immediately, and post a notice on <A HREF = "http://lammps.sandia.gov/bug.html">this page of
the WWW site</A>. Each dated copy of LAMMPS contains all the
features and bug-fixes up to and including that version date. The
version date is printed to the screen and logfile every time you run
LAMMPS. It is also in the file src/version.h and in the LAMMPS
directory name created when you unpack a tarball.
</P>
<UL><LI>If you browse the HTML doc pages on the LAMMPS WWW site, they always
describe the most current version of LAMMPS.
<LI>If you browse the HTML doc pages included in your tarball, they
describe the version you have.
<LI>The <A HREF = "Manual.pdf">PDF file</A> on the WWW site or in the tarball is updated
about once per month. This is because it is large, and we don't want
it to be part of very patch.
<LI>There is also a <A HREF = "Developer.pdf">Developer.pdf</A> file in the doc
directory, which describes the internal structure and algorithms of
LAMMPS.
</UL>
<P>LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel
Simulator.
</P>
<P>LAMMPS is a classical molecular dynamics simulation code designed to
run efficiently on parallel computers. It was developed at Sandia
National Laboratories, a US Department of Energy facility, with
funding from the DOE. It is an open-source code, distributed freely
under the terms of the GNU Public License (GPL).
</P>
<P>The primary developers of LAMMPS are <A HREF = "http://www.sandia.gov/~sjplimp">Steve Plimpton</A>, Aidan
Thompson, and Paul Crozier who can be contacted at
sjplimp,athomps,pscrozi at sandia.gov. The <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> at
http://lammps.sandia.gov has more information about the code and its
uses.
</P>
<HR>
<P>The LAMMPS documentation is organized into the following sections. If
you find errors or omissions in this manual or have suggestions for
useful information to add, please send an email to the developers so
we can improve the LAMMPS documentation.
</P>
<P>Once you are familiar with LAMMPS, you may want to bookmark <A HREF = "Section_commands.html#comm">this
page</A> at Section_commands.html#comm since
it gives quick access to documentation for all LAMMPS commands.
</P>
<P><A HREF = "Manual.pdf">PDF file</A> of the entire manual, generated by
<A HREF = "http://www.easysw.com/htmldoc">htmldoc</A>
</P>
<OL><LI><A HREF = "Section_intro.html">Introduction</A>
<UL> 1.1 <A HREF = "Section_intro.html#intro_1">What is LAMMPS</A>
<BR>
1.2 <A HREF = "Section_intro.html#intro_2">LAMMPS features</A>
<BR>
1.3 <A HREF = "Section_intro.html#intro_3">LAMMPS non-features</A>
<BR>
1.4 <A HREF = "Section_intro.html#intro_4">Open source distribution</A>
<BR>
1.5 <A HREF = "Section_intro.html#intro_5">Acknowledgments and citations</A>
<BR></UL>
<LI><A HREF = "Section_start.html">Getting started</A>
<UL> 2.1 <A HREF = "Section_start.html#start_1">What's in the LAMMPS distribution</A>
<BR>
2.2 <A HREF = "Section_start.html#start_2">Making LAMMPS</A>
<BR>
2.3 <A HREF = "Section_start.html#start_3">Making LAMMPS with optional packages</A>
<BR>
2.4 <A HREF = "Section_start.html#start_4">Building LAMMPS as a library</A>
<BR>
2.5 <A HREF = "Section_start.html#start_5">Running LAMMPS</A>
<BR>
2.6 <A HREF = "Section_start.html#start_6">Command-line options</A>
<BR>
2.7 <A HREF = "Section_start.html#start_7">Screen output</A>
<BR>
2.8 <A HREF = "2_8">Tips for users of previous versions</A>
<BR></UL>
<LI><A HREF = "Section_commands.html">Commands</A>
<UL> 3.1 <A HREF = "Section_commands.html#cmd_1">LAMMPS input script</A>
<BR>
3.2 <A HREF = "Section_commands.html#cmd_2">Parsing rules</A>
<BR>
3.3 <A HREF = "Section_commands.html#cmd_3">Input script structure</A>
<BR>
3.4 <A HREF = "Section_commands.html#cmd_4">Commands listed by category</A>
<BR>
3.5 <A HREF = "Section_commands.html#cmd_5">Commands listed alphabetically</A>
<BR></UL>
<LI><A HREF = "Section_packages.html">Packages</A>
<UL> 4.1 <A HREF = "Section_packages.html#pkg_1">Standard packages</A>
<BR>
4.2 <A HREF = "Section_packages.html#pkg_2">User packages</A>
<BR></UL>
-<LI><A HREF = "Section_accelerate.html">Using accelerated CPU and GPU styles</A>
+<LI><A HREF = "Section_accelerate.html">Accelerating LAMMPS performance</A>
<UL> 5.1 <A HREF = "Section_accelerate.html#acc_1">OPT package</A>
<BR>
5.2 <A HREF = "Section_accelerate.html#acc_2">USER-OMP package</A>
<BR>
5.3 <A HREF = "Section_accelerate.html#acc_3">GPU package</A>
<BR>
5.4 <A HREF = "Section_accelerate.html#acc_4">USER-CUDA package</A>
<BR>
5.5 <A HREF = "Section_accelerate.html#acc_5">Comparison of GPU and USER-CUDA packages</A>
<BR></UL>
<LI><A HREF = "Section_howto.html">How-to discussions</A>
<UL> 6.1 <A HREF = "Section_howto.html#howto_1">Restarting a simulation</A>
<BR>
6.2 <A HREF = "Section_howto.html#howto_2">2d simulations</A>
<BR>
6.3 <A HREF = "Section_howto.html#howto_3">CHARMM and AMBER force fields</A>
<BR>
6.4 <A HREF = "Section_howto.html#howto_4">Running multiple simulations from one input script</A>
<BR>
6.5 <A HREF = "Section_howto.html#howto_5">Multi-replica simulations</A>
<BR>
6.6 <A HREF = "Section_howto.html#howto_6">Granular models</A>
<BR>
6.7 <A HREF = "Section_howto.html#howto_7">TIP3P water model</A>
<BR>
6.8 <A HREF = "Section_howto.html#howto_8">TIP4P water model</A>
<BR>
6.9 <A HREF = "Section_howto.html#howto_9">SPC water model</A>
<BR>
6.10 <A HREF = "Section_howto.html#howto_10">Coupling LAMMPS to other codes</A>
<BR>
6.11 <A HREF = "Section_howto.html#howto_11">Visualizing LAMMPS snapshots</A>
<BR>
6.12 <A HREF = "Section_howto.html#howto_12">Triclinic (non-orthogonal) simulation boxes</A>
<BR>
6.13 <A HREF = "Section_howto.html#howto_13">NEMD simulations</A>
<BR>
6.14 <A HREF = "Section_howto.html#howto_14">Extended spherical and aspherical particles</A>
<BR>
6.15 <A HREF = "Section_howto.html#howto_15">Output from LAMMPS (thermo, dumps, computes, fixes, variables)</A>
<BR>
6.16 <A HREF = "Section_howto.html#howto_16">Thermostatting, barostatting, and compute temperature</A>
<BR>
6.17 <A HREF = "Section_howto.html#howto_17">Walls</A>
<BR>
6.18 <A HREF = "Section_howto.html#howto_18">Elastic constants</A>
<BR>
6.19 <A HREF = "Section_howto.html#howto_19">Library interface to LAMMPS</A>
<BR>
6.20 <A HREF = "Section_howto.html#howto_20">Calculating thermal conductivity</A>
<BR>
6.21 <A HREF = "Section_howto.html#howto_21">Calculating viscosity</A>
<BR></UL>
<LI><A HREF = "Section_example.html">Example problems</A>
<LI><A HREF = "Section_perf.html">Performance & scalability</A>
<LI><A HREF = "Section_tools.html">Additional tools</A>
<LI><A HREF = "Section_modify.html">Modifying & extending LAMMPS</A>
<UL> 10.1 <A HREF = "Section_modify.html#mod_1">Atom styles</A>
<BR>
10.2 <A HREF = "Section_modify.html#mod_2">Bond, angle, dihedral, improper potentials</A>
<BR>
10.3 <A HREF = "Section_modify.html#mod_3">Compute styles</A>
<BR>
10.4 <A HREF = "Section_modify.html#mod_4">Dump styles</A>
<BR>
10.5 <A HREF = "Section_modify.html#mod_5">Dump custom output options</A>
<BR>
10.6 <A HREF = "Section_modify.html#mod_6">Fix styles</A>
<BR>
10.7 <A HREF = "Section_modify.html#mod_7">Input script commands</A>
<BR>
10.8 <A HREF = "Section_modify.html#mod_8">Kspace computations</A>
<BR>
10.9 <A HREF = "Section_modify.html#mod_9">Minimization styles</A>
<BR>
10.10 <A HREF = "Section_modify.html#mod_10">Pairwise potentials</A>
<BR>
10.11 <A HREF = "Section_modify.html#mod_11">Region styles</A>
<BR>
10.12 <A HREF = "Section_modify.html#mod_12">Thermodynamic output options</A>
<BR>
10.13 <A HREF = "Section_modify.html#mod_13">Variable options</A>
<BR>
10.14 <A HREF = "Section_modify.html#mod_14">Submitting new features for inclusion in LAMMPS</A>
<BR></UL>
<LI><A HREF = "Section_python.html">Python interface</A>
<UL> 11.1 <A HREF = "Section_python.html#py_1">Extending Python with a serial version of LAMMPS</A>
<BR>
11.2 <A HREF = "Section_python.html#py_2">Creating a shared MPI library</A>
<BR>
11.3 <A HREF = "Section_python.html#py_3">Extending Python with a parallel version of LAMMPS</A>
<BR>
11.4 <A HREF = "Section_python.html#py_4">Extending Python with MPI</A>
<BR>
11.5 <A HREF = "Section_python.html#py_5">Testing the Python-LAMMPS interface</A>
<BR>
11.6 <A HREF = "Section_python.html#py_6">Using LAMMPS from Python</A>
<BR>
11.7 <A HREF = "Section_python.html#py_7">Example Python scripts that use LAMMPS</A>
<BR></UL>
<LI><A HREF = "Section_errors.html">Errors</A>
<UL> 12.1 <A HREF = "Section_errors.html#err_1">Common problems</A>
<BR>
12.2 <A HREF = "Section_errors.html#err_2">Reporting bugs</A>
<BR>
12.3 <A HREF = "Section_errors.html#err_3">Error & warning messages</A>
<BR></UL>
<LI><A HREF = "Section_history.html">Future and history</A>
<UL> 13.1 <A HREF = "Section_history.html#hist_1">Coming attractions</A>
<BR>
13.2 <A HREF = "Section_history.html#hist_2">Past versions</A>
<BR></UL>
</OL>
</BODY>
</HTML>
diff --git a/doc/Manual.txt b/doc/Manual.txt
index 457230649..62e27cc4a 100644
--- a/doc/Manual.txt
+++ b/doc/Manual.txt
@@ -1,248 +1,248 @@
<HEAD>
<TITLE>LAMMPS Users Manual</TITLE>
<META NAME="docnumber" CONTENT="Large-scale Atomic/Molecular Massively Parallel Simulator">
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
</HEAD>
<BODY>
"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
<H1></H1>
LAMMPS Documentation :c,h3
Version info: :h4
The LAMMPS "version" is the date when it was released, such as 1 May
2010. LAMMPS is updated continuously. Whenever we fix a bug or add a
feature, we release it immediately, and post a notice on "this page of
the WWW site"_bug. Each dated copy of LAMMPS contains all the
features and bug-fixes up to and including that version date. The
version date is printed to the screen and logfile every time you run
LAMMPS. It is also in the file src/version.h and in the LAMMPS
directory name created when you unpack a tarball.
If you browse the HTML doc pages on the LAMMPS WWW site, they always
describe the most current version of LAMMPS. :ulb,l
If you browse the HTML doc pages included in your tarball, they
describe the version you have. :l
The "PDF file"_Manual.pdf on the WWW site or in the tarball is updated
about once per month. This is because it is large, and we don't want
it to be part of very patch. :l
There is also a "Developer.pdf"_Developer.pdf file in the doc
directory, which describes the internal structure and algorithms of
LAMMPS. :ule,l
LAMMPS stands for Large-scale Atomic/Molecular Massively Parallel
Simulator.
LAMMPS is a classical molecular dynamics simulation code designed to
run efficiently on parallel computers. It was developed at Sandia
National Laboratories, a US Department of Energy facility, with
funding from the DOE. It is an open-source code, distributed freely
under the terms of the GNU Public License (GPL).
The primary developers of LAMMPS are "Steve Plimpton"_sjp, Aidan
Thompson, and Paul Crozier who can be contacted at
sjplimp,athomps,pscrozi at sandia.gov. The "LAMMPS WWW Site"_lws at
http://lammps.sandia.gov has more information about the code and its
uses.
:link(bug,http://lammps.sandia.gov/bug.html)
:link(sjp,http://www.sandia.gov/~sjplimp)
:line
The LAMMPS documentation is organized into the following sections. If
you find errors or omissions in this manual or have suggestions for
useful information to add, please send an email to the developers so
we can improve the LAMMPS documentation.
Once you are familiar with LAMMPS, you may want to bookmark "this
page"_Section_commands.html#comm at Section_commands.html#comm since
it gives quick access to documentation for all LAMMPS commands.
"PDF file"_Manual.pdf of the entire manual, generated by
"htmldoc"_http://www.easysw.com/htmldoc
"Introduction"_Section_intro.html :olb,l
1.1 "What is LAMMPS"_intro_1 :ulb,b
1.2 "LAMMPS features"_intro_2 :b
1.3 "LAMMPS non-features"_intro_3 :b
1.4 "Open source distribution"_intro_4 :b
1.5 "Acknowledgments and citations"_intro_5 :ule,b
"Getting started"_Section_start.html :l
2.1 "What's in the LAMMPS distribution"_start_1 :ulb,b
2.2 "Making LAMMPS"_start_2 :b
2.3 "Making LAMMPS with optional packages"_start_3 :b
2.4 "Building LAMMPS as a library"_start_4 :b
2.5 "Running LAMMPS"_start_5 :b
2.6 "Command-line options"_start_6 :b
2.7 "Screen output"_start_7 :b
2.8 "Tips for users of previous versions"_2_8 :ule,b
"Commands"_Section_commands.html :l
3.1 "LAMMPS input script"_cmd_1 :ulb,b
3.2 "Parsing rules"_cmd_2 :b
3.3 "Input script structure"_cmd_3 :b
3.4 "Commands listed by category"_cmd_4 :b
3.5 "Commands listed alphabetically"_cmd_5 :ule,b
"Packages"_Section_packages.html :l
4.1 "Standard packages"_pkg_1 :ulb,b
4.2 "User packages"_pkg_2 :ule,b
-"Using accelerated CPU and GPU styles"_Section_accelerate.html :l
+"Accelerating LAMMPS performance"_Section_accelerate.html :l
5.1 "OPT package"_acc_1 :ulb,b
5.2 "USER-OMP package"_acc_2 :b
5.3 "GPU package"_acc_3 :b
5.4 "USER-CUDA package"_acc_4 :b
5.5 "Comparison of GPU and USER-CUDA packages"_acc_5 :ule,b
"How-to discussions"_Section_howto.html :l
6.1 "Restarting a simulation"_howto_1 :ulb,b
6.2 "2d simulations"_howto_2 :b
6.3 "CHARMM and AMBER force fields"_howto_3 :b
6.4 "Running multiple simulations from one input script"_howto_4 :b
6.5 "Multi-replica simulations"_howto_5 :b
6.6 "Granular models"_howto_6 :b
6.7 "TIP3P water model"_howto_7 :b
6.8 "TIP4P water model"_howto_8 :b
6.9 "SPC water model"_howto_9 :b
6.10 "Coupling LAMMPS to other codes"_howto_10 :b
6.11 "Visualizing LAMMPS snapshots"_howto_11 :b
6.12 "Triclinic (non-orthogonal) simulation boxes"_howto_12 :b
6.13 "NEMD simulations"_howto_13 :b
6.14 "Extended spherical and aspherical particles"_howto_14 :b
6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_howto_15 :b
6.16 "Thermostatting, barostatting, and compute temperature"_howto_16 :b
6.17 "Walls"_howto_17 :b
6.18 "Elastic constants"_howto_18 :b
6.19 "Library interface to LAMMPS"_howto_19 :b
6.20 "Calculating thermal conductivity"_howto_20 :b
6.21 "Calculating viscosity"_howto_21 :ule,b
"Example problems"_Section_example.html :l
"Performance & scalability"_Section_perf.html :l
"Additional tools"_Section_tools.html :l
"Modifying & extending LAMMPS"_Section_modify.html :l
10.1 "Atom styles"_mod_1 :ulb,b
10.2 "Bond, angle, dihedral, improper potentials"_mod_2 :b
10.3 "Compute styles"_mod_3 :b
10.4 "Dump styles"_mod_4 :b
10.5 "Dump custom output options"_mod_5 :b
10.6 "Fix styles"_mod_6 :b
10.7 "Input script commands"_mod_7 :b
10.8 "Kspace computations"_mod_8 :b
10.9 "Minimization styles"_mod_9 :b
10.10 "Pairwise potentials"_mod_10 :b
10.11 "Region styles"_mod_11 :b
10.12 "Thermodynamic output options"_mod_12 :b
10.13 "Variable options"_mod_13 :b
10.14 "Submitting new features for inclusion in LAMMPS"_mod_14 :ule,b
"Python interface"_Section_python.html :l
11.1 "Extending Python with a serial version of LAMMPS"_py_1 :ulb,b
11.2 "Creating a shared MPI library"_py_2 :b
11.3 "Extending Python with a parallel version of LAMMPS"_py_3 :b
11.4 "Extending Python with MPI"_py_4 :b
11.5 "Testing the Python-LAMMPS interface"_py_5 :b
11.6 "Using LAMMPS from Python"_py_6 :b
11.7 "Example Python scripts that use LAMMPS"_py_7 :ule,b
"Errors"_Section_errors.html :l
12.1 "Common problems"_err_1 :ulb,b
12.2 "Reporting bugs"_err_2 :b
12.3 "Error & warning messages"_err_3 :ule,b
"Future and history"_Section_history.html :l
13.1 "Coming attractions"_hist_1 :ulb,b
13.2 "Past versions"_hist_2 :ule,b
:ole
:link(intro_1,Section_intro.html#intro_1)
:link(intro_2,Section_intro.html#intro_2)
:link(intro_3,Section_intro.html#intro_3)
:link(intro_4,Section_intro.html#intro_4)
:link(intro_5,Section_intro.html#intro_5)
:link(start_1,Section_start.html#start_1)
:link(start_2,Section_start.html#start_2)
:link(start_3,Section_start.html#start_3)
:link(start_4,Section_start.html#start_4)
:link(start_5,Section_start.html#start_5)
:link(start_6,Section_start.html#start_6)
:link(start_7,Section_start.html#start_7)
:link(start_8,Section_start.html#start_8)
:link(cmd_1,Section_commands.html#cmd_1)
:link(cmd_2,Section_commands.html#cmd_2)
:link(cmd_3,Section_commands.html#cmd_3)
:link(cmd_4,Section_commands.html#cmd_4)
:link(cmd_5,Section_commands.html#cmd_5)
:link(pkg_1,Section_packages.html#pkg_1)
:link(pkg_2,Section_packages.html#pkg_2)
:link(acc_1,Section_accelerate.html#acc_1)
:link(acc_2,Section_accelerate.html#acc_2)
:link(acc_3,Section_accelerate.html#acc_3)
:link(acc_4,Section_accelerate.html#acc_4)
:link(acc_5,Section_accelerate.html#acc_5)
:link(howto_1,Section_howto.html#howto_1)
:link(howto_2,Section_howto.html#howto_2)
:link(howto_3,Section_howto.html#howto_3)
:link(howto_4,Section_howto.html#howto_4)
:link(howto_5,Section_howto.html#howto_5)
:link(howto_6,Section_howto.html#howto_6)
:link(howto_7,Section_howto.html#howto_7)
:link(howto_8,Section_howto.html#howto_8)
:link(howto_9,Section_howto.html#howto_9)
:link(howto_10,Section_howto.html#howto_10)
:link(howto_11,Section_howto.html#howto_11)
:link(howto_12,Section_howto.html#howto_12)
:link(howto_13,Section_howto.html#howto_13)
:link(howto_14,Section_howto.html#howto_14)
:link(howto_15,Section_howto.html#howto_15)
:link(howto_16,Section_howto.html#howto_16)
:link(howto_17,Section_howto.html#howto_17)
:link(howto_18,Section_howto.html#howto_18)
:link(howto_19,Section_howto.html#howto_19)
:link(howto_20,Section_howto.html#howto_20)
:link(howto_21,Section_howto.html#howto_21)
:link(mod_1,Section_modify.html#mod_1)
:link(mod_2,Section_modify.html#mod_2)
:link(mod_3,Section_modify.html#mod_3)
:link(mod_4,Section_modify.html#mod_4)
:link(mod_5,Section_modify.html#mod_5)
:link(mod_6,Section_modify.html#mod_6)
:link(mod_7,Section_modify.html#mod_7)
:link(mod_8,Section_modify.html#mod_8)
:link(mod_9,Section_modify.html#mod_9)
:link(mod_10,Section_modify.html#mod_10)
:link(mod_11,Section_modify.html#mod_11)
:link(mod_12,Section_modify.html#mod_12)
:link(mod_13,Section_modify.html#mod_13)
:link(mod_14,Section_modify.html#mod_14)
:link(py_1,Section_python.html#py_1)
:link(py_2,Section_python.html#py_2)
:link(py_3,Section_python.html#py_3)
:link(py_4,Section_python.html#py_4)
:link(py_5,Section_python.html#py_5)
:link(py_6,Section_python.html#py_6)
:link(py_7,Section_python.html#py_7)
:link(err_1,Section_errors.html#err_1)
:link(err_2,Section_errors.html#err_2)
:link(err_3,Section_errors.html#err_3)
:link(hist_1,Section_history.html#hist_1)
:link(hist_2,Section_history.html#hist_2)
</BODY>
diff --git a/doc/PDF/pair_gayberne_extra.pdf b/doc/PDF/pair_gayberne_extra.pdf
index a2e2c8ec8..c82233992 100644
Binary files a/doc/PDF/pair_gayberne_extra.pdf and b/doc/PDF/pair_gayberne_extra.pdf differ
diff --git a/doc/Eqs/pair_gayberne_extra.tex b/doc/PDF/pair_gayberne_extra.tex
similarity index 100%
rename from doc/Eqs/pair_gayberne_extra.tex
rename to doc/PDF/pair_gayberne_extra.tex
diff --git a/doc/PDF/pair_resquared_extra.pdf b/doc/PDF/pair_resquared_extra.pdf
index 448e59c8f..c7956b37e 100644
Binary files a/doc/PDF/pair_resquared_extra.pdf and b/doc/PDF/pair_resquared_extra.pdf differ
diff --git a/doc/Eqs/pair_resquared_extra.tex b/doc/PDF/pair_resquared_extra.tex
old mode 100755
new mode 100644
similarity index 100%
rename from doc/Eqs/pair_resquared_extra.tex
rename to doc/PDF/pair_resquared_extra.tex
diff --git a/doc/Section_accelerate.html b/doc/Section_accelerate.html
index b8c2b3a62..88f985bf5 100644
--- a/doc/Section_accelerate.html
+++ b/doc/Section_accelerate.html
@@ -1,650 +1,654 @@
<HTML>
<CENTER><A HREF = "Section_packages.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> -
<A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_howto.html">Next
Section</A>
</CENTER>
<HR>
-<H3>5. Using accelerated CPU and GPU styles
+<H3>5. Accelerating LAMMPS performance
</H3>
+<P>This section describes various methods for improving LAMMPS
+performance for different classes of problems running
+on different kinds of machines.
+</P>
+5.1 <A HREF = "#acc_1">OPT package</A><BR>
+5.2 <A HREF = "#acc_2">USER-OMP package</A><BR>
+5.3 <A HREF = "#acc_3">GPU package</A><BR>
+5.4 <A HREF = "#acc_4">USER-CUDA package</A><BR>
+5.5 <A HREF = "#acc_5">Comparison of GPU and USER-CUDA packages</A> <BR>
+
<P>Accelerated versions of various <A HREF = "pair_style.html">pair_style</A>,
<A HREF = "fix.html">fixes</A>, <A HREF = "compute.html">computes</A>, and other commands have
been added to LAMMPS, which will typically run faster than the
standard non-accelerated versions, if you have the appropriate
hardware on your system.
</P>
<P>The accelerated styles have the same name as the standard styles,
except that a suffix is appended. Otherwise, the syntax for the
command is identical, their functionality is the same, and the
numerical results it produces should also be identical, except for
precision and round-off issues.
</P>
<P>For example, all of these variants of the basic Lennard-Jones pair
style exist in LAMMPS:
</P>
<UL><LI><A HREF = "pair_lj.html">pair_style lj/cut</A>
<LI><A HREF = "pair_lj.html">pair_style lj/cut/opt</A>
<LI><A HREF = "pair_lj.html">pair_style lj/cut/omp</A>
<LI><A HREF = "pair_lj.html">pair_style lj/cut/gpu</A>
<LI><A HREF = "pair_lj.html">pair_style lj/cut/cuda</A>
</UL>
<P>Assuming you have built LAMMPS with the appropriate package, these
styles can be invoked by specifying them explicitly in your input
script. Or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> to invoke the accelerated versions
automatically, without changing your input script. The
<A HREF = "suffix.html">suffix</A> command allows you to set a suffix explicitly and
to turn off/on the comand-line switch setting, both from within your
input script.
</P>
<P>Styles with an "opt" suffix are part of the OPT package and typically
speed-up the pairwise calculations of your simulation by 5-25%.
</P>
<P>Styles with an "omp" suffix are part of the USER-OMP package and allow
a pair-style to be run in multi-threaded mode using OpenMP. This can
be useful on nodes with high-core counts when using less MPI processes
than cores is advantageous, e.g. when running with PPPM so that FFTs
are run on fewer MPI processors or when the many MPI tasks would
overload the available bandwidth for communication.
</P>
<P>Styles with a "gpu" or "cuda" suffix are part of the GPU or USER-CUDA
packages, and can be run on NVIDIA GPUs associated with your CPUs.
The speed-up due to GPU usage depends on a variety of factors, as
discussed below.
</P>
<P>To see what styles are currently available in each of the accelerated
-packages, see <A HREF = "Section_commands.html#cmd_5">this section</A> of the
+packages, see <A HREF = "Section_commands.html#cmd_5">Section_commands 5</A> of the
manual. A list of accelerated styles is included in the pair, fix,
compute, and kspace sections.
</P>
<P>The following sections explain:
</P>
<UL><LI>what hardware and software the accelerated styles require
<LI>how to build LAMMPS with the accelerated packages in place
<LI>what changes (if any) are needed in your input scripts
<LI>guidelines for best performance
<LI>speed-ups you can expect
</UL>
<P>The final section compares and contrasts the GPU and USER-CUDA
packages, since they are both designed to use NVIDIA GPU hardware.
</P>
-5.1 <A HREF = "#acc_1">OPT package</A><BR>
-5.2 <A HREF = "#acc_2">USER-OMP package</A><BR>
-5.3 <A HREF = "#acc_3">GPU package</A><BR>
-5.4 <A HREF = "#acc_4">USER-CUDA package</A><BR>
-5.5 <A HREF = "#acc_5">Comparison of GPU and USER-CUDA packages</A> <BR>
-
<HR>
<HR>
<H4><A NAME = "acc_1"></A>5.1 OPT package
</H4>
<P>The OPT package was developed by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technologies). It contains a handful of pair styles whose compute()
methods were rewritten in C++ templated form to reduce the overhead
due to if tests and other conditional code.
</P>
<P>The procedure for building LAMMPS with the OPT package is simple. It
is the same as for any other package which has no additional library
dependencies:
</P>
<PRE>make yes-opt
make machine
</PRE>
<P>If your input script uses one of the OPT pair styles,
you can run it as follows:
</P>
<PRE>lmp_machine -sf opt < in.script
mpirun -np 4 lmp_machine -sf opt < in.script
</PRE>
<P>You should see a reduction in the "Pair time" printed out at the end
of the run. On most machines and problems, this will typically be a 5
to 20% savings.
</P>
<HR>
<HR>
<H4><A NAME = "acc_2"></A>5.2 USER-OMP package
</H4>
<P>The USER-OMP package was developed by Axel Kohlmeyer at Temple University.
It provides multi-threaded versions of most pair styles, all dihedral
styles and a few fixes in LAMMPS. The package currently uses the OpenMP
interface which requires using a specific compiler flag in the makefile
to enable multiple threads; without this flag the corresponding pair
styles will still be compiled and work, but do not support multi-threading.
</P>
<P><B>Building LAMMPS with the USER-OMP package:</B>
</P>
<P>The procedure for building LAMMPS with the USER-OMP package is simple.
You have to edit your machine specific makefile to add the flag to
enable OpenMP support to the CCFLAGS and LINKFLAGS variables. For the
GNU compilers for example this flag is called <I>-fopenmp</I>. Check your
compiler documentation to find out which flag you need to add.
The rest of the compilation is the same as for any other package which
has no additional library dependencies:
</P>
<PRE>make yes-user-omp
make machine
</PRE>
<P>Please note that this will only install accelerated versions
of styles that are already installed, so you want to install
this package as the last package, or else you may be missing
some accelerated styles. If you plan to uninstall some package,
you should first uninstall the USER-OMP package then the other
package and then re-install USER-OMP, to make sure that there
are no orphaned <I>omp</I> style files present, which would lead to
compilation errors.
</P>
<P>If your input script uses one of regular styles that are also
exist as an OpenMP version in the USER-OMP package you can run
it as follows:
</P>
<PRE>env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script
env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script
mpirun -x OMP_NUM_THREADS=2 -np 2 lmp_machine -sf omp -in in.script
</PRE>
<P>The value of the environment variable OMP_NUM_THREADS determines how
many threads per MPI task are launched. All three examples above use
a total of 4 CPU cores. For different MPI implementations the method
to pass the OMP_NUM_THREADS environment variable to all processes is
different. Two different variants, one for MPICH and OpenMPI, respectively
are shown above. Please check the documentation of your MPI installation
for additional details. Alternatively, the value provided by OMP_NUM_THREADS
can be overridded with the <A HREF = "package.html">package omp</A> command.
Depending on which styles are accelerated in your input, you should
see a reduction in the "Pair time" and/or "Bond time" and "Loop time"
printed out at the end of the run. The optimal ratio of MPI to OpenMP
can vary a lot and should always be confirmed through some benchmark
runs for the current system and on the current machine.
</P>
<P><B>Restrictions:</B>
</P>
<P>None of the pair styles in the USER-OMP package support the "inner",
"middle", "outer" options for r-RESPA integration, only the "pair"
option is supported.
</P>
<P><B>Parallel efficiency and performance tips:</B>
</P>
<P>In most simple cases the MPI parallelization in LAMMPS is more
efficient than multi-threading implemented in the USER-OMP package.
Also the parallel efficiency varies between individual styles.
On the other hand, in many cases you still want to use the <I>omp</I> version
- even when compiling or running without OpenMP support - since they
all contain optimizations similar to those in the OPT package, which
can result in serial speedup.
</P>
<P>Using multi-threading is most effective under the following circumstances:
</P>
<UL><LI>Individual compute nodes have a significant number of CPU cores
but the CPU itself has limited memory bandwidth, e.g. Intel Xeon 53xx
(Clovertown) and 54xx (Harpertown) quad core processors. Running
one MPI task per CPU core will result in significant performance
degradation, so that running with 4 or even only 2 MPI tasks per
nodes is faster. Running in hybrid MPI+OpenMP mode will reduce the
inter-node communication bandwidth contention in the same way,
but offers and additional speedup from utilizing the otherwise
idle CPU cores.
<LI>The interconnect used for MPI communication is not able to provide
sufficient bandwidth for a large number of MPI tasks per node.
This applies for example to running over gigabit ethernet or
on Cray XT4 or XT5 series supercomputers. Same as in the aforementioned
case this effect worsens with using an increasing number of nodes.
<LI>The input is a system that has an inhomogeneous particle density
which cannot be mapped well to the domain decomposition scheme
that LAMMPS employs. While this can be to some degree alleviated
through using the <A HREF = "processors.html">processors</A> keyword, multi-threading
provides a parallelism that parallelizes over the number of particles
not their distribution in space.
<LI>Finally, multi-threaded styles can improve performance when running
LAMMPS in "capability mode", i.e. near the point where the MPI
parallelism scales out. This can happen in particular when using
as kspace style for long-range electrostatics. Here the scaling
of the kspace style is the performance limiting factor and using
multi-threaded styles allows to operate the kspace style at the
limit of scaling and then increase performance parallelizing
the real space calculations with hybrid MPI+OpenMP. Sometimes
additional speedup can be achived by increasing the real-space
coulomb cutoff and thus reducing the work in the kspace part.
</UL>
<P>The best parallel efficiency from <I>omp</I> styles is typically
achieved when there is at least one MPI task per physical
processor, i.e. socket or die.
</P>
<P>Using threads on hyper-threading enabled cores is usually
counterproductive, as the cost in additional memory bandwidth
requirements is not offset by the gain in CPU utilization
through hyper-threading.
</P>
<P>A description of the multi-threading strategy and some performance
examples are <A HREF = "http://sites.google.com/site/akohlmey/software/lammps-icms/lammps-icms-tms2011-talk.pdf?attredirects=0&d=1">presented here</A>
</P>
<HR>
<HR>
<H4><A NAME = "acc_3"></A>5.3 GPU package
</H4>
<P>The GPU package was developed by Mike Brown at ORNL. It provides GPU
versions of several pair styles and for long-range Coulombics via the
PPPM command. It has the following features:
</P>
<UL><LI>The package is designed to exploit common GPU hardware configurations
where one or more GPUs are coupled with many cores of a multi-core
CPUs, e.g. within a node of a parallel machine.
<LI>Atom-based data (e.g. coordinates, forces) moves back-and-forth
between the CPU(s) and GPU every timestep.
<LI>Neighbor lists can be constructed on the CPU or on the GPU
<LI>The charge assignement and force interpolation portions of PPPM can be
run on the GPU. The FFT portion, which requires MPI communication
between processors, runs on the CPU.
<LI>Asynchronous force computations can be performed simultaneously on the
CPU(s) and GPU.
<LI>LAMMPS-specific code is in the GPU package. It makes calls to a
generic GPU library in the lib/gpu directory. This library provides
NVIDIA support as well as more general OpenCL support, so that the
same functionality can eventually be supported on a variety of GPU
hardware.
</UL>
<P><B>Hardware and software requirements:</B>
</P>
<P>To use this package, you currently need to have specific NVIDIA
hardware and install specific NVIDIA CUDA software on your system:
</P>
<UL><LI>Check if you have an NVIDIA card: cat /proc/driver/nvidia/cards/0
<LI>Go to http://www.nvidia.com/object/cuda_get.html
<LI>Install a driver and toolkit appropriate for your system (SDK is not necessary)
<LI>Follow the instructions in lammps/lib/gpu/README to build the library (see below)
<LI>Run lammps/lib/gpu/nvc_get_devices to list supported devices and properties
</UL>
<P><B>Building LAMMPS with the GPU package:</B>
</P>
<P>As with other packages that include a separately compiled library, you
need to first build the GPU library, before building LAMMPS itself.
General instructions for doing this are in <A HREF = "doc/Section_start.html#start_3">this
section</A> of the manual. For this
package, do the following, using a Makefile in lib/gpu appropriate for
your system:
</P>
<PRE>cd lammps/lib/gpu
make -f Makefile.linux
(see further instructions in lammps/lib/gpu/README)
</PRE>
<P>If you are successful, you will produce the file lib/libgpu.a.
</P>
<P>Now you are ready to build LAMMPS with the GPU package installed:
</P>
<PRE>cd lammps/src
make yes-gpu
make machine
</PRE>
<P>Note that the lo-level Makefile (e.g. src/MAKE/Makefile.linux) has
these settings: gpu_SYSINC, gpu_SYSLIB, gpu_SYSPATH. These need to be
set appropriately to include the paths and settings for the CUDA
system software on your machine. See src/MAKE/Makefile.g++ for an
example.
</P>
<P><B>GPU configuration</B>
</P>
<P>When using GPUs, you are restricted to one physical GPU per LAMMPS
process, which is an MPI process running on a single core or
processor. Multiple MPI processes (CPU cores) can share a single GPU,
and in many cases it will be more efficient to run this way.
</P>
<P><B>Input script requirements:</B>
</P>
<P>Additional input script requirements to run pair or PPPM styles with a
<I>gpu</I> suffix are as follows:
</P>
<UL><LI>To invoke specific styles from the GPU package, you can either append
"gpu" to the style name (e.g. pair_style lj/cut/gpu), or use the
<A HREF = "Section_start.html#start_6">-suffix command-line switch</A>, or use the
<A HREF = "suffix.html">suffix</A> command.
<LI>The <A HREF = "newton.html">newton pair</A> setting must be <I>off</I>.
<LI>The <A HREF = "package.html">package gpu</A> command must be used near the beginning
of your script to control the GPU selection and initialization
settings. It also has an option to enable asynchronous splitting of
force computations between the CPUs and GPUs.
</UL>
<P>As an example, if you have two GPUs per node and 8 CPU cores per node,
and would like to run on 4 nodes (32 cores) with dynamic balancing of
force calculation across CPU and GPU cores, you could specify
</P>
<PRE>package gpu force/neigh 0 1 -1
</PRE>
<P>In this case, all CPU cores and GPU devices on the nodes would be
utilized. Each GPU device would be shared by 4 CPU cores. The CPU
cores would perform force calculations for some fraction of the
particles at the same time the GPUs performed force calculation for
the other particles.
</P>
<P><B>Timing output:</B>
</P>
<P>As described by the <A HREF = "package.html">package gpu</A> command, GPU
accelerated pair styles can perform computations asynchronously with
CPU computations. The "Pair" time reported by LAMMPS will be the
maximum of the time required to complete the CPU pair style
computations and the time required to complete the GPU pair style
computations. Any time spent for GPU-enabled pair styles for
computations that run simultaneously with <A HREF = "bond_style.html">bond</A>,
<A HREF = "angle_style.html">angle</A>, <A HREF = "dihedral_style.html">dihedral</A>,
<A HREF = "improper_style.html">improper</A>, and <A HREF = "kspace_style.html">long-range</A>
calculations will not be included in the "Pair" time.
</P>
<P>When the <I>mode</I> setting for the package gpu command is force/neigh,
the time for neighbor list calculations on the GPU will be added into
the "Pair" time, not the "Neigh" time. An additional breakdown of the
times required for various tasks on the GPU (data copy, neighbor
calculations, force computations, etc) are output only with the LAMMPS
screen output (not in the log file) at the end of each run. These
timings represent total time spent on the GPU for each routine,
regardless of asynchronous CPU calculations.
</P>
<P><B>Performance tips:</B>
</P>
<P>Generally speaking, for best performance, you should use multiple CPUs
per GPU, as provided my most multi-core CPU/GPU configurations.
</P>
<P>Because of the large number of cores within each GPU device, it may be
more efficient to run on fewer processes per GPU when the number of
particles per MPI process is small (100's of particles); this can be
necessary to keep the GPU cores busy.
</P>
<P>See the lammps/lib/gpu/README file for instructions on how to build
the GPU library for single, mixed, or double precision. The latter
requires that your GPU card support double precision.
</P>
<HR>
<HR>
<H4><A NAME = "acc_4"></A>5.4 USER-CUDA package
</H4>
<P>The USER-CUDA package was developed by Christian Trott at U Technology
Ilmenau in Germany. It provides NVIDIA GPU versions of many pair
styles, many fixes, a few computes, and for long-range Coulombics via
the PPPM command. It has the following features:
</P>
<UL><LI>The package is designed to allow an entire LAMMPS calculation, for
many timesteps, to run entirely on the GPU (except for inter-processor
MPI communication), so that atom-based data (e.g. coordinates, forces)
do not have to move back-and-forth between the CPU and GPU.
<LI>The speed-up advantage of this approach is typically better when the
number of atoms per GPU is large
<LI>Data will stay on the GPU until a timestep where a non-GPU-ized fix or
compute is invoked. Whenever a non-GPU operation occurs (fix,
compute, output), data automatically moves back to the CPU as needed.
This may incur a performance penalty, but should otherwise work
transparently.
<LI>Neighbor lists for GPU-ized pair styles are constructed on the
GPU.
<LI>The package only supports use of a single CPU (core) with each
GPU.
</UL>
<P><B>Hardware and software requirements:</B>
</P>
<P>To use this package, you need to have specific NVIDIA hardware and
install specific NVIDIA CUDA software on your system.
</P>
<P>Your NVIDIA GPU needs to support Compute Capability 1.3. This list may
help you to find out the Compute Capability of your card:
</P>
<P>http://en.wikipedia.org/wiki/Comparison_of_Nvidia_graphics_processing_units
</P>
<P>Install the Nvidia Cuda Toolkit in version 3.2 or higher and the
corresponding GPU drivers. The Nvidia Cuda SDK is not required for
LAMMPSCUDA but we recommend it be installed. You can then make sure
that its sample projects can be compiled without problems.
</P>
<P><B>Building LAMMPS with the USER-CUDA package:</B>
</P>
<P>As with other packages that include a separately compiled library, you
need to first build the USER-CUDA library, before building LAMMPS
itself. General instructions for doing this are in <A HREF = "doc/Section_start.html#start_3">this
section</A> of the manual. For this
package, do the following, using settings in the lib/cuda Makefiles
appropriate for your system:
</P>
<UL><LI>Go to the lammps/lib/cuda directory
<LI>If your <I>CUDA</I> toolkit is not installed in the default system directoy
<I>/usr/local/cuda</I> edit the file <I>lib/cuda/Makefile.common</I>
accordingly.
<LI>Type "make OPTIONS", where <I>OPTIONS</I> are one or more of the following
options. The settings will be written to the
<I>lib/cuda/Makefile.defaults</I> and used in the next step.
<PRE><I>precision=N</I> to set the precision level
N = 1 for single precision (default)
N = 2 for double precision
N = 3 for positions in double precision
N = 4 for positions and velocities in double precision
<I>arch=M</I> to set GPU compute capability
M = 20 for CC2.0 (GF100/110, e.g. C2050,GTX580,GTX470) (default)
M = 21 for CC2.1 (GF104/114, e.g. GTX560, GTX460, GTX450)
M = 13 for CC1.3 (GF200, e.g. C1060, GTX285)
<I>prec_timer=0/1</I> to use hi-precision timers
0 = do not use them (default)
1 = use these timers
this is usually only useful for Mac machines
<I>dbg=0/1</I> to activate debug mode
0 = no debug mode (default)
1 = yes debug mode
this is only useful for developers
<I>cufft=1</I> to determine usage of CUDA FFT library
0 = no CUFFT support (default)
in the future other CUDA-enabled FFT libraries might be supported
</PRE>
<LI>Type "make" to build the library. If you are successful, you will
produce the file lib/libcuda.a.
</UL>
<P>Now you are ready to build LAMMPS with the USER-CUDA package installed:
</P>
<PRE>cd lammps/src
make yes-user-cuda
make machine
</PRE>
<P>Note that the LAMMPS build references the lib/cuda/Makefile.common
file to extract setting specific CUDA settings. So it is important
that you have first built the cuda library (in lib/cuda) using
settings appropriate to your system.
</P>
<P><B>Input script requirements:</B>
</P>
<P>Additional input script requirements to run styles with a <I>cuda</I>
suffix are as follows:
</P>
<UL><LI>To invoke specific styles from the USER-CUDA package, you can either
append "cuda" to the style name (e.g. pair_style lj/cut/cuda), or use
the <A HREF = "Section_start.html#start_6">-suffix command-line switch</A>, or use
the <A HREF = "suffix.html">suffix</A> command. One exception is that the
<A HREF = "kspace_style.html">kspace_style pppm/cuda</A> command has to be requested
explicitly.
<LI>To use the USER-CUDA package with its default settings, no additional
command is needed in your input script. This is because when LAMMPS
starts up, it detects if it has been built with the USER-CUDA package.
See the <A HREF = "Section_start.html#start_6">-cuda command-line switch</A> for
more details.
<LI>To change settings for the USER-CUDA package at run-time, the <A HREF = "package.html">package
cuda</A> command can be used near the beginning of your
input script. See the <A HREF = "package.html">package</A> command doc page for
details.
</UL>
<P><B>Performance tips:</B>
</P>
<P>The USER-CUDA package offers more speed-up relative to CPU performance
when the number of atoms per GPU is large, e.g. on the order of tens
or hundreds of 1000s.
</P>
<P>As noted above, this package will continue to run a simulation
entirely on the GPU(s) (except for inter-processor MPI communication),
for multiple timesteps, until a CPU calculation is required, either by
a fix or compute that is non-GPU-ized, or until output is performed
(thermo or dump snapshot or restart file). The less often this
occurs, the faster your simulation will run.
</P>
<HR>
<HR>
<H4><A NAME = "acc_5"></A>5.5 Comparison of GPU and USER-CUDA packages
</H4>
<P>Both the GPU and USER-CUDA packages accelerate a LAMMPS calculation
using NVIDIA hardware, but they do it in different ways.
</P>
<P>As a consequence, for a particular simulation on specific hardware,
one package may be faster than the other. We give guidelines below,
but the best way to determine which package is faster for your input
script is to try both of them on your machine. See the benchmarking
section below for examples where this has been done.
</P>
<P><B>Guidelines for using each package optimally:</B>
</P>
<UL><LI>The GPU package allows you to assign multiple CPUs (cores) to a single
GPU (a common configuration for "hybrid" nodes that contain multicore
CPU(s) and GPU(s)) and works effectively in this mode. The USER-CUDA
package does not allow this; you can only use one CPU per GPU.
<LI>The GPU package moves per-atom data (coordinates, forces)
back-and-forth between the CPU and GPU every timestep. The USER-CUDA
package only does this on timesteps when a CPU calculation is required
(e.g. to invoke a fix or compute that is non-GPU-ized). Hence, if you
can formulate your input script to only use GPU-ized fixes and
computes, and avoid doing I/O too often (thermo output, dump file
snapshots, restart files), then the data transfer cost of the
USER-CUDA package can be very low, causing it to run faster than the
GPU package.
<LI>The GPU package is often faster than the USER-CUDA package, if the
number of atoms per GPU is "small". The crossover point, in terms of
atoms/GPU at which the USER-CUDA package becomes faster depends
strongly on the pair style. For example, for a simple Lennard Jones
system the crossover (in single precision) is often about 50K-100K
atoms per GPU. When performing double precision calculations the
crossover point can be significantly smaller.
<LI>Both packages compute bonded interactions (bonds, angles, etc) on the
CPU. This means a model with bonds will force the USER-CUDA package
to transfer per-atom data back-and-forth between the CPU and GPU every
timestep. If the GPU package is running with several MPI processes
assigned to one GPU, the cost of computing the bonded interactions is
spread across more CPUs and hence the GPU package can run faster.
<LI>When using the GPU package with multiple CPUs assigned to one GPU, its
performance depends to some extent on high bandwidth between the CPUs
and the GPU. Hence its performance is affected if full 16 PCIe lanes
are not available for each GPU. In HPC environments this can be the
case if S2050/70 servers are used, where two devices generally share
one PCIe 2.0 16x slot. Also many multi-GPU mainboards do not provide
full 16 lanes to each of the PCIe 2.0 16x slots.
</UL>
<P><B>Differences between the two packages:</B>
</P>
<UL><LI>The GPU package accelerates only pair force, neighbor list, and PPPM
calculations. The USER-CUDA package currently supports a wider range
of pair styles and can also accelerate many fix styles and some
compute styles, as well as neighbor list and PPPM calculations.
<LI>The GPU package uses more GPU memory than the USER-CUDA package. This
is generally not a problem since typical runs are computation-limited
rather than memory-limited.
</UL>
<P><B>Examples:</B>
</P>
<P>The LAMMPS distribution has two directories with sample input scripts
for the GPU and USER-CUDA packages.
</P>
<UL><LI>lammps/examples/gpu = GPU package files
<LI>lammps/examples/USER/cuda = USER-CUDA package files
</UL>
<P>These contain input scripts for identical systems, so they can be used
to benchmark the performance of both packages on your system.
</P>
<HR>
<P><B>Benchmark data:</B>
</P>
<P>NOTE: We plan to add some benchmark results and plots here for the
examples described in the previous section.
</P>
<P>Simulations:
</P>
<P>1. Lennard Jones
</P>
<UL><LI>256,000 atoms
<LI>2.5 A cutoff
<LI>0.844 density
</UL>
<P>2. Lennard Jones
</P>
<UL><LI>256,000 atoms
<LI>5.0 A cutoff
<LI>0.844 density
</UL>
<P>3. Rhodopsin model
</P>
<UL><LI>256,000 atoms
<LI>10A cutoff
<LI>Coulomb via PPPM
</UL>
<P>4. Lihtium-Phosphate
</P>
<UL><LI>295650 atoms
<LI>15A cutoff
<LI>Coulomb via PPPM
</UL>
<P>Hardware:
</P>
<P>Workstation:
</P>
<UL><LI>2x GTX470
<LI>i7 950@3GHz
<LI>24Gb DDR3 @ 1066Mhz
<LI>CentOS 5.5
<LI>CUDA 3.2
<LI>Driver 260.19.12
</UL>
<P>eStella:
</P>
<UL><LI>6 Nodes
<LI>2xC2050
<LI>2xQDR Infiniband interconnect(aggregate bandwidth 80GBps)
<LI>Intel X5650 HexCore @ 2.67GHz
<LI>SL 5.5
<LI>CUDA 3.2
<LI>Driver 260.19.26
</UL>
<P>Keeneland:
</P>
<UL><LI>HP SL-390 (Ariston) cluster
<LI>120 nodes
<LI>2x Intel Westmere hex-core CPUs
<LI>3xC2070s
<LI>QDR InfiniBand interconnect
</UL>
</HTML>
diff --git a/doc/Section_accelerate.txt b/doc/Section_accelerate.txt
index 4a9d08b00..37a49d5f6 100644
--- a/doc/Section_accelerate.txt
+++ b/doc/Section_accelerate.txt
@@ -1,640 +1,644 @@
"Previous Section"_Section_packages.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_howto.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
-5. Using accelerated CPU and GPU styles :h3
+5. Accelerating LAMMPS performance :h3
+
+This section describes various methods for improving LAMMPS
+performance for different classes of problems running
+on different kinds of machines.
+
+5.1 "OPT package"_#acc_1
+5.2 "USER-OMP package"_#acc_2
+5.3 "GPU package"_#acc_3
+5.4 "USER-CUDA package"_#acc_4
+5.5 "Comparison of GPU and USER-CUDA packages"_#acc_5 :all(b)
Accelerated versions of various "pair_style"_pair_style.html,
"fixes"_fix.html, "computes"_compute.html, and other commands have
been added to LAMMPS, which will typically run faster than the
standard non-accelerated versions, if you have the appropriate
hardware on your system.
The accelerated styles have the same name as the standard styles,
except that a suffix is appended. Otherwise, the syntax for the
command is identical, their functionality is the same, and the
numerical results it produces should also be identical, except for
precision and round-off issues.
For example, all of these variants of the basic Lennard-Jones pair
style exist in LAMMPS:
"pair_style lj/cut"_pair_lj.html
"pair_style lj/cut/opt"_pair_lj.html
"pair_style lj/cut/omp"_pair_lj.html
"pair_style lj/cut/gpu"_pair_lj.html
"pair_style lj/cut/cuda"_pair_lj.html :ul
Assuming you have built LAMMPS with the appropriate package, these
styles can be invoked by specifying them explicitly in your input
script. Or you can use the "-suffix command-line
switch"_Section_start.html#start_6 to invoke the accelerated versions
automatically, without changing your input script. The
"suffix"_suffix.html command allows you to set a suffix explicitly and
to turn off/on the comand-line switch setting, both from within your
input script.
Styles with an "opt" suffix are part of the OPT package and typically
speed-up the pairwise calculations of your simulation by 5-25%.
Styles with an "omp" suffix are part of the USER-OMP package and allow
a pair-style to be run in multi-threaded mode using OpenMP. This can
be useful on nodes with high-core counts when using less MPI processes
than cores is advantageous, e.g. when running with PPPM so that FFTs
are run on fewer MPI processors or when the many MPI tasks would
overload the available bandwidth for communication.
Styles with a "gpu" or "cuda" suffix are part of the GPU or USER-CUDA
packages, and can be run on NVIDIA GPUs associated with your CPUs.
The speed-up due to GPU usage depends on a variety of factors, as
discussed below.
To see what styles are currently available in each of the accelerated
-packages, see "this section"_Section_commands.html#cmd_5 of the
+packages, see "Section_commands 5"_Section_commands.html#cmd_5 of the
manual. A list of accelerated styles is included in the pair, fix,
compute, and kspace sections.
The following sections explain:
what hardware and software the accelerated styles require
how to build LAMMPS with the accelerated packages in place
what changes (if any) are needed in your input scripts
guidelines for best performance
speed-ups you can expect :ul
The final section compares and contrasts the GPU and USER-CUDA
packages, since they are both designed to use NVIDIA GPU hardware.
-5.1 "OPT package"_#acc_1
-5.2 "USER-OMP package"_#acc_2
-5.3 "GPU package"_#acc_3
-5.4 "USER-CUDA package"_#acc_4
-5.5 "Comparison of GPU and USER-CUDA packages"_#acc_5 :all(b)
-
:line
:line
5.1 OPT package :h4,link(acc_1)
The OPT package was developed by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technologies). It contains a handful of pair styles whose compute()
methods were rewritten in C++ templated form to reduce the overhead
due to if tests and other conditional code.
The procedure for building LAMMPS with the OPT package is simple. It
is the same as for any other package which has no additional library
dependencies:
make yes-opt
make machine :pre
If your input script uses one of the OPT pair styles,
you can run it as follows:
lmp_machine -sf opt < in.script
mpirun -np 4 lmp_machine -sf opt < in.script :pre
You should see a reduction in the "Pair time" printed out at the end
of the run. On most machines and problems, this will typically be a 5
to 20% savings.
:line
:line
5.2 USER-OMP package :h4,link(acc_2)
The USER-OMP package was developed by Axel Kohlmeyer at Temple University.
It provides multi-threaded versions of most pair styles, all dihedral
styles and a few fixes in LAMMPS. The package currently uses the OpenMP
interface which requires using a specific compiler flag in the makefile
to enable multiple threads; without this flag the corresponding pair
styles will still be compiled and work, but do not support multi-threading.
[Building LAMMPS with the USER-OMP package:]
The procedure for building LAMMPS with the USER-OMP package is simple.
You have to edit your machine specific makefile to add the flag to
enable OpenMP support to the CCFLAGS and LINKFLAGS variables. For the
GNU compilers for example this flag is called {-fopenmp}. Check your
compiler documentation to find out which flag you need to add.
The rest of the compilation is the same as for any other package which
has no additional library dependencies:
make yes-user-omp
make machine :pre
Please note that this will only install accelerated versions
of styles that are already installed, so you want to install
this package as the last package, or else you may be missing
some accelerated styles. If you plan to uninstall some package,
you should first uninstall the USER-OMP package then the other
package and then re-install USER-OMP, to make sure that there
are no orphaned {omp} style files present, which would lead to
compilation errors.
If your input script uses one of regular styles that are also
exist as an OpenMP version in the USER-OMP package you can run
it as follows:
env OMP_NUM_THREADS=4 lmp_serial -sf omp -in in.script
env OMP_NUM_THREADS=2 mpirun -np 2 lmp_machine -sf omp -in in.script
mpirun -x OMP_NUM_THREADS=2 -np 2 lmp_machine -sf omp -in in.script :pre
The value of the environment variable OMP_NUM_THREADS determines how
many threads per MPI task are launched. All three examples above use
a total of 4 CPU cores. For different MPI implementations the method
to pass the OMP_NUM_THREADS environment variable to all processes is
different. Two different variants, one for MPICH and OpenMPI, respectively
are shown above. Please check the documentation of your MPI installation
for additional details. Alternatively, the value provided by OMP_NUM_THREADS
can be overridded with the "package omp"_package.html command.
Depending on which styles are accelerated in your input, you should
see a reduction in the "Pair time" and/or "Bond time" and "Loop time"
printed out at the end of the run. The optimal ratio of MPI to OpenMP
can vary a lot and should always be confirmed through some benchmark
runs for the current system and on the current machine.
[Restrictions:]
None of the pair styles in the USER-OMP package support the "inner",
"middle", "outer" options for r-RESPA integration, only the "pair"
option is supported.
[Parallel efficiency and performance tips:]
In most simple cases the MPI parallelization in LAMMPS is more
efficient than multi-threading implemented in the USER-OMP package.
Also the parallel efficiency varies between individual styles.
On the other hand, in many cases you still want to use the {omp} version
- even when compiling or running without OpenMP support - since they
all contain optimizations similar to those in the OPT package, which
can result in serial speedup.
Using multi-threading is most effective under the following circumstances:
Individual compute nodes have a significant number of CPU cores
but the CPU itself has limited memory bandwidth, e.g. Intel Xeon 53xx
(Clovertown) and 54xx (Harpertown) quad core processors. Running
one MPI task per CPU core will result in significant performance
degradation, so that running with 4 or even only 2 MPI tasks per
nodes is faster. Running in hybrid MPI+OpenMP mode will reduce the
inter-node communication bandwidth contention in the same way,
but offers and additional speedup from utilizing the otherwise
idle CPU cores. :ulb,l
The interconnect used for MPI communication is not able to provide
sufficient bandwidth for a large number of MPI tasks per node.
This applies for example to running over gigabit ethernet or
on Cray XT4 or XT5 series supercomputers. Same as in the aforementioned
case this effect worsens with using an increasing number of nodes. :l
The input is a system that has an inhomogeneous particle density
which cannot be mapped well to the domain decomposition scheme
that LAMMPS employs. While this can be to some degree alleviated
through using the "processors"_processors.html keyword, multi-threading
provides a parallelism that parallelizes over the number of particles
not their distribution in space. :l
Finally, multi-threaded styles can improve performance when running
LAMMPS in "capability mode", i.e. near the point where the MPI
parallelism scales out. This can happen in particular when using
as kspace style for long-range electrostatics. Here the scaling
of the kspace style is the performance limiting factor and using
multi-threaded styles allows to operate the kspace style at the
limit of scaling and then increase performance parallelizing
the real space calculations with hybrid MPI+OpenMP. Sometimes
additional speedup can be achived by increasing the real-space
coulomb cutoff and thus reducing the work in the kspace part. :l,ule
The best parallel efficiency from {omp} styles is typically
achieved when there is at least one MPI task per physical
processor, i.e. socket or die.
Using threads on hyper-threading enabled cores is usually
counterproductive, as the cost in additional memory bandwidth
requirements is not offset by the gain in CPU utilization
through hyper-threading.
A description of the multi-threading strategy and some performance
examples are "presented here"_http://sites.google.com/site/akohlmey/software/lammps-icms/lammps-icms-tms2011-talk.pdf?attredirects=0&d=1
:line
:line
5.3 GPU package :h4,link(acc_3)
The GPU package was developed by Mike Brown at ORNL. It provides GPU
versions of several pair styles and for long-range Coulombics via the
PPPM command. It has the following features:
The package is designed to exploit common GPU hardware configurations
where one or more GPUs are coupled with many cores of a multi-core
CPUs, e.g. within a node of a parallel machine. :ulb,l
Atom-based data (e.g. coordinates, forces) moves back-and-forth
between the CPU(s) and GPU every timestep. :l
Neighbor lists can be constructed on the CPU or on the GPU :l
The charge assignement and force interpolation portions of PPPM can be
run on the GPU. The FFT portion, which requires MPI communication
between processors, runs on the CPU. :l
Asynchronous force computations can be performed simultaneously on the
CPU(s) and GPU. :l
LAMMPS-specific code is in the GPU package. It makes calls to a
generic GPU library in the lib/gpu directory. This library provides
NVIDIA support as well as more general OpenCL support, so that the
same functionality can eventually be supported on a variety of GPU
hardware. :l,ule
[Hardware and software requirements:]
To use this package, you currently need to have specific NVIDIA
hardware and install specific NVIDIA CUDA software on your system:
Check if you have an NVIDIA card: cat /proc/driver/nvidia/cards/0
Go to http://www.nvidia.com/object/cuda_get.html
Install a driver and toolkit appropriate for your system (SDK is not necessary)
Follow the instructions in lammps/lib/gpu/README to build the library (see below)
Run lammps/lib/gpu/nvc_get_devices to list supported devices and properties :ul
[Building LAMMPS with the GPU package:]
As with other packages that include a separately compiled library, you
need to first build the GPU library, before building LAMMPS itself.
General instructions for doing this are in "this
section"_doc/Section_start.html#start_3 of the manual. For this
package, do the following, using a Makefile in lib/gpu appropriate for
your system:
cd lammps/lib/gpu
make -f Makefile.linux
(see further instructions in lammps/lib/gpu/README) :pre
If you are successful, you will produce the file lib/libgpu.a.
Now you are ready to build LAMMPS with the GPU package installed:
cd lammps/src
make yes-gpu
make machine :pre
Note that the lo-level Makefile (e.g. src/MAKE/Makefile.linux) has
these settings: gpu_SYSINC, gpu_SYSLIB, gpu_SYSPATH. These need to be
set appropriately to include the paths and settings for the CUDA
system software on your machine. See src/MAKE/Makefile.g++ for an
example.
[GPU configuration]
When using GPUs, you are restricted to one physical GPU per LAMMPS
process, which is an MPI process running on a single core or
processor. Multiple MPI processes (CPU cores) can share a single GPU,
and in many cases it will be more efficient to run this way.
[Input script requirements:]
Additional input script requirements to run pair or PPPM styles with a
{gpu} suffix are as follows:
To invoke specific styles from the GPU package, you can either append
"gpu" to the style name (e.g. pair_style lj/cut/gpu), or use the
"-suffix command-line switch"_Section_start.html#start_6, or use the
"suffix"_suffix.html command. :ulb,l
The "newton pair"_newton.html setting must be {off}. :l
The "package gpu"_package.html command must be used near the beginning
of your script to control the GPU selection and initialization
settings. It also has an option to enable asynchronous splitting of
force computations between the CPUs and GPUs. :l,ule
As an example, if you have two GPUs per node and 8 CPU cores per node,
and would like to run on 4 nodes (32 cores) with dynamic balancing of
force calculation across CPU and GPU cores, you could specify
package gpu force/neigh 0 1 -1 :pre
In this case, all CPU cores and GPU devices on the nodes would be
utilized. Each GPU device would be shared by 4 CPU cores. The CPU
cores would perform force calculations for some fraction of the
particles at the same time the GPUs performed force calculation for
the other particles.
[Timing output:]
As described by the "package gpu"_package.html command, GPU
accelerated pair styles can perform computations asynchronously with
CPU computations. The "Pair" time reported by LAMMPS will be the
maximum of the time required to complete the CPU pair style
computations and the time required to complete the GPU pair style
computations. Any time spent for GPU-enabled pair styles for
computations that run simultaneously with "bond"_bond_style.html,
"angle"_angle_style.html, "dihedral"_dihedral_style.html,
"improper"_improper_style.html, and "long-range"_kspace_style.html
calculations will not be included in the "Pair" time.
When the {mode} setting for the package gpu command is force/neigh,
the time for neighbor list calculations on the GPU will be added into
the "Pair" time, not the "Neigh" time. An additional breakdown of the
times required for various tasks on the GPU (data copy, neighbor
calculations, force computations, etc) are output only with the LAMMPS
screen output (not in the log file) at the end of each run. These
timings represent total time spent on the GPU for each routine,
regardless of asynchronous CPU calculations.
[Performance tips:]
Generally speaking, for best performance, you should use multiple CPUs
per GPU, as provided my most multi-core CPU/GPU configurations.
Because of the large number of cores within each GPU device, it may be
more efficient to run on fewer processes per GPU when the number of
particles per MPI process is small (100's of particles); this can be
necessary to keep the GPU cores busy.
See the lammps/lib/gpu/README file for instructions on how to build
the GPU library for single, mixed, or double precision. The latter
requires that your GPU card support double precision.
:line
:line
5.4 USER-CUDA package :h4,link(acc_4)
The USER-CUDA package was developed by Christian Trott at U Technology
Ilmenau in Germany. It provides NVIDIA GPU versions of many pair
styles, many fixes, a few computes, and for long-range Coulombics via
the PPPM command. It has the following features:
The package is designed to allow an entire LAMMPS calculation, for
many timesteps, to run entirely on the GPU (except for inter-processor
MPI communication), so that atom-based data (e.g. coordinates, forces)
do not have to move back-and-forth between the CPU and GPU. :ulb,l
The speed-up advantage of this approach is typically better when the
number of atoms per GPU is large :l
Data will stay on the GPU until a timestep where a non-GPU-ized fix or
compute is invoked. Whenever a non-GPU operation occurs (fix,
compute, output), data automatically moves back to the CPU as needed.
This may incur a performance penalty, but should otherwise work
transparently. :l
Neighbor lists for GPU-ized pair styles are constructed on the
GPU. :l
The package only supports use of a single CPU (core) with each
GPU. :l,ule
[Hardware and software requirements:]
To use this package, you need to have specific NVIDIA hardware and
install specific NVIDIA CUDA software on your system.
Your NVIDIA GPU needs to support Compute Capability 1.3. This list may
help you to find out the Compute Capability of your card:
http://en.wikipedia.org/wiki/Comparison_of_Nvidia_graphics_processing_units
Install the Nvidia Cuda Toolkit in version 3.2 or higher and the
corresponding GPU drivers. The Nvidia Cuda SDK is not required for
LAMMPSCUDA but we recommend it be installed. You can then make sure
that its sample projects can be compiled without problems.
[Building LAMMPS with the USER-CUDA package:]
As with other packages that include a separately compiled library, you
need to first build the USER-CUDA library, before building LAMMPS
itself. General instructions for doing this are in "this
section"_doc/Section_start.html#start_3 of the manual. For this
package, do the following, using settings in the lib/cuda Makefiles
appropriate for your system:
Go to the lammps/lib/cuda directory :ulb,l
If your {CUDA} toolkit is not installed in the default system directoy
{/usr/local/cuda} edit the file {lib/cuda/Makefile.common}
accordingly. :l
Type "make OPTIONS", where {OPTIONS} are one or more of the following
options. The settings will be written to the
{lib/cuda/Makefile.defaults} and used in the next step. :l
{precision=N} to set the precision level
N = 1 for single precision (default)
N = 2 for double precision
N = 3 for positions in double precision
N = 4 for positions and velocities in double precision
{arch=M} to set GPU compute capability
M = 20 for CC2.0 (GF100/110, e.g. C2050,GTX580,GTX470) (default)
M = 21 for CC2.1 (GF104/114, e.g. GTX560, GTX460, GTX450)
M = 13 for CC1.3 (GF200, e.g. C1060, GTX285)
{prec_timer=0/1} to use hi-precision timers
0 = do not use them (default)
1 = use these timers
this is usually only useful for Mac machines
{dbg=0/1} to activate debug mode
0 = no debug mode (default)
1 = yes debug mode
this is only useful for developers
{cufft=1} to determine usage of CUDA FFT library
0 = no CUFFT support (default)
in the future other CUDA-enabled FFT libraries might be supported :pre
Type "make" to build the library. If you are successful, you will
produce the file lib/libcuda.a. :l,ule
Now you are ready to build LAMMPS with the USER-CUDA package installed:
cd lammps/src
make yes-user-cuda
make machine :pre
Note that the LAMMPS build references the lib/cuda/Makefile.common
file to extract setting specific CUDA settings. So it is important
that you have first built the cuda library (in lib/cuda) using
settings appropriate to your system.
[Input script requirements:]
Additional input script requirements to run styles with a {cuda}
suffix are as follows:
To invoke specific styles from the USER-CUDA package, you can either
append "cuda" to the style name (e.g. pair_style lj/cut/cuda), or use
the "-suffix command-line switch"_Section_start.html#start_6, or use
the "suffix"_suffix.html command. One exception is that the
"kspace_style pppm/cuda"_kspace_style.html command has to be requested
explicitly. :ulb,l
To use the USER-CUDA package with its default settings, no additional
command is needed in your input script. This is because when LAMMPS
starts up, it detects if it has been built with the USER-CUDA package.
See the "-cuda command-line switch"_Section_start.html#start_6 for
more details. :l
To change settings for the USER-CUDA package at run-time, the "package
cuda"_package.html command can be used near the beginning of your
input script. See the "package"_package.html command doc page for
details. :l,ule
[Performance tips:]
The USER-CUDA package offers more speed-up relative to CPU performance
when the number of atoms per GPU is large, e.g. on the order of tens
or hundreds of 1000s.
As noted above, this package will continue to run a simulation
entirely on the GPU(s) (except for inter-processor MPI communication),
for multiple timesteps, until a CPU calculation is required, either by
a fix or compute that is non-GPU-ized, or until output is performed
(thermo or dump snapshot or restart file). The less often this
occurs, the faster your simulation will run.
:line
:line
5.5 Comparison of GPU and USER-CUDA packages :h4,link(acc_5)
Both the GPU and USER-CUDA packages accelerate a LAMMPS calculation
using NVIDIA hardware, but they do it in different ways.
As a consequence, for a particular simulation on specific hardware,
one package may be faster than the other. We give guidelines below,
but the best way to determine which package is faster for your input
script is to try both of them on your machine. See the benchmarking
section below for examples where this has been done.
[Guidelines for using each package optimally:]
The GPU package allows you to assign multiple CPUs (cores) to a single
GPU (a common configuration for "hybrid" nodes that contain multicore
CPU(s) and GPU(s)) and works effectively in this mode. The USER-CUDA
package does not allow this; you can only use one CPU per GPU. :ulb,l
The GPU package moves per-atom data (coordinates, forces)
back-and-forth between the CPU and GPU every timestep. The USER-CUDA
package only does this on timesteps when a CPU calculation is required
(e.g. to invoke a fix or compute that is non-GPU-ized). Hence, if you
can formulate your input script to only use GPU-ized fixes and
computes, and avoid doing I/O too often (thermo output, dump file
snapshots, restart files), then the data transfer cost of the
USER-CUDA package can be very low, causing it to run faster than the
GPU package. :l
The GPU package is often faster than the USER-CUDA package, if the
number of atoms per GPU is "small". The crossover point, in terms of
atoms/GPU at which the USER-CUDA package becomes faster depends
strongly on the pair style. For example, for a simple Lennard Jones
system the crossover (in single precision) is often about 50K-100K
atoms per GPU. When performing double precision calculations the
crossover point can be significantly smaller. :l
Both packages compute bonded interactions (bonds, angles, etc) on the
CPU. This means a model with bonds will force the USER-CUDA package
to transfer per-atom data back-and-forth between the CPU and GPU every
timestep. If the GPU package is running with several MPI processes
assigned to one GPU, the cost of computing the bonded interactions is
spread across more CPUs and hence the GPU package can run faster. :l
When using the GPU package with multiple CPUs assigned to one GPU, its
performance depends to some extent on high bandwidth between the CPUs
and the GPU. Hence its performance is affected if full 16 PCIe lanes
are not available for each GPU. In HPC environments this can be the
case if S2050/70 servers are used, where two devices generally share
one PCIe 2.0 16x slot. Also many multi-GPU mainboards do not provide
full 16 lanes to each of the PCIe 2.0 16x slots. :l,ule
[Differences between the two packages:]
The GPU package accelerates only pair force, neighbor list, and PPPM
calculations. The USER-CUDA package currently supports a wider range
of pair styles and can also accelerate many fix styles and some
compute styles, as well as neighbor list and PPPM calculations. :ulb,l
The GPU package uses more GPU memory than the USER-CUDA package. This
is generally not a problem since typical runs are computation-limited
rather than memory-limited. :l,ule
[Examples:]
The LAMMPS distribution has two directories with sample input scripts
for the GPU and USER-CUDA packages.
lammps/examples/gpu = GPU package files
lammps/examples/USER/cuda = USER-CUDA package files :ul
These contain input scripts for identical systems, so they can be used
to benchmark the performance of both packages on your system.
:line
[Benchmark data:]
NOTE: We plan to add some benchmark results and plots here for the
examples described in the previous section.
Simulations:
1. Lennard Jones
256,000 atoms
2.5 A cutoff
0.844 density :ul
2. Lennard Jones
256,000 atoms
5.0 A cutoff
0.844 density :ul
3. Rhodopsin model
256,000 atoms
10A cutoff
Coulomb via PPPM :ul
4. Lihtium-Phosphate
295650 atoms
15A cutoff
Coulomb via PPPM :ul
Hardware:
Workstation:
2x GTX470
i7 950@3GHz
24Gb DDR3 @ 1066Mhz
CentOS 5.5
CUDA 3.2
Driver 260.19.12 :ul
eStella:
6 Nodes
2xC2050
2xQDR Infiniband interconnect(aggregate bandwidth 80GBps)
Intel X5650 HexCore @ 2.67GHz
SL 5.5
CUDA 3.2
Driver 260.19.26 :ul
Keeneland:
HP SL-390 (Ariston) cluster
120 nodes
2x Intel Westmere hex-core CPUs
3xC2070s
QDR InfiniBand interconnect :ul
diff --git a/doc/Section_commands.html b/doc/Section_commands.html
index 6e1f356a9..964a194ea 100644
--- a/doc/Section_commands.html
+++ b/doc/Section_commands.html
@@ -1,594 +1,627 @@
<HTML>
<CENTER><A HREF = "Section_start.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_packages.html">Next Section</A>
</CENTER>
<HR>
<H3>3. Commands
</H3>
-<P>This section describes how a LAMMPS input script is formatted and what
-commands are used to define a LAMMPS simulation.
+<P>This section describes how a LAMMPS input script is formatted and the
+input script commands used to define a LAMMPS simulation.
</P>
3.1 <A HREF = "#cmd_1">LAMMPS input script</A><BR>
3.2 <A HREF = "#cmd_2">Parsing rules</A><BR>
3.3 <A HREF = "#cmd_3">Input script structure</A><BR>
3.4 <A HREF = "#cmd_4">Commands listed by category</A><BR>
3.5 <A HREF = "#cmd_5">Commands listed alphabetically</A> <BR>
<HR>
+<HR>
+
<A NAME = "cmd_1"></A><H4>3.1 LAMMPS input script
</H4>
<P>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.
</P>
<P>In many cases, the ordering of commands in an input script is not
important. However the following rules apply:
</P>
<P>(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:
</P>
<PRE>timestep 0.5
run 100
run 100
</PRE>
<P>does something different than this sequence:
</P>
<PRE>run 100
timestep 0.5
run 100
</PRE>
<P>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.
</P>
<P>(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.
</P>
<P>(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
<A HREF = "read_data.html">read_data</A> command initializes the system by setting
up the simulation box and assigning atoms to processors. If default
values are not desired, the <A HREF = "processors.html">processors</A> and
<A HREF = "boundary.html">boundary</A> commands need to be used before read_data to
tell LAMMPS how to map processors to the simulation box.
</P>
<P>Many input script errors are detected by LAMMPS and an ERROR or
WARNING message is printed. <A HREF = "Section_errors.html">This section</A> gives
more information on what errors mean. The documentation for each
command lists restrictions on how the command can be used.
</P>
<HR>
<A NAME = "cmd_2"></A><H4>3.2 Parsing rules
</H4>
<P>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.
</P>
<P>Here is how each line in the input script is parsed by LAMMPS:
</P>
<P>(1) If the last printable character on the line is a "&" character
(with no surrounding quotes), the command is assumed to continue on
the next line. The next line is concatenated to the previous line by
removing the "&" character and newline. This allows long commands to
be continued across two or more lines.
</P>
<P>(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.
</P>
<P>(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". See the <A HREF = "variable.html">variable</A> command for
details of how strings are assigned to variables and how they are
substituted for in input script commands.
</P>
<P>(4) The line is broken into "words" separated by whitespace (tabs,
spaces). Note that words can thus contain letters, digits,
underscores, or punctuation characters.
</P>
<P>(5) The first word is the command name. All successive words in the
line are arguments.
</P>
<P>(6) If you want text with spaces to be treated as a single argument,
it can be enclosed in either double or single quotes. E.g.
</P>
<PRE>print "Volume = $v"
print 'Volume = $v'
</PRE>
<P>The quotes are removed when the single argument is stored internally.
See the <A HREF = "dump_modify.html">dump modify format</A> or <A HREF = "if.html">if</A> commands
for examples. A "#" or "$" character that is between quotes will not
be treated as a comment indicator in (2) or substituted for as a
variable in (3).
</P>
<P>IMPORTANT NOTE: If the argument is itself a command that requires a
quoted argument (e.g. using a <A HREF = "print.html">print</A> command as part of an
<A HREF = "if.html">if</A> or <A HREF = "run.html">run every</A> command), then the double and
single quotes can be nested in the usual manner. See the doc pages
for those commands for examples. Only one of level of nesting is
allowed, but that should be sufficient for most use cases.
</P>
<HR>
<H4><A NAME = "cmd_3"></A>3.3 Input script structure
</H4>
<P>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
-<A HREF = "Section_example.html">this section</A>, and animated on the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
-Site</A>.
+<A HREF = "Section_example.html">Section_example</A>, and animated on the <A HREF = "http://lammps.sandia.gov">LAMMPS
+WWW Site</A>.
</P>
<P>A LAMMPS input script typically has 4 parts:
</P>
<OL><LI>Initialization
<LI>Atom definition
<LI>Settings
<LI>Run a simulation
</OL>
<P>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.
</P>
<P>(1) Initialization
</P>
<P>Set parameters that need to be defined before atoms are created or
read-in from a file.
</P>
<P>The relevant commands are <A HREF = "units.html">units</A>,
<A HREF = "dimension.html">dimension</A>, <A HREF = "newton.html">newton</A>,
<A HREF = "processors.html">processors</A>, <A HREF = "boundary.html">boundary</A>,
<A HREF = "atom_style.html">atom_style</A>, <A HREF = "atom_modify.html">atom_modify</A>.
</P>
<P>If force-field parameters appear in the files that will be read, these
commands tell LAMMPS what kinds of force fields are being used:
<A HREF = "pair_style.html">pair_style</A>, <A HREF = "bond_style.html">bond_style</A>,
<A HREF = "angle_style.html">angle_style</A>, <A HREF = "dihedral_style.html">dihedral_style</A>,
<A HREF = "improper_style.html">improper_style</A>.
</P>
<P>(2) Atom definition
</P>
<P>There are 3 ways to define atoms in LAMMPS. Read them in from a data
or restart file via the <A HREF = "read_data.html">read_data</A> or
<A HREF = "read_restart.html">read_restart</A> commands. These files can contain
molecular topology information. Or create atoms on a lattice (with no
molecular topology), using these commands: <A HREF = "lattice.html">lattice</A>,
<A HREF = "region.html">region</A>, <A HREF = "create_box.html">create_box</A>,
<A HREF = "create_atoms.html">create_atoms</A>. The entire set of atoms can be
duplicated to make a larger simulation using the
<A HREF = "replicate.html">replicate</A> command.
</P>
<P>(3) Settings
</P>
<P>Once atoms and molecular topology are defined, a variety of settings
can be specified: force field coefficients, simulation parameters,
output options, etc.
</P>
<P>Force field coefficients are set by these commands (they can also be
set in the read-in files): <A HREF = "pair_coeff.html">pair_coeff</A>,
<A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "angle_coeff.html">angle_coeff</A>,
<A HREF = "dihedral_coeff.html">dihedral_coeff</A>,
<A HREF = "improper_coeff.html">improper_coeff</A>,
<A HREF = "kspace_style.html">kspace_style</A>, <A HREF = "dielectric.html">dielectric</A>,
<A HREF = "special_bonds.html">special_bonds</A>.
</P>
<P>Various simulation parameters are set by these commands:
<A HREF = "neighbor.html">neighbor</A>, <A HREF = "neigh_modify.html">neigh_modify</A>,
<A HREF = "group.html">group</A>, <A HREF = "timestep.html">timestep</A>,
<A HREF = "reset_timestep.html">reset_timestep</A>, <A HREF = "run_style.html">run_style</A>,
<A HREF = "min_style.html">min_style</A>, <A HREF = "min_modify.html">min_modify</A>.
</P>
<P>Fixes impose a variety of boundary conditions, time integration, and
diagnostic options. The <A HREF = "fix.html">fix</A> command comes in many flavors.
</P>
<P>Various computations can be specified for execution during a
simulation using the <A HREF = "compute.html">compute</A>,
<A HREF = "compute_modify.html">compute_modify</A>, and <A HREF = "variable.html">variable</A>
commands.
</P>
<P>Output options are set by the <A HREF = "thermo.html">thermo</A>, <A HREF = "dump.html">dump</A>,
and <A HREF = "restart.html">restart</A> commands.
</P>
<P>(4) Run a simulation
</P>
<P>A molecular dynamics simulation is run using the <A HREF = "run.html">run</A>
command. Energy minimization (molecular statics) is performed using
the <A HREF = "minimize.html">minimize</A> command. A parallel tempering
(replica-exchange) simulation can be run using the
<A HREF = "temper.html">temper</A> command.
</P>
<HR>
<A NAME = "cmd_4"></A><H4>3.4 Commands listed by category
</H4>
<P>This section lists all LAMMPS commands, grouped by category. The
<A HREF = "#cmd_5">next section</A> lists the same commands alphabetically. Note
that some style options for some commands are part of specific LAMMPS
packages, which means they cannot be used unless the package was
included when LAMMPS was built. Not all packages are included in a
default LAMMPS build. These dependencies are listed as Restrictions
in the command's documentation.
</P>
<P>Initialization:
</P>
<P><A HREF = "atom_modify.html">atom_modify</A>, <A HREF = "atom_style.html">atom_style</A>,
<A HREF = "boundary.html">boundary</A>, <A HREF = "dimension.html">dimension</A>,
<A HREF = "newton.html">newton</A>, <A HREF = "processors.html">processors</A>, <A HREF = "units.html">units</A>
</P>
<P>Atom definition:
</P>
<P><A HREF = "create_atoms.html">create_atoms</A>, <A HREF = "create_box.html">create_box</A>,
<A HREF = "lattice.html">lattice</A>, <A HREF = "read_data.html">read_data</A>,
<A HREF = "read_restart.html">read_restart</A>, <A HREF = "region.html">region</A>,
<A HREF = "replicate.html">replicate</A>
</P>
<P>Force fields:
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>, <A HREF = "angle_style.html">angle_style</A>,
<A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "bond_style.html">bond_style</A>,
<A HREF = "dielectric.html">dielectric</A>, <A HREF = "dihedral_coeff.html">dihedral_coeff</A>,
<A HREF = "dihedral_style.html">dihedral_style</A>,
<A HREF = "improper_coeff.html">improper_coeff</A>,
<A HREF = "improper_style.html">improper_style</A>,
<A HREF = "kspace_modify.html">kspace_modify</A>, <A HREF = "kspace_style.html">kspace_style</A>,
<A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_modify.html">pair_modify</A>,
<A HREF = "pair_style.html">pair_style</A>, <A HREF = "pair_write.html">pair_write</A>,
<A HREF = "special_bonds.html">special_bonds</A>
</P>
<P>Settings:
</P>
<P><A HREF = "communicate.html">communicate</A>, <A HREF = "group.html">group</A>, <A HREF = "mass.html">mass</A>,
<A HREF = "min_modify.html">min_modify</A>, <A HREF = "min_style.html">min_style</A>,
<A HREF = "neigh_modify.html">neigh_modify</A>, <A HREF = "neighbor.html">neighbor</A>,
<A HREF = "reset_timestep.html">reset_timestep</A>, <A HREF = "run_style.html">run_style</A>,
<A HREF = "set.html">set</A>, <A HREF = "timestep.html">timestep</A>, <A HREF = "velocity.html">velocity</A>
</P>
<P>Fixes:
</P>
<P><A HREF = "fix.html">fix</A>, <A HREF = "fix_modify.html">fix_modify</A>, <A HREF = "unfix.html">unfix</A>
</P>
<P>Computes:
</P>
<P><A HREF = "compute.html">compute</A>, <A HREF = "compute_modify.html">compute_modify</A>,
<A HREF = "uncompute.html">uncompute</A>
</P>
<P>Output:
</P>
<P><A HREF = "dump.html">dump</A>, <A HREF = "dump_image.html">dump image</A>,
<A HREF = "dump_modify.html">dump_modify</A>, <A HREF = "restart.html">restart</A>,
<A HREF = "thermo.html">thermo</A>, <A HREF = "thermo_modify.html">thermo_modify</A>,
<A HREF = "thermo_style.html">thermo_style</A>, <A HREF = "undump.html">undump</A>,
<A HREF = "write_restart.html">write_restart</A>
</P>
<P>Actions:
</P>
<P><A HREF = "delete_atoms.html">delete_atoms</A>, <A HREF = "delete_bonds.html">delete_bonds</A>,
<A HREF = "displace_atoms.html">displace_atoms</A>,
<A HREF = "displace_box.html">displace_box</A>, <A HREF = "minimize.html">minimize</A>,
<A HREF = "neb.html">neb</A> <A HREF = "prd.html">prd</A>, <A HREF = "run.html">run</A>, <A HREF = "temper.html">temper</A>
</P>
<P>Miscellaneous:
</P>
<P><A HREF = "clear.html">clear</A>, <A HREF = "echo.html">echo</A>, <A HREF = "if.html">if</A>,
<A HREF = "include.html">include</A>, <A HREF = "jump.html">jump</A>, <A HREF = "label.html">label</A>,
<A HREF = "log.html">log</A>, <A HREF = "next.html">next</A>, <A HREF = "print.html">print</A>,
<A HREF = "shell.html">shell</A>, <A HREF = "variable.html">variable</A>
</P>
<HR>
<H4><A NAME = "cmd_5"></A><A NAME = "comm"></A>3.5 Individual commands
</H4>
<P>This section lists all LAMMPS commands alphabetically, with a separate
listing below of styles within certain commands. The <A HREF = "#cmd_4">previous
section</A> 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.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "angle_coeff.html">angle_coeff</A></TD><TD ><A HREF = "angle_style.html">angle_style</A></TD><TD ><A HREF = "atom_modify.html">atom_modify</A></TD><TD ><A HREF = "atom_style.html">atom_style</A></TD><TD ><A HREF = "bond_coeff.html">bond_coeff</A></TD><TD ><A HREF = "bond_style.html">bond_style</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "boundary.html">boundary</A></TD><TD ><A HREF = "change_box.html">change_box</A></TD><TD ><A HREF = "clear.html">clear</A></TD><TD ><A HREF = "communicate.html">communicate</A></TD><TD ><A HREF = "compute.html">compute</A></TD><TD ><A HREF = "compute_modify.html">compute_modify</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "create_atoms.html">create_atoms</A></TD><TD ><A HREF = "create_box.html">create_box</A></TD><TD ><A HREF = "delete_atoms.html">delete_atoms</A></TD><TD ><A HREF = "delete_bonds.html">delete_bonds</A></TD><TD ><A HREF = "dielectric.html">dielectric</A></TD><TD ><A HREF = "dihedral_coeff.html">dihedral_coeff</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "dihedral_style.html">dihedral_style</A></TD><TD ><A HREF = "dimension.html">dimension</A></TD><TD ><A HREF = "displace_atoms.html">displace_atoms</A></TD><TD ><A HREF = "displace_box.html">displace_box</A></TD><TD ><A HREF = "dump.html">dump</A></TD><TD ><A HREF = "dump_image.html">dump image</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "dump_modify.html">dump_modify</A></TD><TD ><A HREF = "echo.html">echo</A></TD><TD ><A HREF = "fix.html">fix</A></TD><TD ><A HREF = "fix_modify.html">fix_modify</A></TD><TD ><A HREF = "group.html">group</A></TD><TD ><A HREF = "if.html">if</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "improper_coeff.html">improper_coeff</A></TD><TD ><A HREF = "improper_style.html">improper_style</A></TD><TD ><A HREF = "include.html">include</A></TD><TD ><A HREF = "jump.html">jump</A></TD><TD ><A HREF = "kspace_modify.html">kspace_modify</A></TD><TD ><A HREF = "kspace_style.html">kspace_style</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "label.html">label</A></TD><TD ><A HREF = "lattice.html">lattice</A></TD><TD ><A HREF = "log.html">log</A></TD><TD ><A HREF = "mass.html">mass</A></TD><TD ><A HREF = "minimize.html">minimize</A></TD><TD ><A HREF = "min_modify.html">min_modify</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "min_style.html">min_style</A></TD><TD ><A HREF = "neb.html">neb</A></TD><TD ><A HREF = "neigh_modify.html">neigh_modify</A></TD><TD ><A HREF = "neighbor.html">neighbor</A></TD><TD ><A HREF = "newton.html">newton</A></TD><TD ><A HREF = "next.html">next</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "package.html">package</A></TD><TD ><A HREF = "pair_coeff.html">pair_coeff</A></TD><TD ><A HREF = "pair_modify.html">pair_modify</A></TD><TD ><A HREF = "pair_style.html">pair_style</A></TD><TD ><A HREF = "pair_write.html">pair_write</A></TD><TD ><A HREF = "prd.html">prd</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "print.html">print</A></TD><TD ><A HREF = "processors.html">processors</A></TD><TD ><A HREF = "read_data.html">read_data</A></TD><TD ><A HREF = "read_restart.html">read_restart</A></TD><TD ><A HREF = "region.html">region</A></TD><TD ><A HREF = "replicate.html">replicate</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD><TD ><A HREF = "restart.html">restart</A></TD><TD ><A HREF = "run.html">run</A></TD><TD ><A HREF = "run_style.html">run_style</A></TD><TD ><A HREF = "set.html">set</A></TD><TD ><A HREF = "shell.html">shell</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "special_bonds.html">special_bonds</A></TD><TD ><A HREF = "suffix.html">suffix</A></TD><TD ><A HREF = "tad.html">tad</A></TD><TD ><A HREF = "temper.html">temper</A></TD><TD ><A HREF = "thermo.html">thermo</A></TD><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "thermo_style.html">thermo_style</A></TD><TD ><A HREF = "timestep.html">timestep</A></TD><TD ><A HREF = "uncompute.html">uncompute</A></TD><TD ><A HREF = "undump.html">undump</A></TD><TD ><A HREF = "unfix.html">unfix</A></TD><TD ><A HREF = "units.html">units</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "variable.html">variable</A></TD><TD ><A HREF = "velocity.html">velocity</A></TD><TD ><A HREF = "write_restart.html">write_restart</A>
+<TR ALIGN="center"><TD ><A HREF = "package.html">package</A></TD><TD ><A HREF = "pair_coeff.html">pair_coeff</A></TD><TD ><A HREF = "pair_modify.html">pair_modify</A></TD><TD ><A HREF = "pair_style.html">pair_style</A></TD><TD ><A HREF = "pair_write.html">pair_write</A></TD><TD ><A HREF = "partition.html">partition</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "prd.html">prd</A></TD><TD ><A HREF = "print.html">print</A></TD><TD ><A HREF = "processors.html">processors</A></TD><TD ><A HREF = "read_data.html">read_data</A></TD><TD ><A HREF = "read_restart.html">read_restart</A></TD><TD ><A HREF = "region.html">region</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "replicate.html">replicate</A></TD><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD><TD ><A HREF = "restart.html">restart</A></TD><TD ><A HREF = "run.html">run</A></TD><TD ><A HREF = "run_style.html">run_style</A></TD><TD ><A HREF = "set.html">set</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "shell.html">shell</A></TD><TD ><A HREF = "special_bonds.html">special_bonds</A></TD><TD ><A HREF = "suffix.html">suffix</A></TD><TD ><A HREF = "tad.html">tad</A></TD><TD ><A HREF = "temper.html">temper</A></TD><TD ><A HREF = "thermo.html">thermo</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD><TD ><A HREF = "thermo_style.html">thermo_style</A></TD><TD ><A HREF = "timestep.html">timestep</A></TD><TD ><A HREF = "uncompute.html">uncompute</A></TD><TD ><A HREF = "undump.html">undump</A></TD><TD ><A HREF = "unfix.html">unfix</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "units.html">units</A></TD><TD ><A HREF = "variable.html">variable</A></TD><TD ><A HREF = "velocity.html">velocity</A></TD><TD ><A HREF = "write_restart.html">write_restart</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Fix styles
</H4>
<P>See the <A HREF = "fix.html">fix</A> command for one-line descriptions
of each style or click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "fix_adapt.html">adapt</A></TD><TD ><A HREF = "fix_addforce.html">addforce</A></TD><TD ><A HREF = "fix_aveforce.html">aveforce</A></TD><TD ><A HREF = "fix_ave_atom.html">ave/atom</A></TD><TD ><A HREF = "fix_ave_correlate.html">ave/correlate</A></TD><TD ><A HREF = "fix_ave_histo.html">ave/histo</A></TD><TD ><A HREF = "fix_ave_spatial.html">ave/spatial</A></TD><TD ><A HREF = "fix_ave_time.html">ave/time</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_bond_break.html">bond/break</A></TD><TD ><A HREF = "fix_bond_create.html">bond/create</A></TD><TD ><A HREF = "fix_bond_swap.html">bond/swap</A></TD><TD ><A HREF = "fix_box_relax.html">box/relax</A></TD><TD ><A HREF = "fix_deform.html">deform</A></TD><TD ><A HREF = "fix_deposit.html">deposit</A></TD><TD ><A HREF = "fix_drag.html">drag</A></TD><TD ><A HREF = "fix_dt_reset.html">dt/reset</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_efield.html">efield</A></TD><TD ><A HREF = "fix_enforce2d.html">enforce2d</A></TD><TD ><A HREF = "fix_evaporate.html">evaporate</A></TD><TD ><A HREF = "fix_external.html">external</A></TD><TD ><A HREF = "fix_freeze.html">freeze</A></TD><TD ><A HREF = "fix_gcmc.html">gcmc</A></TD><TD ><A HREF = "fix_gravity.html">gravity</A></TD><TD ><A HREF = "fix_heat.html">heat</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_indent.html">indent</A></TD><TD ><A HREF = "fix_langevin.html">langevin</A></TD><TD ><A HREF = "fix_lineforce.html">lineforce</A></TD><TD ><A HREF = "fix_momentum.html">momentum</A></TD><TD ><A HREF = "fix_move.html">move</A></TD><TD ><A HREF = "fix_msst.html">msst</A></TD><TD ><A HREF = "fix_neb.html">neb</A></TD><TD ><A HREF = "fix_nh.html">nph</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nphug.html">nphug</A></TD><TD ><A HREF = "fix_nph_asphere.html">nph/asphere</A></TD><TD ><A HREF = "fix_nph_sphere.html">nph/sphere</A></TD><TD ><A HREF = "fix_nh.html">npt</A></TD><TD ><A HREF = "fix_npt_asphere.html">npt/asphere</A></TD><TD ><A HREF = "fix_npt_sphere.html">npt/sphere</A></TD><TD ><A HREF = "fix_nve.html">nve</A></TD><TD ><A HREF = "fix_nve_asphere.html">nve/asphere</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nve_asphere_noforce.html">nve/asphere/noforce</A></TD><TD ><A HREF = "fix_nve_limit.html">nve/limit</A></TD><TD ><A HREF = "fix_nve_line.html">nve/line</A></TD><TD ><A HREF = "fix_nve_noforce.html">nve/noforce</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere</A></TD><TD ><A HREF = "fix_nve_tri.html">nve/tri</A></TD><TD ><A HREF = "fix_nh.html">nvt</A></TD><TD ><A HREF = "fix_nvt_asphere.html">nvt/asphere</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nvt_sllod.html">nvt/sllod</A></TD><TD ><A HREF = "fix_nvt_sphere.html">nvt/sphere</A></TD><TD ><A HREF = "fix_orient_fcc.html">orient/fcc</A></TD><TD ><A HREF = "fix_planeforce.html">planeforce</A></TD><TD ><A HREF = "fix_poems.html">poems</A></TD><TD ><A HREF = "fix_pour.html">pour</A></TD><TD ><A HREF = "fix_press_berendsen.html">press/berendsen</A></TD><TD ><A HREF = "fix_print.html">print</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_qeq_comb.html">qeq/comb</A></TD><TD ><A HREF = "fix_reax_bonds.html">reax/bonds</A></TD><TD ><A HREF = "fix_recenter.html">recenter</A></TD><TD ><A HREF = "fix_restrain.html">restrain</A></TD><TD ><A HREF = "fix_rigid.html">rigid</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nve</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nvt</A></TD><TD ><A HREF = "fix_setforce.html">setforce</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_shake.html">shake</A></TD><TD ><A HREF = "fix_spring.html">spring</A></TD><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD><TD ><A HREF = "fix_srd.html">srd</A></TD><TD ><A HREF = "fix_store_force.html">store/force</A></TD><TD ><A HREF = "fix_store_state.html">store/state</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_temp_rescale.html">temp/rescale</A></TD><TD ><A HREF = "fix_thermal_conductivity.html">thermal/conductivity</A></TD><TD ><A HREF = "fix_tmd.html">tmd</A></TD><TD ><A HREF = "fix_ttm.html">ttm</A></TD><TD ><A HREF = "fix_viscosity.html">viscosity</A></TD><TD ><A HREF = "fix_viscous.html">viscous</A></TD><TD ><A HREF = "fix_wall.html">wall/colloid</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_wall.html">wall/harmonic</A></TD><TD ><A HREF = "fix_wall.html">wall/lj126</A></TD><TD ><A HREF = "fix_wall.html">wall/lj93</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD><TD ><A HREF = "fix_wall_srd.html">wall/srd</A>
</TD></TR></TABLE></DIV>
<P>These are fix styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "fix_addtorque.html">addtorque</A></TD><TD ><A HREF = "fix_atc.html">atc</A></TD><TD ><A HREF = "fix_imd.html">imd</A></TD><TD ><A HREF = "fix_langevin_eff.html">langevin/eff</A></TD><TD ><A HREF = "fix_meso.html">meso</A></TD><TD ><A HREF = "fix_meso_stationary.html">meso/stationary</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nh_eff.html">nph/eff</A></TD><TD ><A HREF = "fix_nh_eff.html">npt/eff</A></TD><TD ><A HREF = "fix_nve_eff.html">nve/eff</A></TD><TD ><A HREF = "fix_nh_eff.html">nvt/eff</A></TD><TD ><A HREF = "fix_nvt_sllod_eff.html">nvt/sllod/eff</A></TD><TD ><A HREF = "fix_qeq_reax.html">qeq/reax</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_smd.html">smd</A></TD><TD ><A HREF = "fix_temp_rescale_eff.html">temp/rescale/eff</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated fix styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "fix_freeze.html">freeze/cuda</A></TD><TD ><A HREF = "fix_addforce.html">addforce/cuda</A></TD><TD ><A HREF = "fix_aveforce.html">aveforce/cuda</A></TD><TD ><A HREF = "fix_enforce2d.html">enforce2d/cuda</A></TD><TD ><A HREF = "fix_gravity.html">gravity/cuda</A></TD><TD ><A HREF = "fix_gravity.html">gravity/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nh.html">npt/cuda</A></TD><TD ><A HREF = "fix_nh.html">nve/cuda</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere/omp</A></TD><TD ><A HREF = "fix_nh.html">nvt/cuda</A></TD><TD ><A HREF = "fix_qeq_comb.html">qeq/comb/omp</A></TD><TD ><A HREF = "fix_setforce.html">setforce/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_shake.html">shake/cuda</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen/cuda</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale/cuda</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale/limit/cuda</A></TD><TD ><A HREF = "fix_viscous.html">viscous/cuda</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Compute styles
</H4>
<P>See the <A HREF = "compute.html">compute</A> command for one-line descriptions of
each style or click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "compute_angle_local.html">angle/local</A></TD><TD ><A HREF = "compute_atom_molecule.html">atom/molecule</A></TD><TD ><A HREF = "compute_bond_local.html">bond/local</A></TD><TD ><A HREF = "compute_centro_atom.html">centro/atom</A></TD><TD ><A HREF = "compute_cluster_atom.html">cluster/atom</A></TD><TD ><A HREF = "compute_cna_atom.html">cna/atom</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_com.html">com</A></TD><TD ><A HREF = "compute_com_molecule.html">com/molecule</A></TD><TD ><A HREF = "compute_coord_atom.html">coord/atom</A></TD><TD ><A HREF = "compute_damage_atom.html">damage/atom</A></TD><TD ><A HREF = "compute_dihedral_local.html">dihedral/local</A></TD><TD ><A HREF = "compute_displace_atom.html">displace/atom</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_erotate_asphere.html">erotate/asphere</A></TD><TD ><A HREF = "compute_erotate_sphere.html">erotate/sphere</A></TD><TD ><A HREF = "compute_event_displace.html">event/displace</A></TD><TD ><A HREF = "compute_group_group.html">group/group</A></TD><TD ><A HREF = "compute_gyration.html">gyration</A></TD><TD ><A HREF = "compute_gyration_molecule.html">gyration/molecule</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_heat_flux.html">heat/flux</A></TD><TD ><A HREF = "compute_improper_local.html">improper/local</A></TD><TD ><A HREF = "compute_ke.html">ke</A></TD><TD ><A HREF = "compute_ke_atom.html">ke/atom</A></TD><TD ><A HREF = "compute_msd.html">msd</A></TD><TD ><A HREF = "compute_msd_molecule.html">msd/molecule</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_pair.html">pair</A></TD><TD ><A HREF = "compute_pair_local.html">pair/local</A></TD><TD ><A HREF = "compute_pe.html">pe</A></TD><TD ><A HREF = "compute_pe_atom.html">pe/atom</A></TD><TD ><A HREF = "compute_pressure.html">pressure</A></TD><TD ><A HREF = "compute_property_atom.html">property/atom</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_property_local.html">property/local</A></TD><TD ><A HREF = "compute_property_molecule.html">property/molecule</A></TD><TD ><A HREF = "compute_rdf.html">rdf</A></TD><TD ><A HREF = "compute_reduce.html">reduce</A></TD><TD ><A HREF = "compute_reduce.html">reduce/region</A></TD><TD ><A HREF = "compute_slice.html">slice</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_stress_atom.html">stress/atom</A></TD><TD ><A HREF = "compute_temp.html">temp</A></TD><TD ><A HREF = "compute_temp_asphere.html">temp/asphere</A></TD><TD ><A HREF = "compute_temp_com.html">temp/com</A></TD><TD ><A HREF = "compute_temp_deform.html">temp/deform</A></TD><TD ><A HREF = "compute_temp_partial.html">temp/partial</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_temp_profile.html">temp/profile</A></TD><TD ><A HREF = "compute_temp_ramp.html">temp/ramp</A></TD><TD ><A HREF = "compute_temp_region.html">temp/region</A></TD><TD ><A HREF = "compute_temp_sphere.html">temp/sphere</A></TD><TD ><A HREF = "compute_ti.html">ti</A>
</TD></TR></TABLE></DIV>
<P>These are compute styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "compute_ackland_atom.html">ackland/atom</A></TD><TD ><A HREF = "compute_ke_eff.html">ke/eff</A></TD><TD ><A HREF = "compute_ke_atom_eff.html">ke/atom/eff</A></TD><TD ><A HREF = "compute_meso_e_atom.html">meso_e/atom</A></TD><TD ><A HREF = "compute_meso_rho_atom.html">meso_rho/atom</A></TD><TD ><A HREF = "compute_meso_t_atom.html">meso_t/atom</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_temp_eff.html">temp/eff</A></TD><TD ><A HREF = "compute_temp_deform_eff.html">temp/deform/eff</A></TD><TD ><A HREF = "compute_temp_region_eff.html">temp/region/eff</A></TD><TD ><A HREF = "compute_temp_rotate.html">temp/rotate</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated compute styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "compute_pe.html">pe/cuda</A></TD><TD ><A HREF = "compute_pressure.html">pressure/cuda</A></TD><TD ><A HREF = "compute_temp.html">temp/cuda</A></TD><TD ><A HREF = "compute_temp_partial.html">temp/partial/cuda</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Pair_style potentials
</H4>
<P>See the <A HREF = "pair_style.html">pair_style</A> command for an overview of pair
potentials. Click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "pair_none.html">none</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid/overlay</A></TD><TD ><A HREF = "pair_adp.html">adp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">airebo</A></TD><TD ><A HREF = "pair_born.html">born</A></TD><TD ><A HREF = "pair_born.html">born/coul/long</A></TD><TD ><A HREF = "pair_brownian.html">brownian</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_brownian.html">brownian/poly</A></TD><TD ><A HREF = "pair_buck.html">buck</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_colloid.html">colloid</A></TD><TD ><A HREF = "pair_comb.html">comb</A></TD><TD ><A HREF = "pair_coul.html">coul/cut</A></TD><TD ><A HREF = "pair_coul.html">coul/debye</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/long</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut</A></TD><TD ><A HREF = "pair_dpd.html">dpd</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD><TD ><A HREF = "pair_eam.html">eam</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy</A></TD><TD ><A HREF = "pair_eam.html">eam/fs</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eim.html">eim</A></TD><TD ><A HREF = "pair_gauss.html">gauss</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hooke</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_line_lj.html">line/lj</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj_expand.html">lj/expand</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj96.html">lj96/cut</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/poly</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><TD ><A HREF = "pair_meam.html">meam</A></TD><TD ><A HREF = "pair_morse.html">morse</A></TD><TD ><A HREF = "pair_peri.html">peri/lps</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD><TD ><A HREF = "pair_airebo.html">rebo</A></TD><TD ><A HREF = "pair_resquared.html">resquared</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_soft.html">soft</A></TD><TD ><A HREF = "pair_sw.html">sw</A></TD><TD ><A HREF = "pair_table.html">table</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj</A></TD><TD ><A HREF = "pair_yukawa.html">yukawa</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid</A>
+<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">airebo</A></TD><TD ><A HREF = "pair_born.html">born</A></TD><TD ><A HREF = "pair_born.html">born/coul/long</A></TD><TD ><A HREF = "pair_born.html">born/coul/wolf</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_brownian.html">brownian</A></TD><TD ><A HREF = "pair_brownian.html">brownian/poly</A></TD><TD ><A HREF = "pair_buck.html">buck</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/long</A></TD><TD ><A HREF = "pair_colloid.html">colloid</A></TD><TD ><A HREF = "pair_comb.html">comb</A></TD><TD ><A HREF = "pair_coul.html">coul/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/debye</A></TD><TD ><A HREF = "pair_coul.html">coul/long</A></TD><TD ><A HREF = "pair_coul.html">coul/wolf</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_dpd.html">dpd</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat</A></TD><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD><TD ><A HREF = "pair_eam.html">eam</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/alloy</A></TD><TD ><A HREF = "pair_eam.html">eam/fs</A></TD><TD ><A HREF = "pair_eim.html">eim</A></TD><TD ><A HREF = "pair_gauss.html">gauss</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gayberne.html">gayberne</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long</A></TD><TD ><A HREF = "pair_class2.html">lj/class2</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lubricate.html">lubricate/poly</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><TD ><A HREF = "pair_meam.html">meam</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse</A></TD><TD ><A HREF = "pair_peri.html">peri/lps</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">rebo</A></TD><TD ><A HREF = "pair_resquared.html">resquared</A></TD><TD ><A HREF = "pair_soft.html">soft</A></TD><TD ><A HREF = "pair_sw.html">sw</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_table.html">table</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_yukawa.html">yukawa</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid</A>
</TD></TR></TABLE></DIV>
<P>These are pair styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
-<TR ALIGN="center"><TD ><A HREF = "pair_awpmd.html">awpmd/cut</A></TD><TD ><A HREF = "pair_buck_coul.html">buck/coul</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/cut</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/long</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf</A></TD><TD ><A HREF = "pair_eam.html">eam/cd</A></TD><TD ><A HREF = "pair_edip.html">edip</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eff.html">eff/cut</A></TD><TD ><A HREF = "pair_lj_coul.html">lj/coul</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf</A></TD><TD ><A HREF = "pair_reax_c.html">reax/c</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_heatconduction.html">sph/heatconduction</A></TD><TD ><A HREF = "pair_idealgas.html">sph/idealgas</A></TD><TD ><A HREF = "pair_lj.html">sph/lj</A></TD><TD ><A HREF = "pair_rhosum.html">sph/rhosum</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_taitwater.html">sph/taitwater</A></TD><TD ><A HREF = "pair_taitwater_morris.html">sph/taitwater/morris</A>
+<TR ALIGN="center"><TD ><A HREF = "pair_awpmd.html">awpmd/cut</A></TD><TD ><A HREF = "pair_buck_coul.html">buck/coul</A></TD><TD ><A HREF = "pair_coul_diel.html">coul/diel</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf</A></TD><TD ><A HREF = "pair_eam.html">eam/cd</A></TD><TD ><A HREF = "pair_edip.html">edip</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_eff.html">eff/cut</A></TD><TD ><A HREF = "pair_gauss.html">gauss/cut</A></TD><TD ><A HREF = "pair_lj_coul.html">lj/coul</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_reax_c.html">reax/c</A></TD><TD ><A HREF = "pair_heatconduction.html">sph/heatconduction</A></TD><TD ><A HREF = "pair_idealgas.html">sph/idealgas</A></TD><TD ><A HREF = "pair_lj.html">sph/lj</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_rhosum.html">sph/rhosum</A></TD><TD ><A HREF = "pair_taitwater.html">sph/taitwater</A></TD><TD ><A HREF = "pair_taitwater_morris.html">sph/taitwater/morris</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/table</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated pair styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "pair_adp.html">adp/omp</A></TD><TD ><A HREF = "pair_airebo.html">airebo/omp</A></TD><TD ><A HREF = "pair_born.html">born/coul/long/cuda</A></TD><TD ><A HREF = "pair_born.html">born/coul/long/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born/omp</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut/cuda</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut/omp</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/long/omp</A></TD><TD ><A HREF = "pair_buck_coul.html">buck/coul/omp</A></TD><TD ><A HREF = "pair_buck.html">buck/cuda</A></TD><TD ><A HREF = "pair_buck.html">buck/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/cut/cuda</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/debye/cuda</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/long/cuda</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/long/gpu</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_cmm.html">cg/cmm/cuda</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/gpu</A></TD><TD ><A HREF = "pair_colloid.html">colloid/omp</A></TD><TD ><A HREF = "pair_comb.html">comb/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/cut/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/debye/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/long/gpu</A></TD><TD ><A HREF = "pair_coul.html">coul/long/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_dipole.html">dipole/cut/omp</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf/omp</A></TD><TD ><A HREF = "pair_dpd.html">dpd/omp</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/alloy/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/opt</A></TD><TD ><A HREF = "pair_eam.html">eam/cd/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/opt</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/opt</A></TD><TD ><A HREF = "pair_edip.html">edip/omp</A></TD><TD ><A HREF = "pair_eim.html">eim/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gauss.html">gauss/omp</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/gpu</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hooke/cuda</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/omp</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/cuda</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/gpu</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/opt</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/cuda</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_sdk.html">lj/sdk/gpu</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/omp</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long/gpu</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_colloid.html">colloid/omp</A></TD><TD ><A HREF = "pair_comb.html">comb/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/cut/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/debye/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/long/gpu</A></TD><TD ><A HREF = "pair_coul.html">coul/long/omp</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut/omp</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_dpd.html">dpd/omp</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/alloy/opt</A></TD><TD ><A HREF = "pair_eam.html">eam/cd/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/cuda</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/fs/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/opt</A></TD><TD ><A HREF = "pair_eam.html">eam/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/opt</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_edip.html">edip/omp</A></TD><TD ><A HREF = "pair_eim.html">eim/omp</A></TD><TD ><A HREF = "pair_gauss.html">gauss/omp</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/gpu</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gayberne.html">gayberne/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/cuda</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hooke/omp</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj/omp</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse/omp</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/gpu</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/opt</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/pppm/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/gpu</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/omp</A></TD><TD ><A HREF = "pair_lj_coul.html">lj/coul/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/experimental/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/gpu</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/opt</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/cuda</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/gpu</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj_expand.html">lj/expand/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/cuda</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/cuda</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs/omp</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf/omp</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/cuda</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lj96.html">lj96/cut/cuda</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/gpu</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/omp</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse/cuda</A></TD><TD ><A HREF = "pair_morse.html">morse/gpu</A></TD><TD ><A HREF = "pair_morse.html">morse/omp</A></TD><TD ><A HREF = "pair_morse.html">morse/opt</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/lps/omp</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb/omp</A></TD><TD ><A HREF = "pair_airebo.html">rebo/omp</A></TD><TD ><A HREF = "pair_resquared.html">resquared/gpu</A> <A HREF = "pair_resquared.html">resquared/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_soft.html">soft/omp</A></TD><TD ><A HREF = "pair_sw.html">sw/cuda</A></TD><TD ><A HREF = "pair_sw.html">sw/omp</A></TD><TD ><A HREF = "pair_table.html">table/omp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_tersoff.html">tersoff/cuda</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/omp</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl/omp</A></TD><TD ><A HREF = "pair_yukawa.html">yukawa/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/pppm/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/pppm/tip4p/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/cuda</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/experimental/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/opt</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj_expand.html">lj/expand/cuda</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/gpu</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/cuda</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/cuda</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/omp</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/cuda</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/omp</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/cuda</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/gpu</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj96.html">lj96/cut/omp</A></TD><TD ><A HREF = "pair_morse.html">morse/cuda</A></TD><TD ><A HREF = "pair_morse.html">morse/gpu</A></TD><TD ><A HREF = "pair_morse.html">morse/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse/opt</A></TD><TD ><A HREF = "pair_peri.html">peri/lps/omp</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb/omp</A></TD><TD ><A HREF = "pair_airebo.html">rebo/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_resquared.html">resquared/gpu</A></TD><TD ><A HREF = "pair_resquared.html">resquared/omp</A></TD><TD ><A HREF = "pair_soft.html">soft/omp</A></TD><TD ><A HREF = "pair_sw.html">sw/cuda</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_sw.html">sw/omp</A></TD><TD ><A HREF = "pair_table.html">table/omp</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/cuda</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_tersoff.html">tersoff/table/omp</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl/omp</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj/omp</A></TD><TD ><A HREF = "pair_yukawa.html">yukawa/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid/omp</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Bond_style potentials
</H4>
<P>See the <A HREF = "bond_style.html">bond_style</A> command for an overview of bond
potentials. Click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_none.html">none</A></TD><TD WIDTH="100"><A HREF = "bond_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "bond_class2.html">class2</A></TD><TD WIDTH="100"><A HREF = "bond_fene.html">fene</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_fene_expand.html">fene/expand</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "bond_morse.html">morse</A></TD><TD WIDTH="100"><A HREF = "bond_nonlinear.html">nonlinear</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_quartic.html">quartic</A></TD><TD WIDTH="100"><A HREF = "bond_table.html">table</A>
</TD></TR></TABLE></DIV>
<P>These are bond styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "bond_harmonic_shift.html">harmonic/shift</A></TD><TD ><A HREF = "bond_harmonic_shift_cut.html">harmonic/shift/cut</A>
</TD></TR></TABLE></DIV>
+<P>These are accelerated bond styles, which can be used if LAMMPS is
+built with the <A HREF = "Section_accelerate.html">appropriate accelerated
+package</A>.
+</P>
+<DIV ALIGN=center><TABLE BORDER=1 >
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "bond_fene.html">fene/omp</A></TD><TD WIDTH="100"><A HREF = "bond_fene_expand.html">fene/expand/omp</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic.html">harmonic/omp</A></TD></TR>
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_harmonic_shift.html">harmonic/shift/omp</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic_shift_cut.html">harmonic/shift/cut/omp</A></TD><TD WIDTH="100"><A HREF = "bond_morse.html">morse/omp</A></TD><TD WIDTH="100"><A HREF = "bond_nonlinear.html">nonlinear/omp</A></TD></TR>
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_quartic.html">quartic/omp</A></TD><TD WIDTH="100"><A HREF = "bond_table.html">table/omp</A>
+</TD></TR></TABLE></DIV>
+
<HR>
<H4>Angle_style potentials
</H4>
<P>See the <A HREF = "angle_style.html">angle_style</A> command for an overview of
angle potentials. Click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_none.html">none</A></TD><TD WIDTH="100"><A HREF = "angle_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "angle_charmm.html">charmm</A></TD><TD WIDTH="100"><A HREF = "angle_class2.html">class2</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_cosine.html">cosine</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_delta.html">cosine/delta</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_periodic.html">cosine/periodic</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_squared.html">cosine/squared</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "angle_table.html">table</A>
</TD></TR></TABLE></DIV>
<P>These are angle styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
-<TR ALIGN="center"><TD ><A HREF = "angle_cmm.html">cg/cmm</A></TD><TD ><A HREF = "angle_cosine_shift.html">cosine/shift</A></TD><TD ><A HREF = "angle_cosine_shift_exp.html">cosine/shift/exp</A>
+<TR ALIGN="center"><TD ><A HREF = "angle_sdk.html">sdk</A></TD><TD ><A HREF = "angle_cosine_shift.html">cosine/shift</A></TD><TD ><A HREF = "angle_cosine_shift_exp.html">cosine/shift/exp</A>
+</TD></TR></TABLE></DIV>
+
+<P>These are accelerated angle styles, which can be used if LAMMPS is
+built with the <A HREF = "Section_accelerate.html">appropriate accelerated
+package</A>.
+</P>
+<DIV ALIGN=center><TABLE BORDER=1 >
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_charmm.html">charmm/omp</A></TD><TD WIDTH="100"><A HREF = "angle_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine.html">cosine/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_delta.html">cosine/delta/omp</A></TD></TR>
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_cosine_periodic.html">cosine/periodic/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_shift.html">cosine/shift/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_shift_exp.html">cosine/shift/exp/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_squared.html">cosine/squared/omp</A></TD></TR>
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_harmonic.html">harmonic/omp</A></TD><TD WIDTH="100"><A HREF = "angle_table.html">table/omp</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Dihedral_style potentials
</H4>
<P>See the <A HREF = "dihedral_style.html">dihedral_style</A> command for an overview
of dihedral potentials. Click on the style itself for a full
description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_none.html">none</A></TD><TD WIDTH="100"><A HREF = "dihedral_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "dihedral_charmm.html">charmm</A></TD><TD WIDTH="100"><A HREF = "dihedral_class2.html">class2</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "dihedral_helix.html">helix</A></TD><TD WIDTH="100"><A HREF = "dihedral_multi_harmonic.html">multi/harmonic</A></TD><TD WIDTH="100"><A HREF = "dihedral_opls.html">opls</A>
</TD></TR></TABLE></DIV>
<P>These are dihedral styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "dihedral_cosine_shift_exp.html">cosine/shift/exp</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated dihedral styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_charmm.html">charmm/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_cosine_shift_exp.html">cosine/shift/exp/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_harmonic.html">harmonic/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_helix.html">helix/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_multi_harmonic.html">multi/harmonic/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_opls.html">opls/omp</A>
</TD></TR></TABLE></DIV>
<HR>
<H4>Improper_style potentials
</H4>
<P>See the <A HREF = "improper_style.html">improper_style</A> command for an overview
of improper potentials. Click on the style itself for a full
description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_none.html">none</A></TD><TD WIDTH="100"><A HREF = "improper_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "improper_class2.html">class2</A></TD><TD WIDTH="100"><A HREF = "improper_cvff.html">cvff</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "improper_umbrella.html">umbrella</A>
</TD></TR></TABLE></DIV>
+<P>These are accelerated improper styles, which can be used if LAMMPS is
+built with the <A HREF = "Section_accelerate.html">appropriate accelerated
+package</A>.
+</P>
+<DIV ALIGN=center><TABLE BORDER=1 >
+<TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "improper_cvff.html">cvff/omp</A></TD><TD WIDTH="100"><A HREF = "improper_harmonic.html">harmonic/omp</A></TD><TD WIDTH="100"><A HREF = "improper_umbrella.html">umbrella/omp</A>
+</TD></TR></TABLE></DIV>
+
<HR>
<H4>Kspace solvers
</H4>
<P>See the <A HREF = "kspace_style.html">kspace_style</A> command for an overview of
Kspace solvers. Click on the style itself for a full description:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "kspace_style.html">ewald</A></TD><TD WIDTH="100"><A HREF = "kspace_style.html">pppm</A></TD><TD WIDTH="100"><A HREF = "kspace_style.html">pppm/cg</A></TD><TD WIDTH="100"><A HREF = "kspace_style.html">pppm/tip4p</A>
</TD></TR></TABLE></DIV>
<P>These are Kspace solvers contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "kspace_style.html">ewald/n</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated Kspace solvers, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
-<TR ALIGN="center"><TD ><A HREF = "kspace_style.html">pppm/cuda</A></TD><TD ><A HREF = "kspace_style.html">pppm/gpu</A>
+<TR ALIGN="center"><TD ><A HREF = "kspace_style.html">ewald/omp</A></TD><TD ><A HREF = "kspace_style.html">pppm/cuda</A></TD><TD ><A HREF = "kspace_style.html">pppm/gpu</A></TD><TD ><A HREF = "kspace_style.html">pppm/omp</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "kspace_style.html">pppm/proxy</A>
</TD></TR></TABLE></DIV>
</HTML>
diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt
index 00cb93f7c..a697f799b 100644
--- a/doc/Section_commands.txt
+++ b/doc/Section_commands.txt
@@ -1,950 +1,1000 @@
"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 what
-commands are used to define a LAMMPS simulation.
+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
(with no surrounding quotes), the command is assumed to continue on
the next line. The next line is concatenated to the previous line by
removing the "&" character and newline. This allows long commands to
be continued across two or more lines.
(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". See the "variable"_variable.html command for
details of how strings are assigned to variables and how they are
substituted for 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 double or single quotes. E.g.
print "Volume = $v"
print 'Volume = $v' :pre
The quotes are removed when the single argument is stored internally.
See the "dump modify format"_dump_modify.html or "if"_if.html commands
for examples. A "#" or "$" character that is between quotes will not
be treated as a comment indicator in (2) or substituted for as a
variable in (3).
IMPORTANT NOTE: If the argument is itself a command that requires a
quoted argument (e.g. using a "print"_print.html command as part of an
"if"_if.html or "run every"_run.html command), then the double and
single quotes can be nested in the usual manner. See the doc pages
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
-"this section"_Section_example.html, and animated on the "LAMMPS WWW
-Site"_lws.
+"Section_example"_Section_example.html, and animated on the "LAMMPS
+WWW Site"_lws.
A LAMMPS input script typically has 4 parts:
Initialization
Atom definition
Settings
Run a simulation :ol
The last 2 parts can be repeated as many times as desired. I.e. run a
simulation, change some settings, run some more, etc. Each of the 4
parts is now described in more detail. Remember that almost all the
commands need only be used if a non-default value is desired.
(1) Initialization
Set parameters that need to be defined before atoms are created or
read-in from a file.
The relevant commands are "units"_units.html,
"dimension"_dimension.html, "newton"_newton.html,
"processors"_processors.html, "boundary"_boundary.html,
"atom_style"_atom_style.html, "atom_modify"_atom_modify.html.
If force-field parameters appear in the files that will be read, these
commands tell LAMMPS what kinds of force fields are being used:
"pair_style"_pair_style.html, "bond_style"_bond_style.html,
"angle_style"_angle_style.html, "dihedral_style"_dihedral_style.html,
"improper_style"_improper_style.html.
(2) Atom definition
There are 3 ways to define atoms in LAMMPS. Read them in from a data
or restart file via the "read_data"_read_data.html or
"read_restart"_read_restart.html commands. These files can contain
molecular topology information. Or create atoms on a lattice (with no
molecular topology), using these commands: "lattice"_lattice.html,
"region"_region.html, "create_box"_create_box.html,
"create_atoms"_create_atoms.html. The entire set of atoms can be
duplicated to make a larger simulation using the
"replicate"_replicate.html command.
(3) Settings
Once atoms and molecular topology are defined, a variety of settings
can be specified: force field coefficients, simulation parameters,
output options, etc.
Force field coefficients are set by these commands (they can also be
set in the read-in files): "pair_coeff"_pair_coeff.html,
"bond_coeff"_bond_coeff.html, "angle_coeff"_angle_coeff.html,
"dihedral_coeff"_dihedral_coeff.html,
"improper_coeff"_improper_coeff.html,
"kspace_style"_kspace_style.html, "dielectric"_dielectric.html,
"special_bonds"_special_bonds.html.
Various simulation parameters are set by these commands:
"neighbor"_neighbor.html, "neigh_modify"_neigh_modify.html,
"group"_group.html, "timestep"_timestep.html,
"reset_timestep"_reset_timestep.html, "run_style"_run_style.html,
"min_style"_min_style.html, "min_modify"_min_modify.html.
Fixes impose a variety of boundary conditions, time integration, and
diagnostic options. The "fix"_fix.html command comes in many flavors.
Various computations can be specified for execution during a
simulation using the "compute"_compute.html,
"compute_modify"_compute_modify.html, and "variable"_variable.html
commands.
Output options are set by the "thermo"_thermo.html, "dump"_dump.html,
and "restart"_restart.html commands.
(4) Run a simulation
A molecular dynamics simulation is run using the "run"_run.html
command. Energy minimization (molecular statics) is performed using
the "minimize"_minimize.html command. A parallel tempering
(replica-exchange) simulation can be run using the
"temper"_temper.html command.
:line
3.4 Commands listed by category :link(cmd_4),h4
This section lists all LAMMPS commands, grouped by category. The
"next section"_#cmd_5 lists the same commands alphabetically. Note
that some style options for some commands are part of specific LAMMPS
packages, which means they cannot be used unless the package was
included when LAMMPS was built. Not all packages are included in a
default LAMMPS build. These dependencies are listed as Restrictions
in the command's documentation.
Initialization:
"atom_modify"_atom_modify.html, "atom_style"_atom_style.html,
"boundary"_boundary.html, "dimension"_dimension.html,
"newton"_newton.html, "processors"_processors.html, "units"_units.html
Atom definition:
"create_atoms"_create_atoms.html, "create_box"_create_box.html,
"lattice"_lattice.html, "read_data"_read_data.html,
"read_restart"_read_restart.html, "region"_region.html,
"replicate"_replicate.html
Force fields:
"angle_coeff"_angle_coeff.html, "angle_style"_angle_style.html,
"bond_coeff"_bond_coeff.html, "bond_style"_bond_style.html,
"dielectric"_dielectric.html, "dihedral_coeff"_dihedral_coeff.html,
"dihedral_style"_dihedral_style.html,
"improper_coeff"_improper_coeff.html,
"improper_style"_improper_style.html,
"kspace_modify"_kspace_modify.html, "kspace_style"_kspace_style.html,
"pair_coeff"_pair_coeff.html, "pair_modify"_pair_modify.html,
"pair_style"_pair_style.html, "pair_write"_pair_write.html,
"special_bonds"_special_bonds.html
Settings:
"communicate"_communicate.html, "group"_group.html, "mass"_mass.html,
"min_modify"_min_modify.html, "min_style"_min_style.html,
"neigh_modify"_neigh_modify.html, "neighbor"_neighbor.html,
"reset_timestep"_reset_timestep.html, "run_style"_run_style.html,
"set"_set.html, "timestep"_timestep.html, "velocity"_velocity.html
Fixes:
"fix"_fix.html, "fix_modify"_fix_modify.html, "unfix"_unfix.html
Computes:
"compute"_compute.html, "compute_modify"_compute_modify.html,
"uncompute"_uncompute.html
Output:
"dump"_dump.html, "dump image"_dump_image.html,
"dump_modify"_dump_modify.html, "restart"_restart.html,
"thermo"_thermo.html, "thermo_modify"_thermo_modify.html,
"thermo_style"_thermo_style.html, "undump"_undump.html,
"write_restart"_write_restart.html
Actions:
"delete_atoms"_delete_atoms.html, "delete_bonds"_delete_bonds.html,
"displace_atoms"_displace_atoms.html,
"displace_box"_displace_box.html, "minimize"_minimize.html,
"neb"_neb.html "prd"_prd.html, "run"_run.html, "temper"_temper.html
Miscellaneous:
"clear"_clear.html, "echo"_echo.html, "if"_if.html,
"include"_include.html, "jump"_jump.html, "label"_label.html,
"log"_log.html, "next"_next.html, "print"_print.html,
"shell"_shell.html, "variable"_variable.html
:line
3.5 Individual commands :h4,link(cmd_5),link(comm)
This section lists all LAMMPS commands alphabetically, with a separate
listing below of styles within certain commands. The "previous
section"_#cmd_4 lists the same commands, grouped by category. Note
that some style options for some commands are part of specific LAMMPS
packages, which means they cannot be used unless the package was
included when LAMMPS was built. Not all packages are included in a
default LAMMPS build. These dependencies are listed as Restrictions
in the command's documentation.
"angle_coeff"_angle_coeff.html,
"angle_style"_angle_style.html,
"atom_modify"_atom_modify.html,
"atom_style"_atom_style.html,
"bond_coeff"_bond_coeff.html,
"bond_style"_bond_style.html,
"boundary"_boundary.html,
"change_box"_change_box.html,
"clear"_clear.html,
"communicate"_communicate.html,
"compute"_compute.html,
"compute_modify"_compute_modify.html,
"create_atoms"_create_atoms.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,
"displace_box"_displace_box.html,
"dump"_dump.html,
"dump image"_dump_image.html,
"dump_modify"_dump_modify.html,
"echo"_echo.html,
"fix"_fix.html,
"fix_modify"_fix_modify.html,
"group"_group.html,
"if"_if.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,
"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,
"read_data"_read_data.html,
"read_restart"_read_restart.html,
"region"_region.html,
"replicate"_replicate.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,
"timestep"_timestep.html,
"uncompute"_uncompute.html,
"undump"_undump.html,
"unfix"_unfix.html,
"units"_units.html,
"variable"_variable.html,
"velocity"_velocity.html,
"write_restart"_write_restart.html :tb(c=6,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:
"adapt"_fix_adapt.html,
"addforce"_fix_addforce.html,
"aveforce"_fix_aveforce.html,
"ave/atom"_fix_ave_atom.html,
"ave/correlate"_fix_ave_correlate.html,
"ave/histo"_fix_ave_histo.html,
"ave/spatial"_fix_ave_spatial.html,
"ave/time"_fix_ave_time.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,
"deform"_fix_deform.html,
"deposit"_fix_deposit.html,
"drag"_fix_drag.html,
"dt/reset"_fix_dt_reset.html,
"efield"_fix_efield.html,
"enforce2d"_fix_enforce2d.html,
"evaporate"_fix_evaporate.html,
"external"_fix_external.html,
"freeze"_fix_freeze.html,
"gcmc"_fix_gcmc.html,
"gravity"_fix_gravity.html,
"heat"_fix_heat.html,
"indent"_fix_indent.html,
"langevin"_fix_langevin.html,
"lineforce"_fix_lineforce.html,
"momentum"_fix_momentum.html,
"move"_fix_move.html,
"msst"_fix_msst.html,
"neb"_fix_neb.html,
"nph"_fix_nh.html,
"nphug"_fix_nphug.html,
"nph/asphere"_fix_nph_asphere.html,
"nph/sphere"_fix_nph_sphere.html,
"npt"_fix_nh.html,
"npt/asphere"_fix_npt_asphere.html,
"npt/sphere"_fix_npt_sphere.html,
"nve"_fix_nve.html,
"nve/asphere"_fix_nve_asphere.html,
"nve/asphere/noforce"_fix_nve_asphere_noforce.html,
"nve/limit"_fix_nve_limit.html,
"nve/line"_fix_nve_line.html,
"nve/noforce"_fix_nve_noforce.html,
"nve/sphere"_fix_nve_sphere.html,
"nve/tri"_fix_nve_tri.html,
"nvt"_fix_nh.html,
"nvt/asphere"_fix_nvt_asphere.html,
"nvt/sllod"_fix_nvt_sllod.html,
"nvt/sphere"_fix_nvt_sphere.html,
"orient/fcc"_fix_orient_fcc.html,
"planeforce"_fix_planeforce.html,
"poems"_fix_poems.html,
"pour"_fix_pour.html,
"press/berendsen"_fix_press_berendsen.html,
"print"_fix_print.html,
"qeq/comb"_fix_qeq_comb.html,
"reax/bonds"_fix_reax_bonds.html,
"recenter"_fix_recenter.html,
"restrain"_fix_restrain.html,
"rigid"_fix_rigid.html,
"rigid/nve"_fix_rigid.html,
"rigid/nvt"_fix_rigid.html,
"setforce"_fix_setforce.html,
"shake"_fix_shake.html,
"spring"_fix_spring.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/rescale"_fix_temp_rescale.html,
"thermal/conductivity"_fix_thermal_conductivity.html,
"tmd"_fix_tmd.html,
"ttm"_fix_ttm.html,
"viscosity"_fix_viscosity.html,
"viscous"_fix_viscous.html,
"wall/colloid"_fix_wall.html,
"wall/gran"_fix_wall_gran.html,
"wall/harmonic"_fix_wall.html,
"wall/lj126"_fix_wall.html,
"wall/lj93"_fix_wall.html,
"wall/reflect"_fix_wall_reflect.html,
"wall/region"_fix_wall_region.html,
"wall/srd"_fix_wall_srd.html :tb(c=8,ea=c)
These are fix styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"addtorque"_fix_addtorque.html,
"atc"_fix_atc.html,
"imd"_fix_imd.html,
"langevin/eff"_fix_langevin_eff.html,
"meso"_fix_meso.html,
"meso/stationary"_fix_meso_stationary.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,
"qeq/reax"_fix_qeq_reax.html,
"smd"_fix_smd.html,
"temp/rescale/eff"_fix_temp_rescale_eff.html :tb(c=6,ea=c)
These are accelerated fix styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"freeze/cuda"_fix_freeze.html,
"addforce/cuda"_fix_addforce.html,
"aveforce/cuda"_fix_aveforce.html,
"enforce2d/cuda"_fix_enforce2d.html,
"gravity/cuda"_fix_gravity.html,
"gravity/omp"_fix_gravity.html,
"npt/cuda"_fix_nh.html,
"nve/cuda"_fix_nh.html,
"nve/sphere/omp"_fix_nve_sphere.html,
"nvt/cuda"_fix_nh.html,
"qeq/comb/omp"_fix_qeq_comb.html,
"setforce/cuda"_fix_setforce.html,
"shake/cuda"_fix_shake.html,
"temp/berendsen/cuda"_fix_temp_berendsen.html,
"temp/rescale/cuda"_fix_temp_rescale.html,
"temp/rescale/limit/cuda"_fix_temp_rescale.html,
"viscous/cuda"_fix_viscous.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:
"angle/local"_compute_angle_local.html,
"atom/molecule"_compute_atom_molecule.html,
"bond/local"_compute_bond_local.html,
"centro/atom"_compute_centro_atom.html,
"cluster/atom"_compute_cluster_atom.html,
"cna/atom"_compute_cna_atom.html,
"com"_compute_com.html,
"com/molecule"_compute_com_molecule.html,
"coord/atom"_compute_coord_atom.html,
"damage/atom"_compute_damage_atom.html,
"dihedral/local"_compute_dihedral_local.html,
"displace/atom"_compute_displace_atom.html,
"erotate/asphere"_compute_erotate_asphere.html,
"erotate/sphere"_compute_erotate_sphere.html,
"event/displace"_compute_event_displace.html,
"group/group"_compute_group_group.html,
"gyration"_compute_gyration.html,
"gyration/molecule"_compute_gyration_molecule.html,
"heat/flux"_compute_heat_flux.html,
"improper/local"_compute_improper_local.html,
"ke"_compute_ke.html,
"ke/atom"_compute_ke_atom.html,
"msd"_compute_msd.html,
"msd/molecule"_compute_msd_molecule.html,
"pair"_compute_pair.html,
"pair/local"_compute_pair_local.html,
"pe"_compute_pe.html,
"pe/atom"_compute_pe_atom.html,
"pressure"_compute_pressure.html,
"property/atom"_compute_property_atom.html,
"property/local"_compute_property_local.html,
"property/molecule"_compute_property_molecule.html,
"rdf"_compute_rdf.html,
"reduce"_compute_reduce.html,
"reduce/region"_compute_reduce.html,
"slice"_compute_slice.html,
"stress/atom"_compute_stress_atom.html,
"temp"_compute_temp.html,
"temp/asphere"_compute_temp_asphere.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 :tb(c=6,ea=c)
These are compute styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"ackland/atom"_compute_ackland_atom.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,
"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 :tb(c=6,ea=c)
These are accelerated compute styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"pe/cuda"_compute_pe.html,
"pressure/cuda"_compute_pressure.html,
"temp/cuda"_compute_temp.html,
"temp/partial/cuda"_compute_temp_partial.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:
"none"_pair_none.html,
"hybrid"_pair_hybrid.html,
"hybrid/overlay"_pair_hybrid.html,
"adp"_pair_adp.html,
"airebo"_pair_airebo.html,
"born"_pair_born.html,
"born/coul/long"_pair_born.html,
+"born/coul/wolf"_pair_born.html,
"brownian"_pair_brownian.html,
"brownian/poly"_pair_brownian.html,
"buck"_pair_buck.html,
"buck/coul/cut"_pair_buck.html,
"buck/coul/long"_pair_buck.html,
"colloid"_pair_colloid.html,
"comb"_pair_comb.html,
"coul/cut"_pair_coul.html,
"coul/debye"_pair_coul.html,
"coul/long"_pair_coul.html,
+"coul/wolf"_pair_coul.html,
"dipole/cut"_pair_dipole.html,
"dpd"_pair_dpd.html,
"dpd/tstat"_pair_dpd.html,
"dsmc"_pair_dsmc.html,
"eam"_pair_eam.html,
"eam/alloy"_pair_eam.html,
"eam/fs"_pair_eam.html,
"eim"_pair_eim.html,
"gauss"_pair_gauss.html,
"gayberne"_pair_gayberne.html,
"gran/hertz/history"_pair_gran.html,
"gran/hooke"_pair_gran.html,
"gran/hooke/history"_pair_gran.html,
"hbond/dreiding/lj"_pair_hbond_dreiding.html,
"hbond/dreiding/morse"_pair_hbond_dreiding.html,
"line/lj"_pair_line_lj.html,
"lj/charmm/coul/charmm"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit"_pair_charmm.html,
"lj/charmm/coul/long"_pair_charmm.html,
"lj/class2"_pair_class2.html,
"lj/class2/coul/cut"_pair_class2.html,
"lj/class2/coul/long"_pair_class2.html,
"lj/cut"_pair_lj.html,
"lj/cut/coul/cut"_pair_lj.html,
"lj/cut/coul/debye"_pair_lj.html,
"lj/cut/coul/long"_pair_lj.html,
"lj/cut/coul/long/tip4p"_pair_lj.html,
"lj/expand"_pair_lj_expand.html,
"lj/gromacs"_pair_gromacs.html,
"lj/gromacs/coul/gromacs"_pair_gromacs.html,
"lj/smooth"_pair_lj_smooth.html,
"lj96/cut"_pair_lj96.html,
"lubricate"_pair_lubricate.html,
"lubricate/poly"_pair_lubricate.html,
"lubricateU"_pair_lubricateU.html,
"lubricateU/poly"_pair_lubricateU.html,
"meam"_pair_meam.html,
"morse"_pair_morse.html,
"peri/lps"_pair_peri.html,
"peri/pmb"_pair_peri.html,
"reax"_pair_reax.html,
"rebo"_pair_airebo.html,
"resquared"_pair_resquared.html,
"soft"_pair_soft.html,
"sw"_pair_sw.html,
"table"_pair_table.html,
"tersoff"_pair_tersoff.html,
"tersoff/zbl"_pair_tersoff_zbl.html,
"tri/lj"_pair_tri_lj.html,
"yukawa"_pair_yukawa.html,
"yukawa/colloid"_pair_yukawa_colloid.html :tb(c=4,ea=c)
These are pair styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"awpmd/cut"_pair_awpmd.html,
"buck/coul"_pair_buck_coul.html,
-"cg/cmm"_pair_cmm.html,
-"cg/cmm/coul/cut"_pair_cmm.html,
-"cg/cmm/coul/long"_pair_cmm.html,
-"coul/long/gpu"_pair_coul.html,
+"coul/diel"_pair_coul_diel.html,
+"lj/sdk"_pair_sdk.html,
+"lj/sdk/coul/long"_pair_sdk.html,
"dipole/sf"_pair_dipole.html,
"eam/cd"_pair_eam.html,
"edip"_pair_edip.html,
"eff/cut"_pair_eff.html,
+"gauss/cut"_pair_gauss.html,
"lj/coul"_pair_lj_coul.html,
"lj/sf"_pair_lj_sf.html,
"reax/c"_pair_reax_c.html,
"sph/heatconduction"_pair_heatconduction.html,
"sph/idealgas"_pair_idealgas.html,
"sph/lj"_pair_lj.html,
"sph/rhosum"_pair_rhosum.html,
"sph/taitwater"_pair_taitwater.html,
-"sph/taitwater/morris"_pair_taitwater_morris.html :tb(c=4,ea=c)
+"sph/taitwater/morris"_pair_taitwater_morris.html,
+"tersoff/table"_pair_tersoff.html :tb(c=4,ea=c)
These are accelerated pair styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"adp/omp"_pair_adp.html,
"airebo/omp"_pair_airebo.html,
"born/coul/long/cuda"_pair_born.html,
"born/coul/long/omp"_pair_born.html,
"born/omp"_pair_born.html,
"buck/coul/cut/cuda"_pair_buck.html,
"buck/coul/cut/omp"_pair_buck.html,
"buck/coul/long/cuda"_pair_buck.html,
"buck/coul/long/omp"_pair_buck.html,
"buck/coul/omp"_pair_buck_coul.html,
"buck/cuda"_pair_buck.html,
"buck/omp"_pair_buck.html,
-"cg/cmm/coul/cut/cuda"_pair_cmm.html,
-"cg/cmm/coul/debye/cuda"_pair_cmm.html,
-"cg/cmm/coul/long/cuda"_pair_cmm.html,
-"cg/cmm/coul/long/gpu"_pair_cmm.html,
-"cg/cmm/cuda"_pair_cmm.html,
-"cg/cmm/gpu"_pair_cmm.html,
+"lj/sdk/gpu"_pair_sdk.html,
+"lj/sdk/omp"_pair_sdk.html,
+"lj/sdk/coul/long/gpu"_pair_sdk.html,
+"lj/sdk/coul/long/omp"_pair_sdk.html,
"colloid/omp"_pair_colloid.html,
"comb/omp"_pair_comb.html,
"coul/cut/omp"_pair_coul.html,
"coul/debye/omp"_pair_coul.html,
"coul/long/gpu"_pair_coul.html,
"coul/long/omp"_pair_coul.html,
"dipole/cut/omp"_pair_dipole.html,
"dipole/sf/omp"_pair_dipole.html,
"dpd/omp"_pair_dpd.html,
"dpd/tstat/omp"_pair_dpd.html,
"eam/alloy/cuda"_pair_eam.html,
"eam/alloy/omp"_pair_eam.html,
"eam/alloy/opt"_pair_eam.html,
"eam/cd/omp"_pair_eam.html,
"eam/cuda"_pair_eam.html,
"eam/fs/cuda"_pair_eam.html,
"eam/fs/omp"_pair_eam.html,
"eam/fs/opt"_pair_eam.html,
"eam/omp"_pair_eam.html,
"eam/opt"_pair_eam.html,
"edip/omp"_pair_edip.html,
"eim/omp"_pair_eim.html,
"gauss/omp"_pair_gauss.html,
"gayberne/gpu"_pair_gayberne.html,
"gayberne/omp"_pair_gayberne.html,
"gran/hertz/history/omp"_pair_gran.html,
"gran/hooke/cuda"_pair_gran.html,
"gran/hooke/history/omp"_pair_gran.html,
"gran/hooke/omp"_pair_gran.html,
"hbond/dreiding/lj/omp"_pair_hbond_dreiding.html,
"hbond/dreiding/morse/omp"_pair_hbond_dreiding.html,
+"line/lj/omp"_pair_line_lj.html,
"lj/charmm/coul/charmm/cuda"_pair_charmm.html,
"lj/charmm/coul/charmm/omp"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit/cuda"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit/omp"_pair_charmm.html,
"lj/charmm/coul/long/cuda"_pair_charmm.html,
"lj/charmm/coul/long/gpu"_pair_charmm.html,
"lj/charmm/coul/long/omp"_pair_charmm.html,
"lj/charmm/coul/long/opt"_pair_charmm.html,
+"lj/charmm/coul/pppm/omp"_pair_charmm.html,
"lj/class2/coul/cut/cuda"_pair_class2.html,
"lj/class2/coul/cut/omp"_pair_class2.html,
"lj/class2/coul/long/cuda"_pair_class2.html,
"lj/class2/coul/long/gpu"_pair_class2.html,
"lj/class2/coul/long/omp"_pair_class2.html,
"lj/class2/cuda"_pair_class2.html,
"lj/class2/gpu"_pair_class2.html,
"lj/class2/omp"_pair_class2.html,
"lj/coul/omp"_pair_lj_coul.html,
"lj/cut/coul/cut/cuda"_pair_lj.html,
"lj/cut/coul/cut/gpu"_pair_lj.html,
"lj/cut/coul/cut/omp"_pair_lj.html,
"lj/cut/coul/debye/cuda"_pair_lj.html,
"lj/cut/coul/debye/omp"_pair_lj.html,
"lj/cut/coul/long/cuda"_pair_lj.html,
"lj/cut/coul/long/gpu"_pair_lj.html,
"lj/cut/coul/long/omp"_pair_lj.html,
"lj/cut/coul/long/opt"_pair_lj.html,
"lj/cut/coul/long/tip4p/omp"_pair_lj.html,
"lj/cut/coul/long/tip4p/opt"_pair_lj.html,
+"lj/cut/coul/pppm/omp"_pair_lj.html,
+"lj/cut/coul/pppm/tip4p/omp"_pair_lj.html,
"lj/cut/cuda"_pair_lj.html,
"lj/cut/experimental/cuda"_pair_lj.html,
"lj/cut/gpu"_pair_lj.html,
"lj/cut/omp"_pair_lj.html,
"lj/cut/opt"_pair_lj.html,
"lj/expand/cuda"_pair_lj_expand.html,
"lj/expand/gpu"_pair_lj_expand.html,
"lj/expand/omp"_pair_lj_expand.html,
"lj/gromacs/coul/gromacs/cuda"_pair_gromacs.html,
"lj/gromacs/coul/gromacs/omp"_pair_gromacs.html,
"lj/gromacs/cuda"_pair_gromacs.html,
"lj/gromacs/omp"_pair_gromacs.html,
"lj/sf/omp"_pair_lj_sf.html,
"lj/smooth/cuda"_pair_lj_smooth.html,
"lj/smooth/omp"_pair_lj_smooth.html,
"lj96/cut/cuda"_pair_lj96.html,
"lj96/cut/gpu"_pair_lj96.html,
"lj96/cut/omp"_pair_lj96.html,
-"lubricate/omp"_pair_lubricate.html,
"morse/cuda"_pair_morse.html,
"morse/gpu"_pair_morse.html,
"morse/omp"_pair_morse.html,
"morse/opt"_pair_morse.html,
"peri/lps/omp"_pair_peri.html,
"peri/pmb/omp"_pair_peri.html,
"rebo/omp"_pair_airebo.html,
-"resquared/gpu"_pair_resquared.html
+"resquared/gpu"_pair_resquared.html,
"resquared/omp"_pair_resquared.html,
"soft/omp"_pair_soft.html,
"sw/cuda"_pair_sw.html,
"sw/omp"_pair_sw.html,
"table/omp"_pair_table.html,
"tersoff/cuda"_pair_tersoff.html,
"tersoff/omp"_pair_tersoff.html,
+"tersoff/table/omp"_pair_tersoff.html,
"tersoff/zbl/omp"_pair_tersoff_zbl.html,
+"tri/lj/omp"_pair_tri_lj.html,
"yukawa/omp"_pair_yukawa.html,
"yukawa/colloid/omp"_pair_yukawa_colloid.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:
"none"_bond_none.html,
"hybrid"_bond_hybrid.html,
"class2"_bond_class2.html,
"fene"_bond_fene.html,
"fene/expand"_bond_fene_expand.html,
"harmonic"_bond_harmonic.html,
"morse"_bond_morse.html,
"nonlinear"_bond_nonlinear.html,
"quartic"_bond_quartic.html,
"table"_bond_table.html :tb(c=4,ea=c,w=100)
These are bond styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"harmonic/shift"_bond_harmonic_shift.html,
"harmonic/shift/cut"_bond_harmonic_shift_cut.html :tb(c=4,ea=c)
+These are accelerated bond styles, which can be used if LAMMPS is
+built with the "appropriate accelerated
+package"_Section_accelerate.html.
+
+"class2/omp"_bond_class2.html,
+"fene/omp"_bond_fene.html,
+"fene/expand/omp"_bond_fene_expand.html,
+"harmonic/omp"_bond_harmonic.html,
+"harmonic/shift/omp"_bond_harmonic_shift.html,
+"harmonic/shift/cut/omp"_bond_harmonic_shift_cut.html,
+"morse/omp"_bond_morse.html,
+"nonlinear/omp"_bond_nonlinear.html,
+"quartic/omp"_bond_quartic.html,
+"table/omp"_bond_table.html :tb(c=4,ea=c,w=100)
+
: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:
"none"_angle_none.html,
"hybrid"_angle_hybrid.html,
"charmm"_angle_charmm.html,
"class2"_angle_class2.html,
"cosine"_angle_cosine.html,
"cosine/delta"_angle_cosine_delta.html,
"cosine/periodic"_angle_cosine_periodic.html,
"cosine/squared"_angle_cosine_squared.html,
"harmonic"_angle_harmonic.html,
"table"_angle_table.html :tb(c=4,ea=c,w=100)
These are angle styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
-"cg/cmm"_angle_cmm.html,
+"sdk"_angle_sdk.html,
"cosine/shift"_angle_cosine_shift.html,
"cosine/shift/exp"_angle_cosine_shift_exp.html :tb(c=4,ea=c)
+These are accelerated angle styles, which can be used if LAMMPS is
+built with the "appropriate accelerated
+package"_Section_accelerate.html.
+
+"charmm/omp"_angle_charmm.html,
+"class2/omp"_angle_class2.html,
+"cosine/omp"_angle_cosine.html,
+"cosine/delta/omp"_angle_cosine_delta.html,
+"cosine/periodic/omp"_angle_cosine_periodic.html,
+"cosine/shift/omp"_angle_cosine_shift.html,
+"cosine/shift/exp/omp"_angle_cosine_shift_exp.html,
+"cosine/squared/omp"_angle_cosine_squared.html,
+"harmonic/omp"_angle_harmonic.html,
+"table/omp"_angle_table.html :tb(c=4,ea=c,w=100)
+
: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:
"none"_dihedral_none.html,
"hybrid"_dihedral_hybrid.html,
"charmm"_dihedral_charmm.html,
"class2"_dihedral_class2.html,
"harmonic"_dihedral_harmonic.html,
"helix"_dihedral_helix.html,
"multi/harmonic"_dihedral_multi_harmonic.html,
"opls"_dihedral_opls.html :tb(c=4,ea=c,w=100)
These are dihedral styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"cosine/shift/exp"_dihedral_cosine_shift_exp.html :tb(c=4,ea=c)
These are accelerated dihedral styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"charmm/omp"_dihedral_charmm.html,
"class2/omp"_dihedral_class2.html,
"cosine/shift/exp/omp"_dihedral_cosine_shift_exp.html,
"harmonic/omp"_dihedral_harmonic.html,
"helix/omp"_dihedral_helix.html,
"multi/harmonic/omp"_dihedral_multi_harmonic.html,
"opls/omp"_dihedral_opls.html :tb(c=4,ea=c,w=100)
: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:
"none"_improper_none.html,
"hybrid"_improper_hybrid.html,
"class2"_improper_class2.html,
"cvff"_improper_cvff.html,
"harmonic"_improper_harmonic.html,
"umbrella"_improper_umbrella.html :tb(c=4,ea=c,w=100)
+These are accelerated improper styles, which can be used if LAMMPS is
+built with the "appropriate accelerated
+package"_Section_accelerate.html.
+
+"class2/omp"_improper_class2.html,
+"cvff/omp"_improper_cvff.html,
+"harmonic/omp"_improper_harmonic.html,
+"umbrella/omp"_improper_umbrella.html :tb(c=4,ea=c,w=100)
+
: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:
"ewald"_kspace_style.html,
"pppm"_kspace_style.html,
"pppm/cg"_kspace_style.html,
"pppm/tip4p"_kspace_style.html :tb(c=4,ea=c,w=100)
These are Kspace solvers contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"ewald/n"_kspace_style.html :tb(c=4,ea=c,w=100)
These are accelerated Kspace solvers, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
+"ewald/omp"_kspace_style.html,
"pppm/cuda"_kspace_style.html,
-"pppm/gpu"_kspace_style.html :tb(c=4,ea=c)
+"pppm/gpu"_kspace_style.html,
+"pppm/omp"_kspace_style.html,
+"pppm/proxy"_kspace_style.html :tb(c=4,ea=c)
diff --git a/doc/Section_errors.html b/doc/Section_errors.html
index 4330576f5..b7fbbbba7 100644
--- a/doc/Section_errors.html
+++ b/doc/Section_errors.html
@@ -1,6601 +1,6620 @@
<HTML>
<CENTER><A HREF = "Section_python.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> -
<A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_history.html">Next
Section</A>
</CENTER>
<HR>
<H3>12. Errors
</H3>
-<P>This section describes the various kinds of errors you can encounter
-when using LAMMPS.
+<P>This section describes the errors you can encounter when using LAMMPS,
+either conceptually, or as printed out by the program.
</P>
12.1 <A HREF = "#err_1">Common problems</A><BR>
12.2 <A HREF = "#err_2">Reporting bugs</A><BR>
12.3 <A HREF = "#err_3">Error & warning messages</A> <BR>
<HR>
+<HR>
+
<A NAME = "err_1"></A><H4>12.1 Common problems
</H4>
<P>If two LAMMPS runs do not produce the same answer on different
machines or different numbers of processors, this is typically not a
bug. In theory you should get identical answers on any number of
processors and on any machine. In practice, numerical round-off can
cause slight differences and eventual divergence of molecular dynamics
phase space trajectories within a few 100s or few 1000s of timesteps.
However, the statistical properties of the two runs (e.g. average
energy or temperature) should still be the same.
</P>
<P>If the <A HREF = "velocity.html">velocity</A> command is used to set initial atom
velocities, a particular atom can be assigned a different velocity
when the problem is run on a different number of processors or on
different machines. If this happens, the phase space trajectories of
the two simulations will rapidly diverge. See the discussion of the
<I>loop</I> option in the <A HREF = "velocity.html">velocity</A> command for details and
options that avoid this issue.
</P>
<P>Similarly, the <A HREF = "create_atoms.html">create_atoms</A> command generates a
lattice of atoms. For the same physical system, the ordering and
numbering of atoms by atom ID may be different depending on the number
of processors.
</P>
<P>Some commands use random number generators which may be setup to
produce different random number streams on each processor and hence
will produce different effects when run on different numbers of
processors. A commonly-used example is the <A HREF = "fix_langevin.html">fix
langevin</A> command for thermostatting.
</P>
<P>A LAMMPS simulation typically has two stages, setup and run. Most
LAMMPS errors are detected at setup time; others like a bond
stretching too far may not occur until the middle of a run.
</P>
<P>LAMMPS tries to flag errors and print informative error messages so
you can fix the problem. Of course, LAMMPS cannot figure out your
physics or numerical mistakes, like choosing too big a timestep,
specifying erroneous force field coefficients, or putting 2 atoms on
top of each other! If you run into errors that LAMMPS doesn't catch
that you think it should flag, please send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
</P>
<P>If you get an error message about an invalid command in your input
script, you can determine what command is causing the problem by
looking in the log.lammps file or using the <A HREF = "echo.html">echo command</A>
to see it on the screen. For a given command, LAMMPS expects certain
arguments in a specified order. If you mess this up, LAMMPS will
often flag the error, but it may read a bogus argument and assign a
value that is valid, but not what you wanted. E.g. trying to read the
string "abc" as an integer value and assigning the associated variable
a value of 0.
</P>
<P>Generally, LAMMPS will print a message to the screen and logfile and
exit gracefully when it encounters a fatal error. Sometimes it will
print a WARNING to the screen and logfile and continue on; you can
decide if the WARNING is important or not. A WARNING message that is
generated in the middle of a run is only printed to the screen, not to
the logfile, to avoid cluttering up thermodynamic output. If LAMMPS
crashes or hangs without spitting out an error message first then it
could be a bug (see <A HREF = "#err_2">this section</A>) or one of the following
cases:
</P>
<P>LAMMPS runs in the available memory a processor allows to be
allocated. Most reasonable MD runs are compute limited, not memory
limited, so this shouldn't be a bottleneck on most platforms. Almost
all large memory allocations in the code are done via C-style malloc's
which will generate an error message if you run out of memory.
Smaller chunks of memory are allocated via C++ "new" statements. If
you are unlucky you could run out of memory just when one of these
small requests is made, in which case the code will crash or hang (in
parallel), since LAMMPS doesn't trap on those errors.
</P>
<P>Illegal arithmetic can cause LAMMPS to run slow or crash. This is
typically due to invalid physics and numerics that your simulation is
computing. If you see wild thermodynamic values or NaN values in your
LAMMPS output, something is wrong with your simulation. If you
suspect this is happening, it is a good idea to print out
thermodynamic info frequently (e.g. every timestep) via the
<A HREF = "thermo.html">thermo</A> so you can monitor what is happening.
Visualizing the atom movement is also a good idea to insure your model
is behaving as you expect.
</P>
<P>In parallel, one way LAMMPS can hang is due to how different MPI
implementations handle buffering of messages. If the code hangs
without an error message, it may be that you need to specify an MPI
setting or two (usually via an environment variable) to enable
buffering or boost the sizes of messages that can be buffered.
</P>
<HR>
<A NAME = "err_2"></A><H4>12.2 Reporting bugs
</H4>
<P>If you are confident that you have found a bug in LAMMPS, follow these
steps.
</P>
<P>Check the <A HREF = "http://lammps.sandia.gov/bug.html">New features and bug
fixes</A> section of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
site</A> to see if the bug has already been reported or fixed or the
<A HREF = "http://lammps.sandia.gov/unbug.html">Unfixed bug</A> to see if a fix is
pending.
</P>
<P>Check the <A HREF = "http://lammps.sandia.gov/mail.html">mailing list</A>
to see if it has been discussed before.
</P>
<P>If not, send an email to the mailing list describing the problem with
any ideas you have as to what is causing it or where in the code the
problem might be. The developers will ask for more info if needed,
such as an input script or data files.
</P>
<P>The most useful thing you can do to help us fix the bug is to isolate
the problem. Run it on the smallest number of atoms and fewest number
of processors and with the simplest input script that reproduces the
bug and try to identify what command or combination of commands is
causing the problem.
</P>
<P>As a last resort, you can send an email directly to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
</P>
<HR>
<H4><A NAME = "err_3"></A>12.3 Error & warning messages
</H4>
<P>These are two alphabetic lists of the <A HREF = "#error">ERROR</A> and
<A HREF = "#warn">WARNING</A> messages LAMMPS prints out and the reason why. If the
explanation here is not sufficient, the documentation for the
offending command may help.
Error and warning messages also list the source file and line number
where the error was generated. For example, this message
</P>
<P>ERROR: Illegal velocity command (velocity.cpp:78)
</P>
<P>means that line #78 in the file src/velocity.cpp generated the error.
Looking in the source code may help you figure out what went wrong.
</P>
<P>Note that error messages from <A HREF = "Section_start.html#start_3">user-contributed
packages</A> are not listed here. If such an
error occurs and is not self-explanatory, you'll need to look in the
source code or contact the author of the package.
</P>
<H4><A NAME = "error"></A>Errors:
</H4>
<DL>
<DT><I>1-3 bond count is inconsistent</I>
<DD>An inconsistency was detected when computing the number of 1-3
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined.
<DT><I>1-4 bond count is inconsistent</I>
<DD>An inconsistency was detected when computing the number of 1-4
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined.
<DT><I>Accelerated style in input script but no fix gpu</I>
<DD>GPU acceleration requires fix gpu in the input script.
+<DT><I>Accelerator sharing is not currently supported on system.</I>
+
+<DD>You cannot use more MPI processes than accelerators on the
+system as currently configured. For NVIDIA GPUs, the compute
+mode must be changed using nvidia-smi to support sharing.
+
<DT><I>All angle coeffs are not set</I>
<DD>All angle coefficients must be set in the data file or by the
angle_coeff command before running a simulation.
<DT><I>All bond coeffs are not set</I>
<DD>All bond coefficients must be set in the data file or by the
bond_coeff command before running a simulation.
<DT><I>All dihedral coeffs are not set</I>
<DD>All dihedral coefficients must be set in the data file or by the
dihedral_coeff command before running a simulation.
<DT><I>All dipole moments are not set</I>
<DD>For atom styles that define dipole moments for each atom type, all
moments must be set in the data file or by the dipole command before
running a simulation.
<DT><I>All improper coeffs are not set</I>
<DD>All improper coefficients must be set in the data file or by the
improper_coeff command before running a simulation.
<DT><I>All masses are not set</I>
<DD>For atom styles that define masses for each atom type, all masses must
be set in the data file or by the mass command before running a
simulation. They must also be set before using the velocity
command.
<DT><I>All pair coeffs are not set</I>
<DD>All pair coefficients must be set in the data file or by the
pair_coeff command before running a simulation.
<DT><I>All shapes are not set</I>
<DD>All atom types must have a shape setting, even if the particles
are spherical.
<DT><I>All universe/uloop variables must have same # of values</I>
<DD>Self-explanatory.
<DT><I>All variables in next command must be same style</I>
<DD>Self-explanatory.
<DT><I>Angle atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
angle on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid angle.
<DT><I>Angle atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular angle on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid angle.
<DT><I>Angle atoms %d %d %d missing on proc %d at step</I>
<DD>One or more of 3 atoms needed to compute a particular angle are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the angle has blown apart and an atom is
too far away.
<DT><I>Angle coeff for hybrid has invalid style</I>
<DD>Angle style hybrid uses another angle style as one of its
coefficients. The angle style used in the angle_coeff command or read
from a restart file is not recognized.
<DT><I>Angle coeffs are not set</I>
<DD>No angle coefficients have been assigned in the data file or via the
angle_coeff command.
<DT><I>Angle potential must be defined for SHAKE</I>
<DD>When shaking angles, an angle_style potential must be used.
<DT><I>Angle style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Angle style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Angle style hybrid cannot use same pair style twice</I>
<DD>Self-explanatory.
<DT><I>Angle table must range from 0 to 180 degrees</I>
<DD>Self-explanatory.
<DT><I>Angle table parameters did not set N</I>
<DD>List of angle table parameters must include N setting.
<DT><I>Angle_coeff command before angle_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the angle_coeff
command until an angle_style has been assigned.
<DT><I>Angle_coeff command before simulation box is defined</I>
<DD>The angle_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Angle_coeff command when no angles allowed</I>
<DD>The chosen atom style does not allow for angles to be defined.
<DT><I>Angle_style command when no angles allowed</I>
<DD>The chosen atom style does not allow for angles to be defined.
<DT><I>Angles assigned incorrectly</I>
<DD>Angles read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Angles defined but no angle types</I>
<DD>The data file header lists angles but no angle types.
<DT><I>Another input script is already being processed</I>
<DD>Cannot attempt to open a 2nd input script, when the original file is
still being processed.
<DT><I>Arccos of invalid value in variable formula</I>
<DD>Argument of arccos() must be between -1 and 1.
<DT><I>Arcsin of invalid value in variable formula</I>
<DD>Argument of arcsin() must be between -1 and 1.
<DT><I>Atom IDs must be consecutive for velocity create loop all</I>
<DD>Self-explanatory.
<DT><I>Atom count changed in fix neb</I>
<DD>This is not allowed in a NEB calculation.
<DT><I>Atom count is inconsistent, cannot write restart file</I>
<DD>Sum of atoms across processors does not equal initial total count.
This is probably because you have lost some atoms.
<DT><I>Atom in too many rigid bodies - boost MAXBODY</I>
<DD>Fix poems has a parameter MAXBODY (in fix_poems.cpp) which determines
the maximum number of rigid bodies a single atom can belong to (i.e. a
multibody joint). The bodies you have defined exceed this limit.
<DT><I>Atom sort did not operate correctly</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Atom sorting has bin size = 0.0</I>
<DD>The neighbor cutoff is being used as the bin size, but it is zero.
Thus you must explicitly list a bin size in the atom_modify sort
command or turn off sorting.
<DT><I>Atom style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Atom style hybrid cannot use same atom style twice</I>
<DD>Self-explanatory.
<DT><I>Atom vector in equal-style variable formula</I>
<DD>Atom vectors generate one value per atom which is not allowed
in an equal-style variable.
<DT><I>Atom-style variable in equal-style variable formula</I>
<DD>Atom-style variables generate one value per atom which is not allowed
in an equal-style variable.
<DT><I>Atom_modify map command after simulation box is defined</I>
<DD>The atom_modify map command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Atom_modify sort and first options cannot be used together</I>
<DD>Self-explanatory.
<DT><I>Atom_style command after simulation box is defined</I>
<DD>The atom_style command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Attempt to pop empty stack in fix box/relax</I>
<DD>Internal LAMMPS error. Please report it to the developers.
<DT><I>Attempt to push beyond stack limit in fix box/relax</I>
<DD>Internal LAMMPS error. Please report it to the developers.
<DT><I>Attempting to rescale a 0.0 temperature</I>
<DD>Cannot rescale a temperature that is already 0.0.
<DT><I>Bad FENE bond</I>
<DD>Two atoms in a FENE bond have become so far apart that the bond cannot
be computed.
<DT><I>Bad TIP4P angle type for PPPM/TIP4P</I>
<DD>Specified angle type is not valid.
<DT><I>Bad TIP4P bond type for PPPM/TIP4P</I>
<DD>Specified bond type is not valid.
<DT><I>Bad grid of processors</I>
<DD>The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on.
<DT><I>Bad kspace_modify slab parameter</I>
<DD>Kspace_modify value for the slab/volume keyword must be >= 2.0.
<DT><I>Bad principal moments</I>
<DD>Fix rigid did not compute the principal moments of inertia of a rigid
group of atoms correctly.
<DT><I>Bias compute does not calculate a velocity bias</I>
<DD>The specified compute must compute a bias for temperature.
<DT><I>Bias compute does not calculate temperature</I>
<DD>The specified compute must compute temperature.
<DT><I>Bias compute group does not match compute group</I>
<DD>The specified compute must operate on the same group as the parent
compute.
<DT><I>Big particle in fix srd cannot be point particle</I>
<DD>Big particles must be extended spheriods or ellipsoids.
<DT><I>Bigint setting in lmptype.h is invalid</I>
<DD>Size of bigint is less than size of tagint.
<DT><I>Bigint setting in lmptype.h is not compatible</I>
<DD>Bigint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Bitmapped lookup tables require int/float be same size</I>
<DD>Cannot use pair tables on this machine, because of word sizes. Use
the pair_modify command with table 0 instead.
<DT><I>Bitmapped table in file does not match requested table</I>
<DD>Setting for bitmapped table in pair_coeff command must match table
in file exactly.
<DT><I>Bitmapped table is incorrect length in table file</I>
<DD>Number of table entries is not a correct power of 2.
<DT><I>Bond and angle potentials must be defined for TIP4P</I>
<DD>Cannot use TIP4P pair potential unless bond and angle potentials
are defined.
<DT><I>Bond atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
bond on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid bond.
<DT><I>Bond atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular bond on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid bond.
<DT><I>Bond atoms %d %d missing on proc %d at step</I>
<DD>One or both of 2 atoms needed to compute a particular bond are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the bond has blown apart and an atom is
too far away.
<DT><I>Bond coeff for hybrid has invalid style</I>
<DD>Bond style hybrid uses another bond style as one of its coefficients.
The bond style used in the bond_coeff command or read from a restart
file is not recognized.
<DT><I>Bond coeffs are not set</I>
<DD>No bond coefficients have been assigned in the data file or via the
bond_coeff command.
<DT><I>Bond potential must be defined for SHAKE</I>
<DD>Cannot use fix shake unless bond potential is defined.
<DT><I>Bond style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Bond style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Bond style hybrid cannot use same pair style twice</I>
<DD>Self-explanatory.
<DT><I>Bond style quartic cannot be used with 3,4-body interactions</I>
<DD>No angle, dihedral, or improper styles can be defined when using
bond style quartic.
<DT><I>Bond style quartic requires special_bonds = 1,1,1</I>
<DD>This is a restriction of the current bond quartic implementation.
<DT><I>Bond table parameters did not set N</I>
<DD>List of bond table parameters must include N setting.
<DT><I>Bond table values are not increasing</I>
<DD>The values in the tabulated file must be monotonically increasing.
<DT><I>Bond_coeff command before bond_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the bond_coeff
command until an bond_style has been assigned.
<DT><I>Bond_coeff command before simulation box is defined</I>
<DD>The bond_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Bond_coeff command when no bonds allowed</I>
<DD>The chosen atom style does not allow for bonds to be defined.
<DT><I>Bond_style command when no bonds allowed</I>
<DD>The chosen atom style does not allow for bonds to be defined.
<DT><I>Bonds assigned incorrectly</I>
<DD>Bonds read in from the data file were not assigned correctly to atoms.
This means there is something invalid about the topology definitions.
<DT><I>Bonds defined but no bond types</I>
<DD>The data file header lists bonds but no bond types.
<DT><I>Both sides of boundary must be periodic</I>
<DD>Cannot specify a boundary as periodic only on the lo or hi side. Must
be periodic on both sides.
<DT><I>Boundary command after simulation box is defined</I>
<DD>The boundary command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Box bounds are invalid</I>
<DD>The box boundaries specified in the read_data file are invalid. The
lo value must be less than the hi value for all 3 dimensions.
<DT><I>Can not specify Pxy/Pxz/Pyz in fix box/relax with non-triclinic box</I>
<DD>Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details.
<DT><I>Can not specify Pxy/Pxz/Pyz in fix nvt/npt/nph with non-triclinic box</I>
<DD>Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details.
<DT><I>Can only use NEB with 1-processor replicas</I>
<DD>This is current restriction for NEB as implemented in LAMMPS.
<DT><I>Can only use TAD with 1-processor replicas for NEB</I>
<DD>This is current restriction for NEB as implemented in LAMMPS.
<DT><I>Cannot (yet) use PPPM with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot add atoms to fix move variable</I>
<DD>Atoms can not be added afterwards to this fix option.
<DT><I>Cannot change box to orthogonal when tilt is non-zero</I>
<DD>Self-explanatory
<DT><I>Cannot change box with certain fixes defined</I>
<DD>The change_box command cannot be used when fix ave/spatial or
fix/deform are defined .
<DT><I>Cannot change box with dumps defined</I>
<DD>Self-explanatory.
<DT><I>Cannot change dump_modify every for dump dcd</I>
<DD>The frequency of writing dump dcd snapshots cannot be changed.
<DT><I>Cannot change dump_modify every for dump xtc</I>
<DD>The frequency of writing dump xtc snapshots cannot be changed.
<DT><I>Cannot change timestep once fix srd is setup</I>
<DD>This is because various SRD properties depend on the timestep
size.
<DT><I>Cannot change timestep with fix pour</I>
<DD>This fix pre-computes some values based on the timestep, so it cannot
be changed during a simulation run.
<DT><I>Cannot compute PPPM G</I>
<DD>LAMMPS failed to compute a valid approximation for the PPPM g_ewald
factor that partitions the computation between real space and k-space.
<DT><I>Cannot create an atom map unless atoms have IDs</I>
<DD>The simulation requires a mapping from global atom IDs to local atoms,
but the atoms that have been defined have no IDs.
<DT><I>Cannot create atoms with undefined lattice</I>
<DD>Must use the lattice command before using the create_atoms
command.
<DT><I>Cannot create/grow a vector/array of pointers for %s</I>
<DD>LAMMPS code is making an illegal call to the templated memory
allocaters, to create a vector or array of pointers.
<DT><I>Cannot create_atoms after reading restart file with per-atom info</I>
<DD>The per-atom info was stored to be used when by a fix that you
may re-define. If you add atoms before re-defining the fix, then
there will not be a correct amount of per-atom info.
<DT><I>Cannot create_box after simulation box is defined</I>
<DD>The create_box command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Cannot currently use pair reax with pair hybrid</I>
<DD>This is not yet supported.
<DT><I>Cannot delete group all</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a compute</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a dump</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a fix</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by atom_modify first</I>
<DD>Self-explanatory.
<DT><I>Cannot displace_atoms after reading restart file with per-atom info</I>
<DD>This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms.
<DT><I>Cannot displace_box after reading restart file with per-atom info</I>
<DD>This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms.
<DT><I>Cannot displace_box on a non-periodic boundary</I>
<DD>Self-explanatory.
<DT><I>Cannot dump sort on atom IDs with no atom IDs defined</I>
<DD>Self-explanatory.
<DT><I>Cannot evaporate atoms in atom_modify first group</I>
<DD>This is a restriction due to the way atoms are organized in
a list to enable the atom_modify first command.
<DT><I>Cannot find delete_bonds group ID</I>
<DD>Group ID used in the delete_bonds command does not exist.
<DT><I>Cannot have both pair_modify shift and tail set to yes</I>
<DD>These 2 options are contradictory.
<DT><I>Cannot open AIREBO potential file %s</I>
<DD>The specified AIREBO potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open COMB potential file %s</I>
<DD>The specified COMB potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open EAM potential file %s</I>
<DD>The specified EAM potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open EIM potential file %s</I>
<DD>The specified EIM potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open MEAM potential file %s</I>
<DD>The specified MEAM potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open Stillinger-Weber potential file %s</I>
<DD>The specified SW potential file cannot be opened. Check that the path
and name are correct.
<DT><I>Cannot open Tersoff potential file %s</I>
<DD>The specified Tersoff potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open dir to search for restart file</I>
<DD>Using a "*" in the name of the restart file will open the current
directory to search for matching file names.
<DT><I>Cannot open dump file</I>
<DD>The output file for the dump command cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/correlate file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/histo file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/spatial file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/time file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix poems file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix print file %s</I>
<DD>The output file generated by the fix print command cannot be opened
<DT><I>Cannot open fix qeq/comb file %s</I>
<DD>The output file for the fix qeq/combs command cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open fix reax/bonds file %s</I>
<DD>The output file for the fix reax/bonds command cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open fix tmd file %s</I>
<DD>The output file for the fix tmd command cannot be opened. Check that
the path and name are correct.
<DT><I>Cannot open fix ttm file %s</I>
<DD>The output file for the fix ttm command cannot be opened. Check that
the path and name are correct.
<DT><I>Cannot open gzipped file</I>
<DD>LAMMPS is attempting to open a gzipped version of the specified file
but was unsuccessful. Check that the path and name are correct.
<DT><I>Cannot open input script %s</I>
<DD>Self-explanatory.
<DT><I>Cannot open log.lammps</I>
<DD>The default LAMMPS log file cannot be opened. Check that the
directory you are running in allows for files to be created.
<DT><I>Cannot open logfile %s</I>
<DD>The LAMMPS log file specified in the input script cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open logfile</I>
<DD>The LAMMPS log file named in a command-line argument cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open pair_write file</I>
<DD>The specified output file for pair energies and forces cannot be
opened. Check that the path and name are correct.
<DT><I>Cannot open restart file %s</I>
<DD>Self-explanatory.
<DT><I>Cannot open screen file</I>
<DD>The screen file specified as a command-line argument cannot be
opened. Check that the directory you are running in allows for files
to be created.
<DT><I>Cannot open universe log file</I>
<DD>For a multi-partition run, the master log file cannot be opened.
Check that the directory you are running in allows for files to be
created.
<DT><I>Cannot open universe screen file</I>
<DD>For a multi-partition run, the master screen file cannot be opened.
Check that the directory you are running in allows for files to be
created.
<DT><I>Cannot read_data after simulation box is defined</I>
<DD>The read_data command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Cannot read_restart after simulation box is defined</I>
<DD>The read_restart command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Cannot redefine variable as a different style</I>
<DD>An equal-style variable can be re-defined but only if it was
originally an equal-style variable.
<DT><I>Cannot replicate 2d simulation in z dimension</I>
<DD>The replicate command cannot replicate a 2d simulation in the z
dimension.
<DT><I>Cannot replicate with fixes that store atom quantities</I>
<DD>Either fixes are defined that create and store atom-based vectors or a
restart file was read which included atom-based vectors for fixes.
The replicate command cannot duplicate that information for new atoms.
You should use the replicate command before fixes are applied to the
system.
<DT><I>Cannot reset timestep with a dynamic region defined</I>
<DD>Dynamic regions (see the region command) have a time dependence.
Thus you cannot change the timestep when one or more of these
are defined.
<DT><I>Cannot reset timestep with a time-dependent fix defined</I>
<DD>You cannot reset the timestep when a fix that keeps track of elapsed
time is in place.
<DT><I>Cannot reset timestep with dump file already written to</I>
<DD>Changing the timestep will confuse when a dump file is written. Use
the undump command, then restart the dump file.
<DT><I>Cannot reset timestep with restart file already written</I>
<DD>Changing the timestep will confuse when a restart file is written.
Use the "restart 0" command to turn off restarts, then start them
again.
<DT><I>Cannot restart fix rigid/nvt with different # of chains</I>
<DD>This is because the restart file contains per-chain info.
<DT><I>Cannot run 2d simulation with nonperiodic Z dimension</I>
<DD>Use the boundary command to make the z dimension periodic in order to
run a 2d simulation.
<DT><I>Cannot set both respa pair and inner/middle/outer</I>
<DD>In the rRESPA integrator, you must compute pairwise potentials either
all together (pair), or in pieces (inner/middle/outer). You can't do
both.
<DT><I>Cannot set dipole for this atom style</I>
<DD>This atom style does not support dipole settings for each atom type.
<DT><I>Cannot set dump_modify flush for dump xtc</I>
<DD>Self-explanatory.
<DT><I>Cannot set mass for this atom style</I>
<DD>This atom style does not support mass settings for each atom type.
Instead they are defined on a per-atom basis in the data file.
<DT><I>Cannot set non-zero image flag for non-periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot set non-zero z velocity for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot set respa middle without inner/outer</I>
<DD>In the rRESPA integrator, you must define both a inner and outer
setting in order to use a middle setting.
<DT><I>Cannot set shape for this atom style</I>
<DD>The atom style does not support this setting.
<DT><I>Cannot set this attribute for this atom style</I>
<DD>The attribute being set does not exist for the defined atom style.
<DT><I>Cannot set variable z velocity for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot skew triclinic box in z for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use Ewald with 2d simulation</I>
<DD>The kspace style ewald cannot be used in 2d simulations. You can use
2d Ewald in a 3d simulation; see the kspace_modify command.
<DT><I>Cannot use Ewald with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot use NEB unless atom map exists</I>
<DD>Use the atom_modify command to create an atom map.
<DT><I>Cannot use NEB with a single replica</I>
<DD>Self-explanatory.
<DT><I>Cannot use NEB with atom_modify sort enabled</I>
<DD>This is current restriction for NEB implemented in LAMMPS.
<DT><I>Cannot use PPPM with 2d simulation</I>
<DD>The kspace style pppm cannot be used in 2d simulations. You can use
2d PPPM in a 3d simulation; see the kspace_modify command.
<DT><I>Cannot use PRD with a time-dependent fix defined</I>
<DD>PRD alters the timestep in ways that will mess up these fixes.
<DT><I>Cannot use PRD with a time-dependent region defined</I>
<DD>PRD alters the timestep in ways that will mess up these regions.
<DT><I>Cannot use PRD with atom_modify sort enabled</I>
<DD>This is a current restriction of PRD. You must turn off sorting,
which is enabled by default, via the atom_modify command.
<DT><I>Cannot use PRD with multi-processor replicas unless atom map exists</I>
<DD>Use the atom_modify command to create an atom map.
<DT><I>Cannot use TAD unless atom map exists for NEB</I>
<DD>See atom_modify map command to set this.
<DT><I>Cannot use TAD with a single replica for NEB</I>
<DD>NEB requires multiple replicas.
<DT><I>Cannot use TAD with atom_modify sort enabled for NEB</I>
<DD>This is a current restriction of NEB.
<DT><I>Cannot use a damped dynamics min style with fix box/relax</I>
<DD>This is a current restriction in LAMMPS. Use another minimizer
style.
<DT><I>Cannot use a damped dynamics min style with per-atom DOF</I>
<DD>This is a current restriction in LAMMPS. Use another minimizer
style.
<DT><I>Cannot use compute cluster/atom unless atoms have IDs</I>
<DD>Atom IDs are used to identify clusters.
<DT><I>Cannot use cwiggle in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use delete_atoms unless atoms have IDs</I>
<DD>Your atoms do not have IDs, so the delete_atoms command cannot be
used.
<DT><I>Cannot use delete_bonds with non-molecular system</I>
<DD>Your choice of atom style does not have bonds.
<DT><I>Cannot use fix TMD unless atom map exists</I>
<DD>Using this fix requires the ability to lookup an atom index, which is
provided by an atom map. An atom map does not exist (by default) for
non-molecular problems. Using the atom_modify map command will force
an atom map to be created.
<DT><I>Cannot use fix ave/spatial z for 2 dimensional model</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix bond/break with non-molecular systems</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix bond/create with non-molecular systems</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix box/relax on a 2nd non-periodic dimension</I>
<DD>When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic.
<DT><I>Cannot use fix box/relax on a non-periodic dimension</I>
<DD>When specifying a diagonal pressure component, the dimension must be
periodic.
<DT><I>Cannot use fix deform on a 2nd non-periodic boundary</I>
<DD>When specifying a tilt factor change, the 2nd of the two dimensions
must be periodic. E.g. if the xy tilt is specified, then the y
dimension must be periodic.
<DT><I>Cannot use fix deform on a non-periodic boundary</I>
<DD>When specifying a change is a box dimension, the dimension must be
periodic.
<DT><I>Cannot use fix deform trate on a box with zero tilt</I>
<DD>The trate style alters the current strain.
<DT><I>Cannot use fix enforce2d with 3d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix msst without per-type mass defined</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix npt and fix deform on same component of stress tensor</I>
<DD>This would be changing the same box dimension twice.
<DT><I>Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension</I>
<DD>When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic.
<DT><I>Cannot use fix nvt/npt/nph on a non-periodic dimension</I>
<DD>When specifying a diagonal pressure component, the dimension must be
periodic.
<DT><I>Cannot use fix pour with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot use fix press/berendsen and fix deform on same component of stress tensor</I>
<DD>These commands both change the box size/shape, so you cannot use both
together.
<DT><I>Cannot use fix press/berendsen on a non-periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix press/berendsen with triclinic box</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix reax/bonds without pair_style reax</I>
<DD>Self-explantory.
<DT><I>Cannot use fix shake with non-molecular system</I>
<DD>Your choice of atom style does not have bonds.
<DT><I>Cannot use fix ttm with 2d simulation</I>
<DD>This is a current restriction of this fix due to the grid it creates.
<DT><I>Cannot use fix ttm with triclinic box</I>
<DD>This is a current restriction of this fix due to the grid it creates.
<DT><I>Cannot use fix wall in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/reflect in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/reflect zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd more than once</I>
<DD>Nor is their a need to since multiple walls can be specified
in one command.
<DT><I>Cannot use fix wall/srd without fix srd</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use force/neigh with triclinic box</I>
<DD>This is a current limitation of the GPU implementation
in LAMMPS.
<DT><I>Cannot use kspace solver on system with no charge</I>
<DD>No atoms in system have a non-zero charge.
+<DT><I>Cannot use neigh_modify exclude with GPU neighbor builds</I>
+
+<DD>This is a current limitation of the GPU implementation
+in LAMMPS.
+
<DT><I>Cannot use neighbor bins - box size << cutoff</I>
<DD>Too many neighbor bins will be created. This typically happens when
the simulation box is very small in some dimension, compared to the
neighbor cutoff. Use the "nsq" style instead of "bin" style.
<DT><I>Cannot use newton pair with GPU CHARMM pair style</I>
<DD>See the newton command to change the setting.
<DT><I>Cannot use newton pair with GPU Gay-Berne pair style</I>
<DD>See the newton command to change the setting.
<DT><I>Cannot use newton pair with GPU LJ pair style</I>
<DD>See the newton command to change the setting.
<DT><I>Cannot use newton pair with GPU LJ96 pair style</I>
<DD>See the newton command to change the setting.
<DT><I>Cannot use non-zero forces in an energy minimization</I>
<DD>Fix setforce cannot be used in this manner. Use fix addforce
instead.
<DT><I>Cannot use nonperiodic boundares with fix ttm</I>
<DD>This fix requires a fully periodic simulation box.
<DT><I>Cannot use nonperiodic boundaries with Ewald</I>
<DD>For kspace style ewald, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
<DT><I>Cannot use nonperiodic boundaries with PPPM</I>
<DD>For kspace style pppm, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
<DT><I>Cannot use pair hybrid with GPU neighbor builds</I>
<DD>See documentation for fix gpu.
<DT><I>Cannot use pair tail corrections with 2d simulations</I>
<DD>The correction factors are only currently defined for 3d systems.
<DT><I>Cannot use ramp in variable formula between runs</I>
<DD>This is because the ramp() function is time dependent.
<DT><I>Cannot use region INF or EDGE when box does not exist</I>
<DD>Regions that extend to the box boundaries can only be used after the
create_box command has been used.
<DT><I>Cannot use set atom with no atom IDs defined</I>
<DD>Atom IDs are not defined, so they cannot be used to identify an atom.
<DT><I>Cannot use swiggle in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use variable energy with constant force in fix addforce</I>
<DD>This is because for constant force, LAMMPS can compute the change
in energy directly.
<DT><I>Cannot use variable every setting for dump dcd</I>
<DD>The format of DCD dump files requires snapshots be output
at a constant frequency.
<DT><I>Cannot use variable every setting for dump xtc</I>
<DD>The format of this file requires snapshots at regular intervals.
<DT><I>Cannot use vdisplace in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use velocity create loop all unless atoms have IDs</I>
<DD>Atoms in the simulation to do not have IDs, so this style
of velocity creation cannot be performed.
<DT><I>Cannot use wall in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot wiggle and shear fix wall/gran</I>
<DD>Cannot specify both options at the same time.
<DT><I>Cannot zero momentum of 0 atoms</I>
<DD>The collection of atoms for which momentum is being computed has no
atoms.
<DT><I>Change_box command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Change_box operation is invalid</I>
<DD>Cannot change orthogonal box to orthogonal or a triclinic box to
triclinic.
<DT><I>Communicate group != atom_modify first group</I>
<DD>Self-explanatory.
<DT><I>Compute ID for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix store/state does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Compute angle/local used when angles are not allowed</I>
<DD>The atom style does not support angles.
<DT><I>Compute atom/molecule compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Compute bond/local used when bonds are not allowed</I>
<DD>The atom style does not support bonds.
<DT><I>Compute centro/atom requires a pair style be defined</I>
<DD>This is because the computation of the centro-symmetry values
uses a pairwise neighbor list.
<DT><I>Compute cluster/atom cutoff is longer than pairwise cutoff</I>
<DD>Cannot identify clusters beyond cutoff.
<DT><I>Compute cluster/atom requires a pair style be defined</I>
<DD>This is so that the pair style defines a cutoff distance which
is used to find clusters.
<DT><I>Compute cna/atom cutoff is longer than pairwise cutoff</I>
<DD>Self-explantory.
<DT><I>Compute cna/atom requires a pair style be defined</I>
<DD>Self-explantory.
<DT><I>Compute com/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute coord/atom cutoff is longer than pairwise cutoff</I>
<DD>Cannot compute coordination at distances longer than the pair cutoff,
since those atoms are not in the neighbor list.
<DT><I>Compute coord/atom requires a pair style be defined</I>
<DD>Self-explantory.
<DT><I>Compute damage/atom requires peridynamic potential</I>
<DD>Damage is a Peridynamic-specific metric. It requires you
to be running a Peridynamics simulation.
<DT><I>Compute dihedral/local used when dihedrals are not allowed</I>
<DD>The atom style does not support dihedrals.
<DT><I>Compute does not allow an extra compute or fix to be reset</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Compute erotate/asphere cannot be used with atom attributes diameter or rmass</I>
<DD>These attributes override the shape and mass settings, so cannot be
used.
<DT><I>Compute erotate/asphere requires atom attributes angmom, quat, shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Compute erotate/asphere requires extended particles</I>
<DD>This compute cannot be used with point paritlces.
<DT><I>Compute erotate/sphere requires atom attribute omega</I>
<DD>An atom style that defines this attribute must be used.
<DT><I>Compute erotate/sphere requires atom attribute radius or shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Compute erotate/sphere requires spherical particle shapes</I>
<DD>Self-explanatory.
<DT><I>Compute event/displace has invalid fix event assigned</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Compute group/group group ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute gyration/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute ke/atom</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute pe/atom</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute stress/atom</I>
<DD>Self-explanatory.
<DT><I>Compute improper/local used when impropers are not allowed</I>
<DD>The atom style does not support impropers.
<DT><I>Compute msd/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute pair must use group all</I>
<DD>Pair styles accumlate energy on all atoms.
<DT><I>Compute pe must use group all</I>
<DD>Energies computed by potentials (pair, bond, etc) are computed on all
atoms.
<DT><I>Compute pressure must use group all</I>
<DD>Virial contributions computed by potentials (pair, bond, etc) are
computed on all atoms.
<DT><I>Compute pressure temperature ID does not compute temperature</I>
<DD>The compute ID assigned to a pressure computation must compute
temperature.
<DT><I>Compute property/atom for atom property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Compute property/local cannot use these inputs together</I>
<DD>Only inputs that generate the same number of datums can be used
togther. E.g. bond and angle quantities cannot be mixed.
<DT><I>Compute property/local for property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Compute property/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute rdf requires a pair style be defined</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute calculates global values</I>
<DD>A compute that calculates peratom or local values is required.
<DT><I>Compute reduce compute does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix calculates global values</I>
<DD>A fix that calculates peratom or local values is required.
<DT><I>Compute reduce fix does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce replace requires min or max mode</I>
<DD>Self-explanatory.
<DT><I>Compute reduce variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Compute temp/asphere cannot be used with atom attributes diameter or rmass</I>
<DD>These attributes override the shape and mass settings, so cannot be
used.
<DT><I>Compute temp/asphere requires atom attributes angmom, quat, shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Compute temp/asphere requires extended particles</I>
<DD>This compute cannot be used with point paritlces.
<DT><I>Compute temp/partial cannot use vz for 2d systemx</I>
<DD>Self-explanatory.
<DT><I>Compute temp/profile cannot bin z for 2d systems</I>
<DD>Self-explanatory.
<DT><I>Compute temp/profile cannot use vz for 2d systemx</I>
<DD>Self-explanatory.
<DT><I>Compute temp/sphere requires atom attribute omega</I>
<DD>An atom style that defines this attribute must be used.
<DT><I>Compute temp/sphere requires atom attribute radius or shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Compute temp/sphere requires spherical particle shapes</I>
<DD>Self-explanatory.
<DT><I>Compute ti kspace style does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ti pair style does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ti tail when pair style does not compute tail corrections</I>
<DD>Self-explanatory.
<DT><I>Compute used in variable between runs is not current</I>
<DD>Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info.
<DT><I>Compute used in variable thermo keyword between runs is not current</I>
<DD>Some thermo keywords rely on a compute to calculate their value(s).
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info.
<DT><I>Computed temperature for fix temp/berendsen cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Computed temperature for fix temp/rescale cannot be 0.0</I>
<DD>Cannot rescale the temperature to a new value if the current
temperature is 0.0.
<DT><I>Could not count initial bonds in fix bond/create</I>
<DD>Could not find one of the atoms in a bond on this processor.
<DT><I>Could not create 3d FFT plan</I>
<DD>The FFT setup in pppm failed.
<DT><I>Could not create 3d remap plan</I>
<DD>The FFT setup in pppm failed.
<DT><I>Could not find atom_modify first group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID for PRD</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID for TAD</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID for temperature bias</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID to delete</I>
<DD>Self-explanatory.
<DT><I>Could not find compute displace/atom fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute event/displace fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute heat/flux compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute msd fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute pressure temperature ID</I>
<DD>The compute ID for calculating temperature does not exist.
<DT><I>Could not find compute_modify ID</I>
<DD>Self-explanatory.
<DT><I>Could not find delete_atoms group ID</I>
<DD>Group ID used in the delete_atoms command does not exist.
<DT><I>Could not find delete_atoms region ID</I>
<DD>Region ID used in the delete_atoms command does not exist.
<DT><I>Could not find displace_atoms group ID</I>
<DD>Group ID used in the displace_atoms command does not exist.
<DT><I>Could not find displace_box group ID</I>
<DD>Group ID used in the displace_box command does not exist.
<DT><I>Could not find dump cfg compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump cfg fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump cfg variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find dump custom compute ID</I>
<DD>The compute ID needed by dump custom to compute a per-atom quantity
does not exist.
<DT><I>Could not find dump custom fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump custom variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find dump group ID</I>
<DD>A group ID used in the dump command does not exist.
<DT><I>Could not find dump local compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump local fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find fix ID to delete</I>
<DD>Self-explanatory.
<DT><I>Could not find fix group ID</I>
<DD>A group ID used in the fix command does not exist.
<DT><I>Could not find fix msst compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find fix poems group ID</I>
<DD>A group ID used in the fix poems command does not exist.
<DT><I>Could not find fix recenter group ID</I>
<DD>A group ID used in the fix recenter command does not exist.
<DT><I>Could not find fix rigid group ID</I>
<DD>A group ID used in the fix rigid command does not exist.
<DT><I>Could not find fix srd group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find fix_modify ID</I>
<DD>A fix ID used in the fix_modify command does not exist.
<DT><I>Could not find fix_modify pressure ID</I>
<DD>The compute ID for computing pressure does not exist.
<DT><I>Could not find fix_modify temperature ID</I>
<DD>The compute ID for computing temperature does not exist.
<DT><I>Could not find group delete group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find/initialize a specified accelerator device</I>
<DD>Your GPU setup is invalid.
<DT><I>Could not find set group ID</I>
<DD>Group ID specified in set command does not exist.
<DT><I>Could not find thermo compute ID</I>
<DD>Compute ID specified in thermo_style command does not exist.
<DT><I>Could not find thermo custom compute ID</I>
<DD>The compute ID needed by thermo style custom to compute a requested
quantity does not exist.
<DT><I>Could not find thermo custom fix ID</I>
<DD>The fix ID needed by thermo style custom to compute a requested
quantity does not exist.
<DT><I>Could not find thermo custom variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find thermo fix ID</I>
<DD>Fix ID specified in thermo_style command does not exist.
<DT><I>Could not find thermo_modify pressure ID</I>
<DD>The compute ID needed by thermo style custom to compute pressure does
not exist.
<DT><I>Could not find thermo_modify temperature ID</I>
<DD>The compute ID needed by thermo style custom to compute temperature does
not exist.
<DT><I>Could not find undump ID</I>
<DD>A dump ID used in the undump command does not exist.
<DT><I>Could not find velocity group ID</I>
<DD>A group ID used in the velocity command does not exist.
<DT><I>Could not find velocity temperature ID</I>
<DD>The compute ID needed by the velocity command to compute temperature
does not exist.
<DT><I>Could not grab element entry from EIM potential file</I>
<DD>Self-explanatory
<DT><I>Could not grab global entry from EIM potential file</I>
<DD>Self-explanatory.
<DT><I>Could not grab pair entry from EIM potential file</I>
<DD>Self-explanatory.
<DT><I>Could not set finite-size particle attribute in fix rigid</I>
<DD>The particle has a finite size but its attributes could not be
determined.
<DT><I>Coulomb cutoffs of pair hybrid sub-styles do not match</I>
<DD>If using a Kspace solver, all Coulomb cutoffs of long pair styles must
be the same.
<DT><I>Cound not find dump_modify ID</I>
<DD>Self-explanatory.
<DT><I>Create_atoms command before simulation box is defined</I>
<DD>The create_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Create_atoms region ID does not exist</I>
<DD>A region ID used in the create_atoms command does not exist.
<DT><I>Create_box region ID does not exist</I>
<DD>A region ID used in the create_box command does not exist.
<DT><I>Create_box region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the create_box command.
<DT><I>Cyclic loop in joint connections</I>
<DD>Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a ring (or cycle).
<DT><I>Degenerate lattice primitive vectors</I>
<DD>Invalid set of 3 lattice vectors for lattice command.
<DT><I>Delete region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Delete_atoms command before simulation box is defined</I>
<DD>The delete_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Delete_atoms cutoff > neighbor cutoff</I>
<DD>Cannot delete atoms further away than a processor knows about.
<DT><I>Delete_atoms requires a pair style be defined</I>
<DD>This is because atom deletion within a cutoff uses a pairwise
neighbor list.
<DT><I>Delete_bonds command before simulation box is defined</I>
<DD>The delete_bonds command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Delete_bonds command with no atoms existing</I>
<DD>No atoms are yet defined so the delete_bonds command cannot be used.
<DT><I>Deposition region extends outside simulation box</I>
<DD>Self-explanatory.
<DT><I>Did not assign all atoms correctly</I>
<DD>Atoms read in from a data file were not assigned correctly to
processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box.
<DT><I>Did not find all elements in MEAM library file</I>
<DD>The requested elements were not found in the MEAM file.
<DT><I>Did not find fix shake partner info</I>
<DD>Could not find bond partners implied by fix shake command. This error
can be triggered if the delete_bonds command was used before fix
shake, and it removed bonds without resetting the 1-2, 1-3, 1-4
weighting list via the special keyword.
<DT><I>Did not find keyword in table file</I>
<DD>Keyword used in pair_coeff command was not found in table file.
<DT><I>Did not set temp for fix rigid/nvt</I>
<DD>The temp keyword must be used.
<DT><I>Dihedral atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
dihedral on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid dihedral.
<DT><I>Dihedral atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular dihedral
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid dihedral.
<DT><I>Dihedral atoms %d %d %d %d missing on proc %d at step</I>
<DD>One or more of 4 atoms needed to compute a particular dihedral are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the dihedral has blown apart and an atom is
too far away.
<DT><I>Dihedral charmm is incompatible with Pair style</I>
<DD>Dihedral style charmm must be used with a pair style charmm
in order for the 1-4 epsilon/sigma parameters to be defined.
<DT><I>Dihedral coeff for hybrid has invalid style</I>
<DD>Dihedral style hybrid uses another dihedral style as one of its
coefficients. The dihedral style used in the dihedral_coeff command
or read from a restart file is not recognized.
<DT><I>Dihedral coeffs are not set</I>
<DD>No dihedral coefficients have been assigned in the data file or via
the dihedral_coeff command.
<DT><I>Dihedral style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Dihedral style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Dihedral style hybrid cannot use same dihedral style twice</I>
<DD>Self-explanatory.
<DT><I>Dihedral_coeff command before dihedral_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the dihedral_coeff
command until an dihedral_style has been assigned.
<DT><I>Dihedral_coeff command before simulation box is defined</I>
<DD>The dihedral_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Dihedral_coeff command when no dihedrals allowed</I>
<DD>The chosen atom style does not allow for dihedrals to be defined.
<DT><I>Dihedral_style command when no dihedrals allowed</I>
<DD>The chosen atom style does not allow for dihedrals to be defined.
<DT><I>Dihedrals assigned incorrectly</I>
<DD>Dihedrals read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Dihedrals defined but no dihedral types</I>
<DD>The data file header lists dihedrals but no dihedral types.
<DT><I>Dimension command after simulation box is defined</I>
<DD>The dimension command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Dipole command before simulation box is defined</I>
<DD>The dipole command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Displace_atoms command before simulation box is defined</I>
<DD>The displace_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Displace_box command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Displace_box tilt factors require triclinic box</I>
<DD>Cannot use tilt factors unless the simulation box is
non-orthogonal.
<DT><I>Distance must be > 0 for compute event/displace</I>
<DD>Self-explanatory.
<DT><I>Divide by 0 in influence function of pair peri/lps</I>
<DD>This should not normally occur. It is likely a problem with your
model.
<DT><I>Divide by 0 in variable formula</I>
<DD>Self-explanatory.
<DT><I>Domain too large for neighbor bins</I>
<DD>The domain has become extremely large so that neighbor bins cannot be
used. Most likely, one or more atoms have been blown out of the
simulation box to a great distance.
<DT><I>Double precision is not supported on this accelerator.</I>
<DD>In this case, you must compile the GPU library for single precision.
<DT><I>Dump cfg and fix not computed at compatible times</I>
<DD>The fix must produce per-atom quantities on timesteps that dump cfg
needs them.
<DT><I>Dump cfg arguments must start with 'id type xs ys zs'</I>
<DD>This is a requirement of the CFG output format.
<DT><I>Dump cfg requires one snapshot per file</I>
<DD>Use the wildcard "*" character in the filename.
<DT><I>Dump custom and fix not computed at compatible times</I>
<DD>The fix must produce per-atom quantities on timesteps that dump custom
needs them.
<DT><I>Dump custom compute does not calculate per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute does not calculate per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump custom variable is not atom-style variable</I>
<DD>Only atom-style variables generate per-atom quantities, needed for
dump output.
<DT><I>Dump dcd of non-matching # of atoms</I>
<DD>Every snapshot written by dump dcd must contain the same # of atoms.
<DT><I>Dump dcd requires sorting by atom ID</I>
<DD>Use the dump_modify sort command to enable this.
<DT><I>Dump every variable returned a bad timestep</I>
<DD>The variable must return a timestep greater than the current timestep.
<DT><I>Dump local and fix not computed at compatible times</I>
<DD>The fix must produce per-atom quantities on timesteps that dump local
needs them.
<DT><I>Dump local attributes contain no compute or fix</I>
<DD>Self-explanatory.
<DT><I>Dump local cannot sort by atom ID</I>
<DD>This is because dump local does not really dump per-atom info.
<DT><I>Dump local compute does not calculate local array</I>
<DD>Self-explanatory.
<DT><I>Dump local compute does not calculate local vector</I>
<DD>Self-explanatory.
<DT><I>Dump local compute does not compute local info</I>
<DD>Self-explanatory.
<DT><I>Dump local compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump local count is not consistent across input fields</I>
<DD>Every column of output must be the same length.
<DT><I>Dump local fix does not compute local array</I>
<DD>Self-explanatory.
<DT><I>Dump local fix does not compute local info</I>
<DD>Self-explanatory.
<DT><I>Dump local fix does not compute local vector</I>
<DD>Self-explanatory.
<DT><I>Dump local fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID vector is not large enough</I>
<DD>Self-explanatory.
<DT><I>Dump modify element names do not match atom types</I>
<DD>Number of element names must equal number of atom types.
<DT><I>Dump modify fix ID does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID vector is not large enough</I>
<DD>Self-explanatory.
<DT><I>Dump modify variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Dump sort column is invalid</I>
<DD>Self-explanatory.
<DT><I>Dump xtc requires sorting by atom ID</I>
<DD>Use the dump_modify sort command to enable this.
<DT><I>Dump_modify region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Dumping an atom property that isn't allocated</I>
<DD>The chosen atom style does not define the per-atom quantity being
dumped.
<DT><I>Dumping an atom quantity that isn't allocated</I>
<DD>Only per-atom quantities that are defined for the atom style being
used are allowed.
<DT><I>Duplicate particle in PeriDynamic bond - simulation box is too small</I>
<DD>This is likely because your box length is shorter than 2 times
the bond length.
<DT><I>Electronic temperature dropped below zero</I>
<DD>Something has gone wrong with the fix ttm electron temperature model.
<DT><I>Empty brackets in variable</I>
<DD>There is no variable syntax that uses empty brackets. Check
the variable doc page.
<DT><I>Energy was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Expected floating point parameter in input script or data file</I>
<DD>The quantity being read is an integer on non-numeric value.
<DT><I>Expected floating point parameter in variable definition</I>
<DD>The quantity being read is a non-numeric value.
<DT><I>Expected integer parameter in input script or data file</I>
<DD>The quantity being read is a floating point or non-numeric value.
<DT><I>Expected integer parameter in variable definition</I>
<DD>The quantity being read is a floating point or non-numeric value.
<DT><I>Failed to allocate %d bytes for array %s</I>
<DD>Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors.
<DT><I>Failed to reallocate %d bytes for array %s</I>
<DD>Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors.
<DT><I>Fewer SRD bins than processors in some dimension</I>
<DD>This is not allowed. Make your SRD bin size smaller.
<DT><I>Final box dimension due to fix deform is < 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix gpu split must be positive for hybrid pair styles.</I>
<DD>See documentation for fix gpu.
<DT><I>Fix ID for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix store/state does not exist</I>
<DD>Self-explanatory
<DT><I>Fix ID must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Fix SRD cannot have both atom attributes angmom and omega</I>
<DD>Use either spheroid solute particles or fully generalized
aspherical solute particles.
<DT><I>Fix SRD no-slip requires atom attribute torque</I>
<DD>This is because the SRD collisions will impart torque to the solute
particles.
<DT><I>Fix SRD requires atom attribute angmom or omega</I>
<DD>This is because the SRD collisions with cause the solute particles to
rotate.
<DT><I>Fix SRD requires atom attribute radius or shape</I>
<DD>This is because the solute particles must be finite-size particles,
not point particles.
<DT><I>Fix SRD: bad bin assignment for SRD advection</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: bad search bin assignment</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: bad stencil bin for big particle</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: too many big particles in bin</I>
<DD>Reset the ATOMPERBIN parameter at the top of fix_srd.cpp
to a larger value, and re-compile the code.
<DT><I>Fix SRD: too many walls in bin</I>
<DD>This should not happen unless your system has been setup incorrectly.
<DT><I>Fix adapt kspace style does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix adapt pair style does not exist</I>
<DD>Self-explanatory
<DT><I>Fix adapt pair style param not supported</I>
<DD>The pair style does not know about the parameter you specified.
<DT><I>Fix adapt requires atom attribute diameter</I>
<DD>The atom style being used does not specify an atom diameter.
<DT><I>Fix adapt type pair range is not valid for pair hybrid sub-style</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute does not calculate a per-atom vector</I>
<DD>A compute used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom compute does not calculate per-atom values</I>
<DD>A compute used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom fix does not calculate a per-atom vector</I>
<DD>A fix used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom fix does not calculate per-atom values</I>
<DD>A fix used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom variable is not atom-style variable</I>
<DD>A variable used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/histo cannot input local values in scalar mode</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo cannot input per-atom values in scalar mode</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate local values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate local values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid compute</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid fix</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid variable</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo inputs are not all global, peratom, or local</I>
<DD>All inputs in a single fix ave/histo command must be of the
same style.
<DT><I>Fix ave/spatial compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/spatial compute does not calculate a per-atom vector</I>
<DD>A compute used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial compute does not calculate per-atom values</I>
<DD>A compute used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/spatial fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/spatial fix does not calculate a per-atom vector</I>
<DD>A fix used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial fix does not calculate per-atom values</I>
<DD>A fix used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/spatial for triclinic boxes requires units reduced</I>
<DD>Self-explanatory.
<DT><I>Fix ave/spatial settings invalid with changing box</I>
<DD>If the ave setting is "running" or "window" and the box size/shape
changes during the simulation, then the units setting must be
"reduced", else the number of bins may change.
<DT><I>Fix ave/spatial variable is not atom-style variable</I>
<DD>A variable used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/time cannot set output array intensive/extensive from these inputs</I>
<DD>One of more of the vector inputs has individual elements which are
flagged as intensive or extensive. Such an input cannot be flagged as
all intensive/extensive when turned into an array by fix ave/time.
<DT><I>Fix ave/time cannot use variable with vector mode</I>
<DD>Variables produce scalar values.
<DT><I>Fix ave/time columns are inconsistent lengths</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time compute does not calculate a scalar</I>
<DD>Only computes that calculate a scalar or vector quantity (not a
per-atom quantity) can be used with fix ave/time.
<DT><I>Fix ave/time compute does not calculate a vector</I>
<DD>Only computes that calculate a scalar or vector quantity (not a
per-atom quantity) can be used with fix ave/time.
<DT><I>Fix ave/time compute does not calculate an array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/time fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time fix does not calculate a scalar</I>
<DD>A fix used by fix ave/time must generate global values.
<DT><I>Fix ave/time fix does not calculate a vector</I>
<DD>A fix used by fix ave/time must generate global values.
<DT><I>Fix ave/time fix does not calculate an array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/time variable is not equal-style variable</I>
<DD>A variable used by fix ave/time must generate a global value.
<DT><I>Fix bond/break requires special_bonds = 0,1,1</I>
<DD>This is a restriction of the current fix bond/break implementation.
<DT><I>Fix bond/create cutoff is longer than pairwise cutoff</I>
<DD>This is not allowed because bond creation is done using the
pairwise neighbor list.
<DT><I>Fix bond/create requires special_bonds coul = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix bond/create requires special_bonds lj = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix bond/swap cannot use dihedral or improper styles</I>
<DD>These styles cannot be defined when using this fix.
<DT><I>Fix bond/swap requires pair and bond styles</I>
<DD>Self-explanatory.
<DT><I>Fix bond/swap requires special_bonds = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix box/relax generated negative box length</I>
<DD>The pressure being applied is likely too large. Try applying
it incrementally, to build to the high pressure.
<DT><I>Fix command before simulation box is defined</I>
<DD>The fix command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Fix deform is changing yz by too much with changing xy</I>
<DD>When both yz and xy are changing, it induces changes in xz if the
box must flip from one tilt extreme to another. Thus it is not
allowed for yz to grow so much that a flip is induced.
<DT><I>Fix deform tilt factors require triclinic box</I>
<DD>Cannot deform the tilt factors of a simulation box unless it
is a triclinic (non-orthogonal) box.
<DT><I>Fix deform volume setting is invalid</I>
<DD>Cannot use volume style unless other dimensions are being controlled.
<DT><I>Fix deposit region cannot be dynamic</I>
<DD>Only static regions can be used with fix deposit.
<DT><I>Fix deposit region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the fix deposit command.
<DT><I>Fix efield requires atom attribute q</I>
<DD>Self-explanatory.
<DT><I>Fix evaporate molecule requires atom attribute molecule</I>
<DD>The atom style being used does not define a molecule ID.
<DT><I>Fix external callback function not set</I>
<DD>This must be done by an external program in order to use this fix.
<DT><I>Fix for fix ave/atom not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/atom is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/correlate not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/correlate
is requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/histo not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/histo is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/spatial not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/spatial is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/time not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/time
is requesting a value on a non-allowed timestep.
<DT><I>Fix for fix store/state not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix store/state
is requesting a value on a non-allowed timestep.
<DT><I>Fix freeze requires atom attribute torque</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Fix heat group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix heat kinetic energy went negative</I>
<DD>This will cause the velocity rescaling about to be performed by fix
heat to be invalid.
<DT><I>Fix in variable not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. The variable is
requesting the values on a non-allowed timestep.
<DT><I>Fix langevin period must be > 0.0</I>
<DD>The time window for temperature relaxation must be > 0
<DT><I>Fix momentum group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot define z or vz variable for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot have 0 length rotation vector</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot rotate aroung non z-axis for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot set linear z motion for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot set wiggle z motion for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute potential energy</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute pressure</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute temperature</I>
<DD>Self-explanatory.
<DT><I>Fix msst requires a periodic box</I>
<DD>Self-explanatory.
<DT><I>Fix msst tscale must satisfy 0 <= tscale < 1</I>
<DD>Self-explanatory.
<DT><I>Fix npt/nph has tilted box too far - box flips are not yet implemented</I>
<DD>This feature has not yet been added. However, if you are applying
an off-diagonal pressure to a fluid, the box may want to tilt indefinitely,
because the fluid cannot support the pressure you are imposing.
<DT><I>Fix nve/asphere cannot be used with atom attributes diameter or rmass</I>
<DD>These attributes override the shape and mass settings, so cannot be
used.
<DT><I>Fix nve/asphere requires atom attributes angmom, quat, torque, shape</I>
<DD>An atom style that specifies these quantities is needed.
<DT><I>Fix nve/asphere requires extended particles</I>
<DD>This fix can only be used for particles with a shape setting.
<DT><I>Fix nve/sphere requires atom attribute diameter or shape</I>
<DD>An atom style that specifies these quantities is needed.
<DT><I>Fix nve/sphere requires atom attribute mu</I>
<DD>An atom style with this attribute is needed.
<DT><I>Fix nve/sphere requires atom attributes omega, torque</I>
<DD>An atom style with these attributes is needed.
<DT><I>Fix nve/sphere requires extended particles</I>
<DD>This fix can only be used for particles of a finite size.
<DT><I>Fix nve/sphere requires spherical particle shapes</I>
<DD>Self-explanatory.
<DT><I>Fix nvt/nph/npt asphere cannot be used with atom attributes diameter or rmass</I>
<DD>Those attributes are for spherical particles.
<DT><I>Fix nvt/nph/npt asphere requires atom attributes quat, angmom, torque, shape</I>
<DD>Those attributes are what are used to define aspherical particles.
<DT><I>Fix nvt/nph/npt asphere requires extended particles</I>
<DD>The shape setting for a particle in the fix group has shape = 0.0,
which means it is a point particle.
<DT><I>Fix nvt/nph/npt sphere requires atom attribute diameter or shape</I>
<DD>An atom style that specifies these quantities is needed.
<DT><I>Fix nvt/nph/npt sphere requires atom attributes omega, torque</I>
<DD>Those attributes are what are used to define spherical particles.
<DT><I>Fix nvt/npt/nph damping parameters must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix nvt/sphere requires extended particles</I>
<DD>This fix can only be used for particles of a finite size.
<DT><I>Fix nvt/sphere requires spherical particle shapes</I>
<DD>Self-explanatory.
<DT><I>Fix orient/fcc file open failed</I>
<DD>The fix orient/fcc command could not open a specified file.
<DT><I>Fix orient/fcc file read failed</I>
<DD>The fix orient/fcc command could not read the needed parameters from a
specified file.
<DT><I>Fix orient/fcc found self twice</I>
<DD>The neighbor lists used by fix orient/fcc are messed up. If this
error occurs, it is likely a bug, so send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
<DT><I>Fix peri neigh does not exist</I>
<DD>Somehow a fix that the pair style defines has been deleted.
<DT><I>Fix pour region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix pour region cannot be dynamic</I>
<DD>Only static regions can be used with fix pour.
<DT><I>Fix pour region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the fix pour command.
<DT><I>Fix pour requires atom attributes radius, rmass</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Fix press/berendsen damping parameters must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix qeq/comb group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix qeq/comb requires atom attribute q</I>
<DD>An atom style with charge must be used to perform charge equilibration.
<DT><I>Fix reax/bonds numbonds > nsbmax_most</I>
<DD>The limit of the number of bonds expected by the ReaxFF force field
was exceeded.
<DT><I>Fix recenter group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix rigid atom has non-zero image flag in a non-periodic dimension</I>
<DD>You cannot set image flags for non-periodic dimensions.
<DT><I>Fix rigid molecule requires atom attribute molecule</I>
<DD>Self-explanatory.
<DT><I>Fix rigid/nvt period must be > 0.0</I>
<DD>Self-explanatory
<DT><I>Fix rigid: Bad principal moments</I>
<DD>The principal moments of inertia computed for a rigid body
are not within the required tolerances.
<DT><I>Fix shake cannot be used with minimization</I>
<DD>Cannot use fix shake while doing an energy minimization since
it turns off bonds that should contribute to the energy.
<DT><I>Fix spring couple group ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix srd lamda must be >= 0.6 of SRD grid size</I>
<DD>This is a requirement for accuracy reasons.
<DT><I>Fix srd requires SRD particles all have same mass</I>
<DD>Self-explanatory.
<DT><I>Fix srd requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Fix srd requires newton pair on</I>
<DD>Self-explanatory.
<DT><I>Fix store/state compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix store/state compute does not calculate a per-atom array</I>
<DD>The compute calculates a per-atom vector.
<DT><I>Fix store/state compute does not calculate a per-atom vector</I>
<DD>The compute calculates a per-atom vector.
<DT><I>Fix store/state compute does not calculate per-atom values</I>
<DD>Computes that calculate global or local quantities cannot be used
with fix store/state.
<DT><I>Fix store/state fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix store/state fix does not calculate a per-atom array</I>
<DD>The fix calculates a per-atom vector.
<DT><I>Fix store/state fix does not calculate a per-atom vector</I>
<DD>The fix calculates a per-atom array.
<DT><I>Fix store/state fix does not calculate per-atom values</I>
<DD>Fixes that calculate global or local quantities cannot be used with
fix store/state.
<DT><I>Fix store/state for atom property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Fix store/state variable is not atom-style variable</I>
<DD>Only atom-style variables calculate per-atom quantities.
<DT><I>Fix temp/berendsen period must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix thermal/conductivity swap value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix tmd must come after integration fixes</I>
<DD>Any fix tmd command must appear in the input script after all time
integration fixes (nve, nvt, npt). See the fix tmd documentation for
details.
<DT><I>Fix ttm electron temperatures must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_density must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_specific_heat must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_thermal_conductivity must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm gamma_p must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm gamma_s must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm number of nodes must be > 0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm v_0 must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix used in compute atom/molecule not computed at compatible time</I>
<DD>The fix must produce per-atom quantities on timesteps that the compute
needs them.
<DT><I>Fix used in compute reduce not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Compute sum is
requesting a value on a non-allowed timestep.
<DT><I>Fix viscosity swap value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix viscosity vtarget value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix wall cutoff <= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix wall/colloid cannot be used with atom attribute diameter</I>
<DD>Only finite-size particles defined by the shape command can be used.
<DT><I>Fix wall/colloid requires atom attribute shape</I>
<DD>Self-explanatory.
<DT><I>Fix wall/colloid requires extended particles</I>
<DD>Self-explanatory.
<DT><I>Fix wall/colloid requires spherical particles</I>
<DD>Self-explanatory.
<DT><I>Fix wall/gran is incompatible with Pair style</I>
<DD>Must use a granular pair style to define the parameters needed for
this fix.
<DT><I>Fix wall/gran requires atom attributes radius, omega, torque</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Fix wall/region colloid cannot be used with atom attribute diameter</I>
<DD>Only finite-size particles defined by the shape command can be used.
<DT><I>Fix wall/region colloid requires atom attribute shape</I>
<DD>Self-explanatory.
<DT><I>Fix wall/region colloid requires extended particles</I>
<DD>Self-explanatory.
<DT><I>Fix wall/region colloid requires spherical particles</I>
<DD>Self-explanatory.
<DT><I>Fix wall/region cutoff <= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix_modify order must be 3 or 5</I>
<DD>Self-explanatory.
<DT><I>Fix_modify pressure ID does not compute pressure</I>
<DD>The compute ID assigned to the fix must compute pressure.
<DT><I>Fix_modify temperature ID does not compute temperature</I>
<DD>The compute ID assigned to the fix must compute temperature.
<DT><I>Found no restart file matching pattern</I>
<DD>When using a "*" in the restart file name, no matching file was found.
<DT><I>GPU is not the first fix for this run</I>
<DD>This is the way the fix must be defined in your input script.
<DT><I>GPU library not compiled for this accelerator</I>
<DD>The GPU library was not built for your accelerator. Check the arch flag in
lib/gpu.
<DT><I>Gmask function in equal-style variable formula</I>
<DD>Gmask is per-atom operation.
<DT><I>Gravity changed since fix pour was created</I>
<DD>Gravity must be static and not dynamic for use with fix pour.
<DT><I>Gravity must point in -y to use with fix pour in 2d</I>
<DD>Gravity must be pointing "down" in a 2d box.
<DT><I>Gravity must point in -z to use with fix pour in 3d</I>
<DD>Gravity must be pointing "down" in a 3d box, i.e. theta = 180.0.
<DT><I>Grmask function in equal-style variable formula</I>
<DD>Grmask is per-atom operation.
<DT><I>Group ID does not exist</I>
<DD>A group ID used in the group command does not exist.
<DT><I>Group ID in variable formula does not exist</I>
<DD>Self-explanatory.
<DT><I>Group command before simulation box is defined</I>
<DD>The group command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Group region ID does not exist</I>
<DD>A region ID used in the group command does not exist.
<DT><I>Illegal ... command</I>
<DD>Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
<DT><I>Illegal COMB parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal Stillinger-Weber parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal Tersoff parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal chemical element names</I>
<DD>The name is too long to be a chemical element.
<DT><I>Illegal fix gpu command</I>
<DD>Self-explanatory.
<DT><I>Illegal number of angle table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal number of bond table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal number of pair table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal simulation box</I>
<DD>The lower bound of the simulation box is greater than the upper bound.
<DT><I>Improper atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
improper on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid improper.
<DT><I>Improper atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular improper
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid improper.
<DT><I>Improper atoms %d %d %d %d missing on proc %d at step</I>
<DD>One or more of 4 atoms needed to compute a particular improper are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the improper has blown apart and an atom is
too far away.
<DT><I>Improper coeff for hybrid has invalid style</I>
<DD>Improper style hybrid uses another improper style as one of its
coefficients. The improper style used in the improper_coeff command
or read from a restart file is not recognized.
<DT><I>Improper coeffs are not set</I>
<DD>No improper coefficients have been assigned in the data file or via
the improper_coeff command.
<DT><I>Improper style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Improper style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Improper style hybrid cannot use same improper style twice</I>
<DD>Self-explanatory.
<DT><I>Improper_coeff command before improper_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the improper_coeff
command until an improper_style has been assigned.
<DT><I>Improper_coeff command before simulation box is defined</I>
<DD>The improper_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Improper_coeff command when no impropers allowed</I>
<DD>The chosen atom style does not allow for impropers to be defined.
<DT><I>Improper_style command when no impropers allowed</I>
<DD>The chosen atom style does not allow for impropers to be defined.
<DT><I>Impropers assigned incorrectly</I>
<DD>Impropers read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Impropers defined but no improper types</I>
<DD>The data file header lists improper but no improper types.
<DT><I>Inconsistent iparam/jparam values in fix bond/create command</I>
<DD>If itype and jtype are the same, then their maxbond and newtype
settings must also be the same.
<DT><I>Incorrect args for angle coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for bond coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for improper coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for pair coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args in pair_style command</I>
<DD>Self-explanatory.
<DT><I>Incorrect atom format in data file</I>
<DD>Number of values per atom line in the data file is not consistent with
the atom style.
<DT><I>Incorrect boundaries with slab Ewald</I>
<DD>Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with Ewald.
<DT><I>Incorrect boundaries with slab PPPM</I>
<DD>Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with PPPM.
<DT><I>Incorrect element names in EAM potential file</I>
<DD>The element names in the EAM file do not match those requested.
<DT><I>Incorrect format in COMB potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in MEAM potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in NEB coordinate file</I>
<DD>Self-explanatory.
<DT><I>Incorrect format in Stillinger-Weber potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in TMD target file</I>
<DD>Format of file read by fix tmd command is incorrect.
<DT><I>Incorrect format in Tersoff potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect multiplicity arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect sign arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect velocity format in data file</I>
<DD>Each atom style defines a format for the Velocity section
of the data file. The read-in lines do not match.
<DT><I>Incorrect weight arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Index between variable brackets must be positive</I>
<DD>Self-explanatory.
<DT><I>Indexed per-atom vector in variable formula without atom map</I>
<DD>Accessing a value from an atom vector requires the ability to lookup
an atom index, which is provided by an atom map. An atom map does not
exist (by default) for non-molecular problems. Using the atom_modify
map command will force an atom map to be created.
<DT><I>Induced tilt by displace_box is too large</I>
<DD>The final tilt value must be between -1/2 and 1/2 of the perpendicular
box length.
<DT><I>Initial temperatures not all set in fix ttm</I>
<DD>Self-explantory.
<DT><I>Input line too long after variable substitution</I>
<DD>This is a hard (very large) limit defined in the input.cpp file.
<DT><I>Input line too long: %s</I>
<DD>This is a hard (very large) limit defined in the input.cpp file.
<DT><I>Insertion region extends outside simulation box</I>
<DD>Region specified with fix pour command extends outside the global
simulation box.
<DT><I>Insufficient Jacobi rotations for POEMS body</I>
<DD>Eigensolve for rigid body was not sufficiently accurate.
<DT><I>Insufficient Jacobi rotations for rigid body</I>
<DD>Eigensolve for rigid body was not sufficiently accurate.
<DT><I>Insufficient memory on accelerator. </I>
<DD>Self-explanatory.
<DT><I>Invalid Boolean syntax in if command</I>
<DD>Self-explanatory.
<DT><I>Invalid REAX atom type</I>
<DD>There is a mis-match between LAMMPS atom types and the elements
listed in the ReaxFF force field file.
<DT><I>Invalid angle style</I>
<DD>The choice of angle style is unknown.
<DT><I>Invalid angle table length</I>
<DD>Length must be 2 or greater.
<DT><I>Invalid angle type in Angles section of data file</I>
<DD>Angle type must be positive integer and within range of specified angle
types.
<DT><I>Invalid angle type index for fix shake</I>
<DD>Self-explanatory.
<DT><I>Invalid atom ID in Angles section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Atoms section of data file</I>
<DD>Atom IDs must be positive integers.
<DT><I>Invalid atom ID in Bonds section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Dihedrals section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Impropers section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Velocities section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom mass for fix shake</I>
<DD>Mass specified in fix shake command must be > 0.0.
<DT><I>Invalid atom style</I>
<DD>The choice of atom style is unknown.
<DT><I>Invalid atom type in Atoms section of data file</I>
<DD>Atom types must range from 1 to specified # of types.
<DT><I>Invalid atom type in create_atoms command</I>
<DD>The create_box command specified the range of valid atom types.
An invalid type is being requested.
<DT><I>Invalid atom type in fix bond/create command</I>
<DD>Self-explanatory.
<DT><I>Invalid atom type in neighbor exclusion list</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom type index for fix shake</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom types in pair_write command</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom vector in variable formula</I>
<DD>The atom vector is not recognized.
<DT><I>Invalid attribute in dump custom command</I>
<DD>Self-explantory.
<DT><I>Invalid attribute in dump local command</I>
<DD>Self-explantory.
<DT><I>Invalid attribute in dump modify command</I>
<DD>Self-explantory.
<DT><I>Invalid bond style</I>
<DD>The choice of bond style is unknown.
<DT><I>Invalid bond table length</I>
<DD>Length must be 2 or greater.
<DT><I>Invalid bond type in Bonds section of data file</I>
<DD>Bond type must be positive integer and within range of specified bond
types.
<DT><I>Invalid bond type in fix bond/break command</I>
<DD>Self-explanatory.
<DT><I>Invalid bond type in fix bond/create command</I>
<DD>Self-explanatory.
<DT><I>Invalid bond type index for fix shake</I>
<DD>Self-explanatory. Check the fix shake command in the input script.
<DT><I>Invalid coeffs for this dihedral style</I>
<DD>Cannot set class 2 coeffs in data file for this dihedral style.
<DT><I>Invalid command-line argument</I>
<DD>One or more command-line arguments is invalid. Check the syntax of
the command you are using to launch LAMMPS.
<DT><I>Invalid compute ID in variable formula</I>
<DD>The compute is not recognized.
<DT><I>Invalid compute style</I>
<DD>Self-explanatory.
<DT><I>Invalid cutoff in communicate command</I>
<DD>Specified cutoff must be >= 0.0.
<DT><I>Invalid cutoffs in pair_write command</I>
<DD>Inner cutoff must be larger than 0.0 and less than outer cutoff.
<DT><I>Invalid d1 or d2 value for pair colloid coeff</I>
<DD>Neither d1 or d2 can be < 0.
<DT><I>Invalid data file section: Angle Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: AngleAngle Coeffs</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: AngleAngleTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: AngleTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Angles</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: Bond Coeffs</I>
<DD>Atom style does not allow bonds.
<DT><I>Invalid data file section: BondAngle Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: BondBond Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: BondBond13 Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Bonds</I>
<DD>Atom style does not allow bonds.
<DT><I>Invalid data file section: Dihedral Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Dihedrals</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: EndBondTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Improper Coeffs</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: Impropers</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: MiddleBondTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid delta_conf in tad command</I>
<DD>The value must be between 0 and 1 inclusive.
<DT><I>Invalid density in Atoms section of data file</I>
<DD>Density value cannot be <= 0.0.
<DT><I>Invalid dihedral style</I>
<DD>The choice of dihedral style is unknown.
<DT><I>Invalid dihedral type in Dihedrals section of data file</I>
<DD>Dihedral type must be positive integer and within range of specified
dihedral types.
<DT><I>Invalid dipole line in data file</I>
<DD>Self-explanatory.
<DT><I>Invalid dipole value</I>
<DD>Self-explanatory.
<DT><I>Invalid dump dcd filename</I>
<DD>Filenames used with the dump dcd style cannot be binary or compressed
or cause multiple files to be written.
<DT><I>Invalid dump frequency</I>
<DD>Dump frequency must be 1 or greater.
<DT><I>Invalid dump style</I>
<DD>The choice of dump style is unknown.
<DT><I>Invalid dump xtc filename</I>
<DD>Filenames used with the dump xtc style cannot be binary or compressed
or cause multiple files to be written.
<DT><I>Invalid dump xyz filename</I>
<DD>Filenames used with the dump xyz style cannot be binary or cause files
to be written by each processor.
<DT><I>Invalid dump_modify threshhold operator</I>
<DD>Operator keyword used for threshold specification in not recognized.
<DT><I>Invalid fix ID in variable formula</I>
<DD>The fix is not recognized.
<DT><I>Invalid fix ave/time off column</I>
<DD>Self-explantory.
<DT><I>Invalid fix box/relax command for a 2d simulation</I>
<DD>Fix box/relax styles involving the z dimension cannot be used in
a 2d simulation.
<DT><I>Invalid fix box/relax command pressure settings</I>
<DD>If multiple dimensions are coupled, those dimensions must be specified.
<DT><I>Invalid fix box/relax pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix nvt/npt/nph command for a 2d simulation</I>
<DD>Cannot control z dimension in a 2d model.
<DT><I>Invalid fix nvt/npt/nph command pressure settings</I>
<DD>If multiple dimensions are coupled, those dimensions must be
specified.
<DT><I>Invalid fix nvt/npt/nph pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix press/berendsen for a 2d simulation</I>
<DD>The z component of pressure cannot be controlled for a 2d model.
<DT><I>Invalid fix press/berendsen pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix style</I>
<DD>The choice of fix style is unknown.
<DT><I>Invalid flag in force field section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid flag in header section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid flag in type arrays section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid frequency in temper command</I>
<DD>Nevery must be > 0.
<DT><I>Invalid group ID in neigh_modify command</I>
<DD>A group ID used in the neigh_modify command does not exist.
<DT><I>Invalid group function in variable formula</I>
<DD>Group function is not recognized.
<DT><I>Invalid group in communicate command</I>
<DD>Self-explanatory.
<DT><I>Invalid improper style</I>
<DD>The choice of improper style is unknown.
<DT><I>Invalid improper type in Impropers section of data file</I>
<DD>Improper type must be positive integer and within range of specified
improper types.
<DT><I>Invalid keyword in angle table parameters</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in bond table parameters</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute angle/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute bond/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute dihedral/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute improper/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute pair/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/atom command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/molecule command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in dump cfg command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in pair table parameters</I>
<DD>Keyword used in list of table parameters is not recognized.
<DT><I>Invalid keyword in thermo_style custom command</I>
<DD>One or more specified keywords are not recognized.
<DT><I>Invalid kspace style</I>
<DD>The choice of kspace style is unknown.
<DT><I>Invalid mass line in data file</I>
<DD>Self-explanatory.
<DT><I>Invalid mass value</I>
<DD>Self-explanatory.
<DT><I>Invalid math function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid math/group/special function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid option in lattice command for non-custom style</I>
<DD>Certain lattice keywords are not supported unless the
lattice style is "custom".
<DT><I>Invalid order of forces within respa levels</I>
<DD>For respa, ordering of force computations within respa levels must
obey certain rules. E.g. bonds cannot be compute less frequently than
angles, pairwise forces cannot be computed less frequently than
kspace, etc.
<DT><I>Invalid pair style</I>
<DD>The choice of pair style is unknown.
<DT><I>Invalid pair table cutoff</I>
<DD>Cutoffs in pair_coeff command are not valid with read-in pair table.
<DT><I>Invalid pair table length</I>
<DD>Length of read-in pair table is invalid
<DT><I>Invalid radius in Atoms section of data file</I>
<DD>Radius must be >= 0.0.
<DT><I>Invalid random number seed in fix ttm command</I>
<DD>Random number seed must be > 0.
<DT><I>Invalid random number seed in set command</I>
<DD>Random number seed must be > 0.
<DT><I>Invalid region style</I>
<DD>The choice of region style is unknown.
<DT><I>Invalid replace values in compute reduce</I>
<DD>Self-explanatory.
<DT><I>Invalid run command N value</I>
<DD>The number of timesteps must fit in a 32-bit integer. If you want to
run for more steps than this, perform multiple shorter runs.
<DT><I>Invalid run command start/stop value</I>
<DD>Self-explanatory.
<DT><I>Invalid run command upto value</I>
<DD>Self-explanatory.
<DT><I>Invalid seed for Marsaglia random # generator</I>
<DD>The initial seed for this random number generator must be a positive
integer less than or equal to 900 million.
<DT><I>Invalid seed for Park random # generator</I>
<DD>The initial seed for this random number generator must be a positive
integer.
<DT><I>Invalid shape line in data file</I>
<DD>Self-explanatory.
<DT><I>Invalid shape line in data file</I>
<DD>Self-explanatory.
<DT><I>Invalid shape value</I>
<DD>Self-explanatory.
<DT><I>Invalid shear direction for fix wall/gran</I>
<DD>Self-explanatory.
<DT><I>Invalid special function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid style in pair_write command</I>
<DD>Self-explanatory. Check the input script.
<DT><I>Invalid syntax in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid t_event in prd command</I>
<DD>Self-explanatory.
<DT><I>Invalid t_event in tad command</I>
<DD>The value must be greater than 0.
<DT><I>Invalid thermo keyword in variable formula</I>
<DD>The keyword is not recognized.
<DT><I>Invalid tmax in tad command</I>
<DD>The value must be greater than 0.0.
<DT><I>Invalid type for dipole set</I>
<DD>Dipole command must set a type from 1-N where N is the number of atom
types.
<DT><I>Invalid type for mass set</I>
<DD>Mass command must set a type from 1-N where N is the number of atom
types.
<DT><I>Invalid type for shape set</I>
<DD>Atom type is out of bounds.
<DT><I>Invalid value in set command</I>
<DD>The value specified for the setting is invalid, likely because it is
too small or too large.
<DT><I>Invalid variable evaluation in variable formula</I>
<DD>A variable used in a formula could not be evaluated.
<DT><I>Invalid variable in next command</I>
<DD>Self-explanatory.
<DT><I>Invalid variable name in variable formula</I>
<DD>Variable name is not recognized.
<DT><I>Invalid variable name</I>
<DD>Variable name used in an input script line is invalid.
<DT><I>Invalid variable style with next command</I>
<DD>Variable styles <I>equal</I> and <I>world</I> cannot be used in a next
command.
<DT><I>Invalid wiggle direction for fix wall/gran</I>
<DD>Self-explanatory.
<DT><I>Invoked angle equil angle on angle style none</I>
<DD>Self-explanatory.
<DT><I>Invoked angle single on angle style none</I>
<DD>Self-explanatory.
<DT><I>Invoked bond equil distance on bond style none</I>
<DD>Self-explanatory.
<DT><I>Invoked bond single on bond style none</I>
<DD>Self-explanatory.
<DT><I>Invoked pair single on pair style none</I>
<DD>A command (e.g. a dump) attempted to invoke the single() function on a
pair style none, which is illegal. You are probably attempting to
compute per-atom quantities with an undefined pair style.
<DT><I>KSpace style has not yet been set</I>
<DD>Cannot use kspace_modify command until a kspace style is set.
<DT><I>KSpace style is incompatible with Pair style</I>
<DD>Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected.
<DT><I>Keyword %s in MEAM parameter file not recognized</I>
<DD>Self-explanatory.
<DT><I>Kspace style requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Label wasn't found in input script</I>
<DD>Self-explanatory.
<DT><I>Lattice orient vectors are not orthogonal</I>
<DD>The three specified lattice orientation vectors must be mutually
orthogonal.
<DT><I>Lattice orient vectors are not right-handed</I>
<DD>The three specified lattice orientation vectors must create a
right-handed coordinate system such that a1 cross a2 = a3.
<DT><I>Lattice primitive vectors are collinear</I>
<DD>The specified lattice primitive vectors do not for a unit cell with
non-zero volume.
<DT><I>Lattice settings are not compatible with 2d simulation</I>
<DD>One or more of the specified lattice vectors has a non-zero z
component.
<DT><I>Lattice spacings are invalid</I>
<DD>Each x,y,z spacing must be > 0.
<DT><I>Lattice style incompatible with simulation dimension</I>
<DD>2d simulation can use sq, sq2, or hex lattice. 3d simulation can use
sc, bcc, or fcc lattice.
<DT><I>Log of zero/negative value in variable formula</I>
<DD>Self-explanatory.
<DT><I>MEAM library error %d</I>
<DD>A call to the MEAM Fortran library returned an error.
<DT><I>MPI_LMP_BIGINT and bigint in lmptype.h are not compatible</I>
<DD>The size of the MPI datatype does not match the size of a bigint.
<DT><I>MPI_LMP_TAGINT and tagint in lmptype.h are not compatible</I>
<DD>The size of the MPI datatype does not match the size of a tagint.
<DT><I>Mass command before simulation box is defined</I>
<DD>The mass command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Min_style command before simulation box is defined</I>
<DD>The min_style command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Minimization could not find thermo_pe compute</I>
<DD>This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command.
<DT><I>Minimize command before simulation box is defined</I>
<DD>The minimize command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Mismatched brackets in variable</I>
<DD>Self-explanatory.
<DT><I>Mismatched compute in variable formula</I>
<DD>A compute is referenced incorrectly or a compute that produces per-atom
values is used in an equal-style variable formula.
<DT><I>Mismatched fix in variable formula</I>
<DD>A fix is referenced incorrectly or a fix that produces per-atom
values is used in an equal-style variable formula.
<DT><I>Mismatched variable in variable formula</I>
<DD>A variable is referenced incorrectly or an atom-style variable that
produces per-atom values is used in an equal-style variable
formula.
<DT><I>Molecular data file has too many atoms</I>
<DD>These kids of data files are currently limited to a number
of atoms that fits in a 32-bit integer.
<DT><I>Molecule count changed in compute atom/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute com/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute gyration/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute msd/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute property/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>More than one fix deform</I>
<DD>Only one fix deform can be defined at a time.
<DT><I>More than one fix freeze</I>
<DD>Only one of these fixes can be defined, since the granular pair
potentials access it.
<DT><I>More than one fix shake</I>
<DD>Only one fix shake can be defined.
<DT><I>Must define angle_style before Angle Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define angle_style before BondAngle Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define angle_style before BondBond Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define bond_style before Bond Coeffs</I>
<DD>Must use a bond_style command before reading a data file that
defines Bond Coeffs.
<DT><I>Must define dihedral_style before AngleAngleTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines AngleAngleTorsion Coeffs.
<DT><I>Must define dihedral_style before AngleTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines AngleTorsion Coeffs.
<DT><I>Must define dihedral_style before BondBond13 Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines BondBond13 Coeffs.
<DT><I>Must define dihedral_style before Dihedral Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines Dihedral Coeffs.
<DT><I>Must define dihedral_style before EndBondTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines EndBondTorsion Coeffs.
<DT><I>Must define dihedral_style before MiddleBondTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines MiddleBondTorsion Coeffs.
<DT><I>Must define improper_style before AngleAngle Coeffs</I>
<DD>Must use an improper_style command before reading a data file that
defines AngleAngle Coeffs.
<DT><I>Must define improper_style before Improper Coeffs</I>
<DD>Must use an improper_style command before reading a data file that
defines Improper Coeffs.
<DT><I>Must define pair_style before Pair Coeffs</I>
<DD>Must use a pair_style command before reading a data file that defines
Pair Coeffs.
<DT><I>Must have more than one processor partition to temper</I>
<DD>Cannot use the temper command with only one processor partition. Use
the -partition command-line option.
<DT><I>Must read Atoms before Angles</I>
<DD>The Atoms section of a data file must come before an Angles section.
<DT><I>Must read Atoms before Bonds</I>
<DD>The Atoms section of a data file must come before a Bonds section.
<DT><I>Must read Atoms before Dihedrals</I>
<DD>The Atoms section of a data file must come before a Dihedrals section.
<DT><I>Must read Atoms before Impropers</I>
<DD>The Atoms section of a data file must come before an Impropers
section.
<DT><I>Must read Atoms before Velocities</I>
<DD>The Atoms section of a data file must come before a Velocities
section.
<DT><I>Must set both respa inner and outer</I>
<DD>Cannot use just the inner or outer option with respa without using the
other.
<DT><I>Must specify a region in fix deposit</I>
<DD>The region keyword must be specified with this fix.
<DT><I>Must specify a region in fix pour</I>
<DD>The region keyword must be specified with this fix.
<DT><I>Must use -in switch with multiple partitions</I>
<DD>A multi-partition simulation cannot read the input script from stdin.
The -in command-line option must be used to specify a file.
<DT><I>Must use a block or cylinder region with fix pour</I>
<DD>Self-explanatory.
<DT><I>Must use a block region with fix pour for 2d simulations</I>
<DD>Self-explanatory.
<DT><I>Must use a bond style with TIP4P potential</I>
<DD>TIP4P potentials assume bond lengths in water are constrained
by a fix shake command.
<DT><I>Must use a molecular atom style with fix poems molecule</I>
<DD>Self-explanatory.
<DT><I>Must use a z-axis cylinder with fix pour</I>
<DD>The axis of the cylinder region used with the fix pour command must
be oriented along the z dimension.
<DT><I>Must use an angle style with TIP4P potential</I>
<DD>TIP4P potentials assume angles in water are constrained by a fix shake
command.
<DT><I>Must use atom style with molecule IDs with fix bond/swap</I>
<DD>Self-explanatory.
<DT><I>Must use pair_style comb with fix qeq/comb</I>
<DD>Self-explanatory.
<DT><I>Must use variable energy with fix addforce</I>
<DD>Must define an energy vartiable when applyting a dynamic
force during minimization.
<DT><I>NEB command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>NEB requires damped dynamics minimizer</I>
<DD>Use a different minimization style.
<DT><I>NEB requires use of fix neb</I>
<DD>Self-explanatory.
<DT><I>Needed topology not in data file</I>
<DD>The header of the data file indicated that bonds or angles or
dihedrals or impropers would be included, but they were not present.
<DT><I>Neigh_modify exclude molecule requires atom attribute molecule</I>
<DD>Self-explanatory.
<DT><I>Neigh_modify include group != atom_modify first group</I>
<DD>Self-explanatory.
<DT><I>Neighbor delay must be 0 or multiple of every setting</I>
<DD>The delay and every parameters set via the neigh_modify command are
inconsistent. If the delay setting is non-zero, then it must be a
multiple of the every setting.
<DT><I>Neighbor include group not allowed with ghost neighbors</I>
<DD>This is a current restriction within LAMMPS.
<DT><I>Neighbor list overflow, boost neigh_modify one or page</I>
<DD>There are too many neighbors of a single atom. Use the neigh_modify
command to increase the neighbor page size and the max number of
neighbors allowed for one atom.
<DT><I>Neighbor multi not yet enabled for ghost neighbors</I>
<DD>This is a current restriction within LAMMPS.
<DT><I>Neighbor multi not yet enabled for granular</I>
<DD>Self-explanatory.
<DT><I>Neighbor multi not yet enabled for rRESPA</I>
<DD>Self-explanatory.
<DT><I>Neighbor page size must be >= 10x the one atom setting</I>
<DD>This is required to prevent wasting too much memory.
<DT><I>Neighbors of ghost atoms only allowed for full neighbor lists</I>
<DD>This is a current restriction within LAMMPS.
<DT><I>New bond exceeded bonds per atom in fix bond/create</I>
<DD>See the read_data command for info on setting the "extra bond per
atom" header value to allow for additional bonds to be formed.
<DT><I>New bond exceeded special list size in fix bond/create</I>
<DD>See the special_bonds extra command for info on how to leave space in
the special bonds list to allow for additional bonds to be formed.
<DT><I>Newton bond change after simulation box is defined</I>
<DD>The newton command cannot be used to change the newton bond value
after a read_data, read_restart, or create_box command.
<DT><I>No angle style is defined for compute angle/local</I>
<DD>Self-explanatory.
<DT><I>No angles allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No atoms in data file</I>
<DD>The header of the data file indicated that atoms would be included,
but they were not present.
<DT><I>No basis atoms in lattice</I>
<DD>Basis atoms must be defined for lattice style user.
<DT><I>No bond style is defined for compute bond/local</I>
<DD>Self-explanatory.
<DT><I>No bonds allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No dihedral style is defined for compute dihedral/local</I>
<DD>Self-explanatory.
<DT><I>No dihedrals allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No dump custom arguments specified</I>
<DD>The dump custom command requires that atom quantities be specified to
output to dump file.
<DT><I>No dump local arguments specified</I>
<DD>Self-explanatory.
<DT><I>No fix gravity defined for fix pour</I>
<DD>Cannot add poured particles without gravity to move them.
<DT><I>No improper style is defined for compute improper/local</I>
<DD>Self-explanatory.
<DT><I>No impropers allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No matching element in EAM potential file</I>
<DD>The EAM potential file does not contain elements that match the
requested elements.
<DT><I>No pair hbond/dreiding coefficients set</I>
<DD>Self-explanatory.
<DT><I>No pair style defined for compute group/group</I>
<DD>Cannot calculate group interactions without a pair style defined.
<DT><I>No pair style is defined for compute pair/local</I>
<DD>Self-explanatory.
<DT><I>No pair style is defined for compute property/local</I>
<DD>Self-explanatory.
<DT><I>No rigid bodies defined</I>
<DD>The fix specification did not end up defining any rigid bodies.
<DT><I>Non digit character between brackets in variable</I>
<DD>Self-explantory.
<DT><I>Non integer # of swaps in temper command</I>
<DD>Swap frequency in temper command must evenly divide the total # of
timesteps.
<DT><I>One or more atoms belong to multiple rigid bodies</I>
<DD>Two or more rigid bodies defined by the fix rigid command cannot
contain the same atom.
<DT><I>One or zero atoms in rigid body</I>
<DD>Any rigid body defined by the fix rigid command must contain 2 or more
atoms.
<DT><I>Out of range atoms - cannot compute PPPM</I>
<DD>One or more atoms are attempting to map their charge to a PPPM grid
point that is not owned by a processor. This is likely for one of two
reasons, both of them bad. First, it may mean that an atom near the
boundary of a processor's sub-domain has moved more than 1/2 the
<A HREF = "neighbor.html">neighbor skin distance</A> without neighbor lists being
rebuilt and atoms being migrated to new processors. This also means
you may be missing pairwise interactions that need to be computed.
The solution is to change the re-neighboring criteria via the
<A HREF = "neigh_modify">neigh_modify</A> command. The safest settings are "delay 0
every 1 check yes". Second, it may mean that an atom has moved far
outside a processor's sub-domain or even the entire simulation box.
This indicates bad physics, e.g. due to highly overlapping atoms, too
large a timestep, etc.
<DT><I>Overlapping large/large in pair colloid</I>
<DD>This potential is infinite when there is an overlap.
<DT><I>Overlapping small/large in pair colloid</I>
<DD>This potential is inifinte when there is an overlap.
<DT><I>POEMS fix must come before NPT/NPH fix</I>
<DD>NPT/NPH fix must be defined in input script after all poems fixes,
else the fix contribution to the pressure virial is incorrect.
<DT><I>PPPM grid is too large</I>
<DD>The global PPPM grid is larger than OFFSET in one or more dimensions.
OFFSET is currently set to 4096. You likely need to decrease the
requested precision.
<DT><I>PPPM order cannot be greater than %d</I>
<DD>Self-explanatory.
<DT><I>PPPM order has been reduced to 0</I>
<DD>LAMMPS has attempted to reduce the PPPM order to enable the simulation
to run, but can reduce the order no further. Try increasing the
accuracy of PPPM by reducing the tolerance size, thus inducing a
larger PPPM grid.
<DT><I>PRD command before simulation box is defined</I>
<DD>The prd command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>PRD nsteps must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>PRD t_corr must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>Pair coeff for hybrid has invalid style</I>
<DD>Style in pair coeff must have been listed in pair_style command.
<DT><I>Pair cutoff < Respa interior cutoff</I>
<DD>One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs.
<DT><I>Pair dipole/cut requires atom attributes q, mu, torque, dipole</I>
<DD>An atom style that specifies these quantities is needed.
<DT><I>Pair distance < table inner cutoff</I>
<DD>Two atoms are closer together than the pairwise table allows.
<DT><I>Pair distance > table outer cutoff</I>
<DD>Two atoms are further apart than the pairwise table allows.
<DT><I>Pair dpd requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair gayberne cannot be used with atom attribute diameter</I>
<DD>Finite-size particles must be defined with the shape command.
<DT><I>Pair gayberne epsilon a,b,c coeffs are not all set</I>
<DD>Each atom type involved in pair_style gayberne must
have these 3 coefficients set at least once.
<DT><I>Pair gayberne requires atom attributes quat, torque, shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Pair granular requires atom attributes radius, omega, torque</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair granular requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair granular with shear history requires newton pair off</I>
<DD>This is a current restriction of the implementation of pair
granular styles with history.
<DT><I>Pair hybrid sub-style does not support single call</I>
<DD>You are attempting to invoke a single() call on a pair style
that doesn't support it.
<DT><I>Pair hybrid sub-style is not used</I>
<DD>No pair_coeff command used a sub-style specified in the pair_style
command.
<DT><I>Pair inner cutoff < Respa interior cutoff</I>
<DD>One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs.
<DT><I>Pair inner cutoff >= Pair outer cutoff</I>
<DD>The specified cutoffs for the pair style are inconsistent.
<DT><I>Pair lubricate cannot be used with atom attributes diameter or rmass</I>
<DD>These attributes override the shape and mass settings, so cannot be
used.
<DT><I>Pair lubricate requires atom attribute omega or angmom</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Pair lubricate requires atom attributes torque and shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Pair lubricate requires extended particles</I>
<DD>This pair style can only be used for particles with a shape
setting.
<DT><I>Pair lubricate requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair lubricate requires spherical, mono-disperse particles</I>
<DD>This is a current restriction of this pair style.
<DT><I>Pair peri lattice is not identical in x, y, and z</I>
<DD>The lattice defined by the lattice command must be cubic.
<DT><I>Pair peri requires a lattice be defined</I>
<DD>Use the lattice command for this purpose.
<DT><I>Pair peri requires an atom map, see atom_modify</I>
<DD>Even for atomic systems, an atom map is required to find Peridynamic
bonds. Use the atom_modify command to define one.
<DT><I>Pair resquared cannot be used with atom attribute diameter</I>
<DD>This attribute overrides the shape settings, so cannot be used.
<DT><I>Pair resquared epsilon a,b,c coeffs are not all set</I>
<DD>Self-explanatory.
<DT><I>Pair resquared epsilon and sigma coeffs are not all set</I>
<DD>Self-explanatory.
<DT><I>Pair resquared requires atom attributes quat, torque, shape</I>
<DD>An atom style that defines these attributes must be used.
<DT><I>Pair style AIREBO requires atom IDs</I>
<DD>This is a requirement to use the AIREBO potential.
<DT><I>Pair style AIREBO requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the AIREBO
potential.
<DT><I>Pair style COMB requires atom IDs</I>
<DD>This is a requirement to use the AIREBO potential.
<DT><I>Pair style COMB requires atom attribute q</I>
<DD>Self-explanatory.
<DT><I>Pair style COMB requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the COMB
potential.
<DT><I>Pair style MEAM requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the MEAM
potential.
<DT><I>Pair style Stillinger-Weber requires atom IDs</I>
<DD>This is a requirement to use the SW potential.
<DT><I>Pair style Stillinger-Weber requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the SW
potential.
<DT><I>Pair style Tersoff requires atom IDs</I>
<DD>This is a requirement to use the Tersoff potential.
<DT><I>Pair style Tersoff requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the Tersoff
potential.
<DT><I>Pair style born/coul/long requires atom attribute q</I>
<DD>An atom style that defines this attribute must be used.
<DT><I>Pair style buck/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style buck/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style does not support bond_style quartic</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by bond_style quartic.
<DT><I>Pair style does not support compute group/group</I>
<DD>The pair_style does not have a single() function, so it cannot be
invokded by the compute group/group command.
<DT><I>Pair style does not support compute pair/local</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by fix bond/swap.
<DT><I>Pair style does not support compute property/local</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by fix bond/swap.
<DT><I>Pair style does not support fix bond/swap</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by fix bond/swap.
<DT><I>Pair style does not support pair_write</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by pair write.
<DT><I>Pair style does not support rRESPA inner/middle/outer</I>
<DD>You are attempting to use rRESPA options with a pair style that
does not support them.
<DT><I>Pair style granular with history requires atoms have IDs</I>
<DD>Atoms in the simulation do not have IDs, so history effects
cannot be tracked by the granular pair potential.
<DT><I>Pair style hbond/dreiding requires an atom map, see atom_modify</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires atom IDs</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires molecular system</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires newton pair on</I>
<DD>See the newton command for details.
<DT><I>Pair style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Pair style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Pair style hybrid cannot use same pair style twice</I>
<DD>The sub-style arguments of pair_style hybrid cannot be duplicated.
Check the input script.
<DT><I>Pair style is incompatible with KSpace style</I>
<DD>If a pair style with a long-range Coulombic component is selected,
then a kspace style must also be used.
<DT><I>Pair style lj/charmm/coul/charmm requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/charmm/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/class2/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/class2/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/long/tip4p requires atom IDs</I>
<DD>There are no atom IDs defined in the system and the TIP4P potential
requires them to find O,H atoms with a water molecule.
<DT><I>Pair style lj/cut/coul/long/tip4p requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/cut/coul/long/tip4p requires newton pair on</I>
<DD>This is because the computation of constraint forces within a water
molecule adds forces to atoms owned by other processors.
<DT><I>Pair style lj/gromacs/coul/gromacs requires atom attribute q</I>
<DD>An atom_style with this attribute is needed.
<DT><I>Pair style peri_lps requires atom style peri</I>
<DD>This is because atom style peri stores quantities needed by
the peridynamic potential.
<DT><I>Pair style peri_pmb requires atom style peri</I>
<DD>This is because atom style peri stores quantities needed by
the peridynamic potential.
<DT><I>Pair style reax requires atom IDs</I>
<DD>This is a requirement to use the ReaxFF potential.
<DT><I>Pair style reax requires newton pair on</I>
<DD>This is a requirement to use the ReaxFF potential.
<DT><I>Pair table cutoffs must all be equal to use with KSpace</I>
<DD>When using pair style table with a long-range KSpace solver, the
cutoffs for all atom type pairs must all be the same, since the
long-range solver starts at that cutoff.
<DT><I>Pair table parameters did not set N</I>
<DD>List of pair table parameters must include N setting.
<DT><I>Pair tersoff/zbl requires metal or real units</I>
<DD>This is a current restriction of this pair potential.
<DT><I>Pair yukawa/colloid cannot be used with atom attribute diameter</I>
<DD>Only finite-size particles defined by the shape command can be used.
<DT><I>Pair yukawa/colloid requires atom attribute shape</I>
<DD>Self-explanatory.
<DT><I>Pair yukawa/colloid requires spherical particles</I>
<DD>Self-explanatory.
<DT><I>Pair_coeff command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Pair_coeff command before simulation box is defined</I>
<DD>The pair_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Pair_modify command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Pair_write command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Particle on or inside fix wall surface</I>
<DD>Particles must be "exterior" to the wall in order for energy/force to
be calculated.
<DT><I>Particle on or inside surface of region used in fix wall/region</I>
<DD>Particles must be "exterior" to the region surface in order for
energy/force to be calculated.
<DT><I>Per-atom compute in equal-style variable formula</I>
<DD>Equal-style variables cannot use per-atom quantities.
<DT><I>Per-atom energy was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Per-atom fix in equal-style variable formula</I>
<DD>Equal-style variables cannot use per-atom quantities.
<DT><I>Per-atom virial was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to have
tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Per-processor system is too big</I>
<DD>The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
<DT><I>Potential energy ID for fix neb does not exist</I>
<DD>Self-explanatory.
<DT><I>Potential file has duplicate entry</I>
<DD>The potential file for a SW or Tersoff potential has more than
one entry for the same 3 ordered elements.
<DT><I>Potential file is missing an entry</I>
<DD>The potential file for a SW or Tersoff potential does not have a
needed entry.
<DT><I>Power by 0 in variable formula</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix box/relax does not exist</I>
<DD>The compute ID needed to compute pressure for the fix does not
exist.
<DT><I>Pressure ID for fix modify does not exist</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix npt/nph does not exist</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix press/berendsen does not exist</I>
<DD>The compute ID needed to compute pressure for the fix does not
exist.
<DT><I>Pressure ID for thermo does not exist</I>
<DD>The compute ID needed to compute pressure for thermodynamics does not
exist.
<DT><I>Pressure control can not be used with fix nvt/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt/sllod</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt/sphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph/sphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix npt/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix npt/sphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix npt</I>
<DD>Self-explanatory.
<DT><I>Processor count in z must be 1 for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Processor partitions are inconsistent</I>
<DD>The total number of processors in all partitions must match the number
of processors LAMMPS is running on.
<DT><I>Processors command after simulation box is defined</I>
<DD>The processors command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Quaternion creation numeric error</I>
<DD>A numeric error occurred in the creation of a rigid body by the fix
rigid command.
<DT><I>R0 < 0 for fix spring command</I>
<DD>Equilibrium spring length is invalid.
<DT><I>Reax_defs.h setting for NATDEF is too small</I>
<DD>Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS.
<DT><I>Reax_defs.h setting for NNEIGHMAXDEF is too small</I>
<DD>Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS.
<DT><I>Region ID for compute reduce/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for compute temp/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for dump cfg does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for dump custom does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix addforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix aveforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix deposit does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix evaporate does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix heat does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix setforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix wall/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID in variable formula does not exist</I>
<DD>Self-explanatory.
<DT><I>Region cannot have 0 length rotation vector</I>
<DD>Self-explanatory.
<DT><I>Region intersect region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Region union or intersect cannot be dynamic</I>
<DD>The sub-regions can be dynamic, but not the combined region.
<DT><I>Region union region ID does not exist</I>
<DD>One or more of the region IDs specified by the region union command
does not exist.
<DT><I>Replacing a fix, but new style != old style</I>
<DD>A fix ID can be used a 2nd time, but only if the style matches the
previous fix. In this case it is assumed you with to reset a fix's
parameters. This error may mean you are mistakenly re-using a fix ID
when you do not intend to.
<DT><I>Replicate command before simulation box is defined</I>
<DD>The replicate command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Replicate did not assign all atoms correctly</I>
<DD>Atoms replicated by the replicate command were not assigned correctly
to processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box.
<DT><I>Replicated molecular system atom IDs are too big</I>
<DD>See the setting for the allowed atom ID size in the src/lmptype.h
file.
<DT><I>Replicated system is too big</I>
<DD>See the setting for bigint in the src/lmptype.h file.
<DT><I>Resetting timestep is not allowed with fix move</I>
<DD>This is because fix move is moving atoms based on elapsed time.
<DT><I>Respa inner cutoffs are invalid</I>
<DD>The first cutoff must be <= the second cutoff.
<DT><I>Respa levels must be >= 1</I>
<DD>Self-explanatory.
<DT><I>Respa middle cutoffs are invalid</I>
<DD>The first cutoff must be <= the second cutoff.
<DT><I>Reuse of compute ID</I>
<DD>A compute ID cannot be used twice.
<DT><I>Reuse of dump ID</I>
<DD>A dump ID cannot be used twice.
<DT><I>Reuse of region ID</I>
<DD>A region ID cannot be used twice.
<DT><I>Rigid body has degenerate moment of inertia</I>
<DD>Fix poems will only work with bodies (collections of atoms) that have
non-zero principal moments of inertia. This means they must be 3 or
more non-collinear atoms, even with joint atoms removed.
<DT><I>Rigid fix must come before NPT/NPH fix</I>
<DD>NPT/NPH fix must be defined in input script after all rigid fixes,
else the rigid fix contribution to the pressure virial is
incorrect.
<DT><I>Rmask function in equal-style variable formula</I>
<DD>Rmask is per-atom operation.
<DT><I>Run command before simulation box is defined</I>
<DD>The run command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Run command start value is after start of run</I>
<DD>Self-explanatory.
<DT><I>Run command stop value is before end of run</I>
<DD>Self-explanatory.
<DT><I>Run_style command before simulation box is defined</I>
<DD>The run_style command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>SRD bin size for fix srd differs from user request</I>
<DD>Fix SRD had to adjust the bin size to fit the simulation box.
<DT><I>SRD bins for fix srd are not cubic enough</I>
<DD>The bin shape is not within tolerance of cubic.
<DT><I>Same dimension twice in fix ave/spatial</I>
<DD>Self-explanatory.
<DT><I>Set command before simulation box is defined</I>
<DD>The set command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Set command with no atoms existing</I>
<DD>No atoms are yet defined so the set command cannot be used.
<DT><I>Set region ID does not exist</I>
<DD>Region ID specified in set command does not exist.
<DT><I>Shake angles have different bond types</I>
<DD>All 3-atom angle-constrained SHAKE clusters specified by the fix shake
command that are the same angle type, must also have the same bond
types for the 2 bonds in the angle.
<DT><I>Shake atoms %d %d %d %d missing on proc %d at step</I>
<DD>The 4 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake atoms %d %d %d missing on proc %d at step</I>
<DD>The 3 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake atoms %d %d missing on proc %d at step</I>
<DD>The 2 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake cluster of more than 4 atoms</I>
<DD>A single cluster specified by the fix shake command can have no more
than 4 atoms.
<DT><I>Shake clusters are connected</I>
<DD>A single cluster specified by the fix shake command must have a single
central atom with up to 3 other atoms bonded to it.
<DT><I>Shake determinant = 0.0</I>
<DD>The determinant of the matrix being solved for a single cluster
specified by the fix shake command is numerically invalid.
<DT><I>Shake fix must come before NPT/NPH fix</I>
<DD>NPT fix must be defined in input script after SHAKE fix, else the
SHAKE fix contribution to the pressure virial is incorrect.
<DT><I>Shape command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Smallint setting in lmptype.h is invalid</I>
<DD>It has to be the size of an integer.
<DT><I>Smallint setting in lmptype.h is not compatible</I>
<DD>Smallint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Sqrt of negative value in variable formula</I>
<DD>Self-explanatory.
<DT><I>Substitution for illegal variable</I>
<DD>Input script line contained a variable that could not be substituted
for.
<DT><I>System in data file is too big</I>
<DD>See the setting for bigint in the src/lmptype.h file.
<DT><I>TAD nsteps must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>TIP4P hydrogen has incorrect atom type</I>
<DD>The TIP4P pairwise computation found an H atom whose type does not
agree with the specified H type.
<DT><I>TIP4P hydrogen is missing</I>
<DD>The TIP4P pairwise computation failed to find the correct H atom
within a water molecule.
<DT><I>TMD target file did not list all group atoms</I>
<DD>The target file for the fix tmd command did not list all atoms in the
fix group.
<DT><I>Tad command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Tagint setting in lmptype.h is invalid</I>
<DD>Tagint must be as large or larger than smallint.
<DT><I>Tagint setting in lmptype.h is not compatible</I>
<DD>Smallint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Target temperature for fix nvt/npt/nph cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Target temperature for fix rigid/nvt cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Temper command before simulation box is defined</I>
<DD>The temper command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Temperature ID for fix bond/swap does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix box/relax does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix nvt/nph/npt does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix press/berendsen does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix temp/berendsen does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix temp/rescale does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix npt/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix npt/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix npt</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/sllod</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt</I>
<DD>Self-explanatory.
<DT><I>Temperature for fix nvt/sllod does not have a bias</I>
<DD>The specified compute must compute temperature with a bias.
<DT><I>Tempering could not find thermo_pe compute</I>
<DD>This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command.
<DT><I>Tempering fix ID is not defined</I>
<DD>The fix ID specified by the temper command does not exist.
<DT><I>Tempering temperature fix is not valid</I>
<DD>The fix specified by the temper command is not one that controls
temperature (nvt or langevin).
<DT><I>Thermo and fix not computed at compatible times</I>
<DD>Fixes generate values on specific timesteps. The thermo output
does not match these timesteps.
<DT><I>Thermo compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute array</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute scalar</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute vector</I>
<DD>Self-explanatory.
<DT><I>Thermo compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo custom variable cannot be indexed</I>
<DD>Self-explanatory.
<DT><I>Thermo custom variable is not equal-style variable</I>
<DD>Only equal-style variables can be output with thermodynamics, not
atom-style variables.
<DT><I>Thermo every variable returned a bad timestep</I>
<DD>The variable must return a timestep greater than the current timestep.
<DT><I>Thermo fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute array</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute scalar</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute vector</I>
<DD>Self-explanatory.
<DT><I>Thermo fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo keyword in variable requires lattice be defined</I>
<DD>The xlat, ylat, zlat keywords refer to lattice properties.
<DT><I>Thermo keyword in variable requires thermo to use/init pe</I>
<DD>You are using a thermo keyword in a variable that requires
potential energy to be calculated, but your thermo output
does not use it. Add it to your thermo output.
<DT><I>Thermo keyword in variable requires thermo to use/init press</I>
<DD>You are using a thermo keyword in a variable that requires pressure to
be calculated, but your thermo output does not use it. Add it to your
thermo output.
<DT><I>Thermo keyword in variable requires thermo to use/init temp</I>
<DD>You are using a thermo keyword in a variable that requires temperature
to be calculated, but your thermo output does not use it. Add it to
your thermo output.
<DT><I>Thermo keyword requires lattice be defined</I>
<DD>The xlat, ylat, zlat keywords refer to lattice properties.
<DT><I>Thermo style does not use press</I>
<DD>Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity.
<DT><I>Thermo style does not use temp</I>
<DD>Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity.
<DT><I>Thermo_modify int format does not contain d character</I>
<DD>Self-explanatory.
<DT><I>Thermo_modify pressure ID does not compute pressure</I>
<DD>The specified compute ID does not compute pressure.
<DT><I>Thermo_modify temperature ID does not compute temperature</I>
<DD>The specified compute ID does not compute temperature.
<DT><I>Thermo_style command before simulation box is defined</I>
<DD>The thermo_style command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>This variable thermo keyword cannot be used between runs</I>
<DD>Keywords that refer to time (such as cpu, elapsed) do not
make sense in between runs.
<DT><I>Threshhold for an atom property that isn't allocated</I>
<DD>A dump threshhold has been requested on a quantity that is
not defined by the atom style used in this simulation.
<DT><I>Timestep must be >= 0</I>
<DD>Specified timestep size is invalid.
<DT><I>Too big a problem to use velocity create loop all</I>
<DD>The system size must fit in a 32-bit integer to use this option.
<DT><I>Too big a timestep for dump dcd</I>
<DD>The timestep must fit in a 32-bit integer to use this dump style.
<DT><I>Too big a timestep for dump xtc</I>
<DD>The timestep must fit in a 32-bit integer to use this dump style.
<DT><I>Too few bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
<DT><I>Too many atom sorting bins</I>
<DD>This is likely due to an immense simulation box that has blown up
to a large size.
<DT><I>Too many atoms for dump dcd</I>
<DD>The system size must fit in a 32-bit integer to use this dump
style.
<DT><I>Too many atoms for dump xtc</I>
<DD>The system size must fit in a 32-bit integer to use this dump
style.
<DT><I>Too many atoms to dump sort</I>
<DD>Cannot sort when running with more than 2^31 atoms.
<DT><I>Too many exponent bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
<DT><I>Too many groups</I>
<DD>The maximum number of atom groups (including the "all" group) is
given by MAX_GROUP in group.cpp and is 32.
<DT><I>Too many iterations</I>
<DD>You must use a number of iterations that fit in a 32-bit integer
for minimization.
<DT><I>Too many mantissa bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
<DT><I>Too many masses for fix shake</I>
<DD>The fix shake command cannot list more masses than there are atom
types.
<DT><I>Too many neighbor bins</I>
<DD>This is likely due to an immense simulation box that has blown up
to a large size.
<DT><I>Too many timesteps for NEB</I>
<DD>You must use a number of timesteps that fit in a 32-bit integer
for NEB.
<DT><I>Too many total atoms</I>
<DD>See the setting for bigint in the src/lmptype.h file.
<DT><I>Too many total bits for bitmapped lookup table</I>
<DD>Table size specified via pair_modify command is too large. Note that
a value of N generates a 2^N size table.
<DT><I>Too many touching neighbors - boost MAXTOUCH</I>
<DD>A granular simulation has too many neighbors touching one atom. The
MAXTOUCH parameter in fix_shear_history.cpp must be set larger and
LAMMPS must be re-built.
<DT><I>Too much per-proc info for dump</I>
<DD>Number of local atoms times number of columns must fit in a 32-bit
integer for dump.
<DT><I>Tree structure in joint connections</I>
<DD>Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a tree structure.
<DT><I>Triclinic box must be periodic in skewed dimensions</I>
<DD>This is a requirement for using a non-orthogonal box. E.g. to set a
non-zero xy tilt, both x and y must be periodic dimensions.
<DT><I>Triclinic box skew is too large</I>
<DD>The displacement in a skewed direction must be less than half the box
length in that dimension. E.g. the xy tilt must be between -half and
+half of the x box length.
<DT><I>Tried to convert a double to int, but input_double > INT_MAX</I>
<DD>Self-explanatory.
<DT><I>Two groups cannot be the same in fix spring couple</I>
<DD>Self-explanatory.
+<DT><I>Unable to initialize accelerator for use</I>
+
+<DD>One or more specified accelerator(s) cannot currently be used by LAMMPS.
+This can happen if the accelerator is already in use by another
+process.
+
<DT><I>Unbalanced quotes in input line</I>
<DD>No matching end double quote was found following a leading double
quote.
<DT><I>Unexpected end of data file</I>
<DD>LAMMPS hit the end of the data file while attempting to read a
section. Something is wrong with the format of the data file.
<DT><I>Units command after simulation box is defined</I>
<DD>The units command cannot be used after a read_data, read_restart, or
create_box command.
<DT><I>Universe/uloop variable count < # of partitions</I>
<DD>A universe or uloop style variable must specify a number of values >= to the
number of processor partitions.
<DT><I>Unknown command: %s</I>
<DD>The command is not known to LAMMPS. Check the input script.
<DT><I>Unknown identifier in data file: %s</I>
<DD>A section of the data file cannot be read by LAMMPS.
<DT><I>Unknown table style in angle style table</I>
<DD>Self-explanatory.
<DT><I>Unknown table style in bond style table</I>
<DD>Self-explanatory.
<DT><I>Unknown table style in pair_style command</I>
<DD>Style of table is invalid for use with pair_style table command.
<DT><I>Unrecognized lattice type in MEAM file 1</I>
<DD>The lattice type in an entry of the MEAM library file is not
valid.
<DT><I>Unrecognized lattice type in MEAM file 2</I>
<DD>The lattice type in an entry of the MEAM parameter file is not
valid.
<DT><I>Unrecognized pair style in compute pair command</I>
<DD>Self-explanatory.
<DT><I>Use of compute temp/ramp with undefined lattice</I>
<DD>Must use lattice command with compute temp/ramp command if units
option is set to lattice.
<DT><I>Use of displace_atoms with undefined lattice</I>
<DD>Must use lattice command with displace_atoms command if units option
is set to lattice.
<DT><I>Use of displace_box with undefined lattice</I>
<DD>Must use lattice command with displace_box command if units option is
set to lattice.
<DT><I>Use of fix ave/spatial with undefined lattice</I>
<DD>A lattice must be defined to use fix ave/spatial with units = lattice.
<DT><I>Use of fix deform with undefined lattice</I>
<DD>A lattice must be defined to use fix deform with units = lattice.
<DT><I>Use of fix deposit with undefined lattice</I>
<DD>Must use lattice command with compute fix deposit command if units
option is set to lattice.
<DT><I>Use of fix dt/reset with undefined lattice</I>
<DD>Must use lattice command with fix dt/reset command if units option is
set to lattice.
<DT><I>Use of fix indent with undefined lattice</I>
<DD>The lattice command must be used to define a lattice before using the
fix indent command.
<DT><I>Use of fix move with undefined lattice</I>
<DD>Must use lattice command with fix move command if units option is
set to lattice.
<DT><I>Use of fix recenter with undefined lattice</I>
<DD>Must use lattice command with fix recenter command if units option is
set to lattice.
<DT><I>Use of fix wall with undefined lattice</I>
<DD>Must use lattice command with fix wall command if units option is set
to lattice.
<DT><I>Use of region with undefined lattice</I>
<DD>If scale = lattice (the default) for the region command, then a
lattice must first be defined via the lattice command.
<DT><I>Use of velocity with undefined lattice</I>
<DD>If scale = lattice (the default) for the velocity set or velocity ramp
command, then a lattice must first be defined via the lattice command.
<DT><I>Using fix nvt/sllod with inconsistent fix deform remap option</I>
<DD>Fix nvt/sllod requires that deforming atoms have a velocity profile
provided by "remap v" as a fix deform option.
<DT><I>Using fix nvt/sllod with no fix deform defined</I>
<DD>Self-explanatory.
<DT><I>Using fix srd with inconsistent fix deform remap option</I>
<DD>When shearing the box in an SRD simulation, the remap v option for fix
deform needs to be used.
<DT><I>Variable evaluation before simulation box is defined</I>
<DD>Cannot evaluate a compute or fix or atom-based value in a variable
before the simulation has been setup.
<DT><I>Variable for compute ti is invalid style</I>
<DD>Self-explanatory.
<DT><I>Variable for dump every is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix adapt is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix addforce is invalid style</I>
<DD>Self-explanatory.
<DT><I>Variable for fix aveforce is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix efield is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix indent is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix indent is not equal style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix move is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix setforce is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix wall is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix wall/reflect is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix wall/srd is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for region is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for region is not equal style</I>
<DD>Self-explanatory.
<DT><I>Variable for thermo every is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for velocity set is invalid style</I>
<DD>Only atom-style variables can be used.
<DT><I>Variable formula compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute ti does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump every does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix adapt does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix addforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix aveforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix efield does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix indent does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix move does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix setforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix store/state does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix wall does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix wall/reflect does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix wall/srd does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for region does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for thermo every does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for velocity set does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Velocity command before simulation box is defined</I>
<DD>The velocity command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Velocity command with no atoms existing</I>
<DD>A velocity command has been used, but no atoms yet exist.
<DT><I>Velocity ramp in z for a 2d problem</I>
<DD>Self-explanatory.
<DT><I>Velocity temperature ID does not compute temperature</I>
<DD>The compute ID given to the velocity command must compute
temperature.
<DT><I>Virial was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Wall defined twice in fix wall command</I>
<DD>Self-explanatory.
<DT><I>Wall defined twice in fix wall/reflect command</I>
<DD>Self-explanatory.
<DT><I>Wall defined twice in fix wall/srd command</I>
<DD>Self-explanatory.
<DT><I>Weighted neighbor list values are too big</I>
<DD>You must have less atoms per processor to use this
style neighbor list.
<DT><I>World variable count doesn't match # of partitions</I>
<DD>A world-style variable must specify a number of values equal to the
number of processor partitions.
<DT><I>Write_restart command before simulation box is defined</I>
<DD>The write_restart command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Zero-length lattice orient vector</I>
<DD>Self-explanatory.
</DL>
<H4><A NAME = "warn"></A>Warnings:
</H4>
<DL>
<DT><I>All element names have been set to 'C' for dump cfg</I>
<DD>Use the dump_modify command if you wish to override this.
<DT><I>Atom with molecule ID = 0 included in compute molecule group</I>
<DD>The group used in a compute command that operates on moleclues
includes atoms with no molecule ID. This is probably not what you
want.
<DT><I>Broken bonds will not alter angles, dihedrals, or impropers</I>
<DD>See the doc page for fix bond/break for more info on this
restriction.
<DT><I>Building an occasional neighobr list when atoms may have moved too far</I>
<DD>This can cause LAMMPS to crash when the neighbor list is built.
The solution is to check for building the regular neighbor lists
more frequently.
<DT><I>Compute cna/atom cutoff may be too large to find ghost atom neighbors</I>
<DD>The neighbor cutoff used may not encompass enough ghost atoms
to perform this operation correctly.
<DT><I>Computing temperature of portions of rigid bodies</I>
<DD>The group defined by the temperature compute does not encompass all
the atoms in one or more rigid bodies, so the change in
degrees-of-freedom for the atoms in those partial rigid bodies will
not be accounted for.
<DT><I>Created bonds will not create angles, dihedrals, or impropers</I>
<DD>See the doc page for fix bond/create for more info on this
restriction.
<DT><I>Dihedral problem: %d %d %d %d %d %d</I>
<DD>Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry.
<DT><I>Dump dcd/xtc timestamp may be wrong with fix dt/reset</I>
<DD>If the fix changes the timestep, the dump dcd file will not
reflect the change.
<DT><I>FENE bond too long: %d %d %d %g</I>
<DD>A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up.
<DT><I>FENE bond too long: %d %g</I>
<DD>A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up.
<DT><I>Fix SRD walls overlap but fix srd overlap not set</I>
<DD>You likely want to set this in your input script.
<DT><I>Fix bond/swap will ignore defined angles</I>
<DD>See the doc page for fix bond/swap for more info on this
restriction.
<DT><I>Fix move does not update angular momentum</I>
<DD>Atoms store this quantity, but fix move does not (yet) update it.
<DT><I>Fix move does not update quaternions</I>
<DD>Atoms store this quantity, but fix move does not (yet) update it.
<DT><I>Fix recenter should come after all other integration fixes</I>
<DD>Other fixes may change the position of the center-of-mass, so
fix recenter should come last.
<DT><I>Fix srd SRD moves may trigger frequent reneighboring</I>
<DD>This is because the SRD particles may move long distances.
<DT><I>Fix srd grid size > 1/4 of big particle diameter</I>
<DD>This may cause accuracy problems.
<DT><I>Fix srd no-slip wall collisions with bin shifting</I>
<DD>This is an inconsistent setting in your input script.
<DT><I>Fix srd particle moved outside valid domain</I>
<DD>This may indicate a problem with your simulation parameters.
<DT><I>Fix srd particles may move > big particle diameter</I>
<DD>This may cause accuracy problems.
<DT><I>Fix srd viscosity < 0.0 due to low SRD density</I>
<DD>This may cause accuracy problems.
<DT><I>Fix thermal/conductivity comes before fix ave/spatial</I>
<DD>The order of these 2 fixes in your input script is such that fix
thermal/conductivity comes first. If you are using fix ave/spatial to
measure the temperature profile induced by fix viscosity, then this
may cause a glitch in the profile since you are averaging immediately
after swaps have occurred. Flipping the order of the 2 fixes
typically helps.
<DT><I>Fix viscosity comes before fix ave/spatial</I>
<DD>The order of these 2 fixes in your input script is such that
fix viscosity comes first. If you are using fix ave/spatial
to measure the velocity profile induced by fix viscosity, then
this may cause a glitch in the profile since you are averaging
immediately after swaps have occurred. Flipping the order
of the 2 fixes typically helps.
<DT><I>Group for fix_modify temp != fix group</I>
<DD>The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do.
<DT><I>Improper problem: %d %d %d %d %d %d</I>
<DD>Conformation of the 4 listed improper atoms is extreme; you may want
to check your simulation geometry.
<DT><I>Kspace_modify slab param < 2.0 may cause unphysical behavior</I>
<DD>The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap.
<DT><I>Less insertions than requested</I>
<DD>Less atom insertions occurred on this timestep due to the fix pour
command than were scheduled. This is probably because there were too
many overlaps detected.
<DT><I>Lost atoms: original %.15g current %.15g</I>
<DD>A thermodynamic computation has detected lost atoms.
<DT><I>Mismatch between velocity and compute groups</I>
<DD>The temperature computation used by the velocity command will not be
on the same group of atoms that velocities are being set for.
<DT><I>More than one compute centro/atom</I>
<DD>It is not efficient to use compute centro/atom more than once.
<DT><I>More than one compute cluster/atom</I>
<DD>It is not efficient to use compute cluster/atom more than once.
<DT><I>More than one compute cna/atom defined</I>
<DD>It is not efficient to use compute cna/atom more than once.
<DT><I>More than one compute coord/atom</I>
<DD>It is not efficient to use compute coord/atom more than once.
<DT><I>More than one compute damage/atom</I>
<DD>It is not efficient to use compute ke/atom more than once.
<DT><I>More than one compute ke/atom</I>
<DD>It is not efficient to use compute ke/atom more than once.
<DT><I>More than one fix poems</I>
<DD>It is not efficient to use fix poems more than once.
<DT><I>More than one fix rigid</I>
<DD>It is not efficient to use fix rigid more than once.
<DT><I>New thermo_style command, previous thermo_modify settings will be lost</I>
<DD>If a thermo_style command is used after a thermo_modify command, the
settings changed by the thermo_modify command will be reset to their
default values. This is because the thermo_modify commmand acts on
the currently defined thermo style, and a thermo_style command creates
a new style.
<DT><I>No fixes defined, atoms won't move</I>
<DD>If you are not using a fix like nve, nvt, npt then atom velocities and
coordinates will not be updated during timestepping.
<DT><I>No joints between rigid bodies, use fix rigid instead</I>
<DD>The bodies defined by fix poems are not connected by joints. POEMS
will integrate the body motion, but it would be more efficient to use
fix rigid.
<DT><I>Not using real units with pair reax</I>
<DD>This is most likely an error, unless you have created your own ReaxFF
parameter file in a different set of units.
<DT><I>One or more atoms are time integrated more than once</I>
<DD>This is probably an error since you typically do not want to
advance the positions or velocities of an atom more than once
per timestep.
<DT><I>One or more compute molecules has atoms not in group</I>
<DD>The group used in a compute command that operates on moleclues does
not include all the atoms in some molecules. This is probably not
what you want.
<DT><I>One or more respa levels compute no forces</I>
<DD>This is computationally inefficient.
<DT><I>Pair COMB charge %.10f with force %.10f hit max barrier</I>
<DD>Something is possibly wrong with your model.
<DT><I>Pair COMB charge %.10f with force %.10f hit min barrier</I>
<DD>Something is possibly wrong with your model.
<DT><I>Pair dsmc: num_of_collisions > number_of_A</I>
<DD>Collision model in DSMC is breaking down.
<DT><I>Pair dsmc: num_of_collisions > number_of_B</I>
<DD>Collision model in DSMC is breaking down.
<DT><I>Particle deposition was unsuccessful</I>
<DD>The fix deposit command was not able to insert as many atoms as
needed. The requested volume fraction may be too high, or other atoms
may be in the insertion region.
<DT><I>Reducing PPPM order b/c stencil extends beyond neighbor processor</I>
<DD>LAMMPS is attempting this in order to allow the simulation
to run. It should not effect the PPPM accuracy.
<DT><I>Replacing a fix, but new group != old group</I>
<DD>The ID and style of a fix match for a fix you are changing with a fix
command, but the new group you are specifying does not match the old
group.
<DT><I>Replicating in a non-periodic dimension</I>
<DD>The parameters for a replicate command will cause a non-periodic
dimension to be replicated; this may cause unwanted behavior.
<DT><I>Resetting reneighboring criteria during PRD</I>
<DD>A PRD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation.
<DT><I>Resetting reneighboring criteria during TAD</I>
<DD>A TAD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation.
<DT><I>Resetting reneighboring criteria during minimization</I>
<DD>Minimization requires that neigh_modify settings be delay = 0, every =
1, check = yes. Since these settings were not in place, LAMMPS
changed them and will restore them to their original values after the
minimization.
<DT><I>Restart file used different # of processors</I>
<DD>The restart file was written out by a LAMMPS simulation running on a
different number of processors. Due to round-off, the trajectories of
your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors.
<DT><I>Restart file used different 3d processor grid</I>
<DD>The restart file was written out by a LAMMPS simulation running on a
different 3d grid of processors. Due to round-off, the trajectories
of your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors.
<DT><I>Restart file used different boundary settings, using restart file values</I>
<DD>Your input script cannot change these restart file settings.
<DT><I>Restart file used different newton bond setting, using restart file value</I>
<DD>The restart file value will override the setting in the input script.
<DT><I>Restart file used different newton pair setting, using input script value</I>
<DD>The input script value will override the setting in the restart file.
<DT><I>Restart file version does not match LAMMPS version</I>
<DD>This may cause problems when reading the restart file.
<DT><I>Running PRD with only one replica</I>
<DD>This is allowed, but you will get no parallel speed-up.
<DT><I>SRD bin shifting turned on due to small lamda</I>
<DD>This is done to try to preserve accuracy.
<DT><I>SRD bin size for fix srd differs from user request</I>
<DD>Check if the new bin size is acceptable.
<DT><I>SRD bins for fix srd are not cubic enough</I>
<DD>Check if the bin shape is acceptable.
<DT><I>SRD particle %d started inside big particle %d on step %d bounce %d</I>
<DD>This may not be a problem, but indicates one or more SRD particles are
being left inside solute particles.
<DT><I>Shake determinant < 0.0</I>
<DD>The determinant of the quadratic equation being solved for a single
cluster specified by the fix shake command is numerically suspect. LAMMPS
will set it to 0.0 and continue.
<DT><I>Should not allow rigid bodies to bounce off relecting walls</I>
<DD>LAMMPS allows this, but their dynamics are not computed correctly.
<DT><I>System is not charge neutral, net charge = %g</I>
<DD>The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM.
<DT><I>Table inner cutoff >= outer cutoff</I>
<DD>You specified an inner cutoff for a Coulombic table that is longer
than the global cutoff. Probably not what you wanted.
<DT><I>Temperature for MSST is not for group all</I>
<DD>User-assigned temperature to MSST fix does not compute temperature for
all atoms. Since MSST computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by MSST could be inaccurate.
<DT><I>Temperature for NPT is not for group all</I>
<DD>User-assigned temperature to NPT fix does not compute temperature for
all atoms. Since NPT computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by NPT could be inaccurate.
<DT><I>Temperature for fix modify is not for group all</I>
<DD>The temperature compute is being used with a pressure calculation
which does operate on group all, so this may be inconsistent.
<DT><I>Temperature for thermo pressure is not for group all</I>
<DD>User-assigned temperature to thermo via the thermo_modify command does
not compute temperature for all atoms. Since thermo computes a global
pressure, the kinetic energy contribution from the temperature is
assumed to also be for all atoms. Thus the pressure printed by thermo
could be inaccurate.
<DT><I>Too many common neighbors in CNA %d times</I>
<DD>More than the maximum # of neighbors was found multiple times. This
was unexpected.
<DT><I>Too many inner timesteps in fix ttm</I>
<DD>Self-explanatory.
<DT><I>Too many neighbors in CNA for %d atoms</I>
<DD>More than the maximum # of neighbors was found multiple times. This
was unexpected.
<DT><I>Use special bonds = 0,1,1 with bond style fene/expand</I>
<DD>Most FENE models need this setting for the special_bonds command.
<DT><I>Use special bonds = 0,1,1 with bond style fene</I>
<DD>Most FENE models need this setting for the special_bonds command.
<DT><I>Using compute temp/deform with inconsistent fix deform remap option</I>
<DD>Fix nvt/sllod assumes deforming atoms have a velocity profile provided
by "remap v" or "remap none" as a fix deform option.
<DT><I>Using compute temp/deform with no fix deform defined</I>
<DD>This is probably an error, since it makes little sense to use
compute temp/deform in this case.
<DT><I>Using pair tail corrections with nonperiodic system</I>
<DD>This is probably a bogus thing to do, since tail corrections are
computed by integrating the density of a periodic system out to
infinity.
</DL>
</HTML>
diff --git a/doc/Section_errors.txt b/doc/Section_errors.txt
index 2bf511d92..9c44470ab 100644
--- a/doc/Section_errors.txt
+++ b/doc/Section_errors.txt
@@ -1,6613 +1,6614 @@
"Previous Section"_Section_python.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_history.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
12. Errors :h3
-This section describes the various kinds of errors you can encounter
-when using LAMMPS.
+This section describes the errors you can encounter when using LAMMPS,
+either conceptually, or as printed out by the program.
12.1 "Common problems"_#err_1
12.2 "Reporting bugs"_#err_2
12.3 "Error & warning messages"_#err_3 :all(b)
+:line
:line
12.1 Common problems :link(err_1),h4
If two LAMMPS runs do not produce the same answer on different
machines or different numbers of processors, this is typically not a
bug. In theory you should get identical answers on any number of
processors and on any machine. In practice, numerical round-off can
cause slight differences and eventual divergence of molecular dynamics
phase space trajectories within a few 100s or few 1000s of timesteps.
However, the statistical properties of the two runs (e.g. average
energy or temperature) should still be the same.
If the "velocity"_velocity.html command is used to set initial atom
velocities, a particular atom can be assigned a different velocity
when the problem is run on a different number of processors or on
different machines. If this happens, the phase space trajectories of
the two simulations will rapidly diverge. See the discussion of the
{loop} option in the "velocity"_velocity.html command for details and
options that avoid this issue.
Similarly, the "create_atoms"_create_atoms.html command generates a
lattice of atoms. For the same physical system, the ordering and
numbering of atoms by atom ID may be different depending on the number
of processors.
Some commands use random number generators which may be setup to
produce different random number streams on each processor and hence
will produce different effects when run on different numbers of
processors. A commonly-used example is the "fix
langevin"_fix_langevin.html command for thermostatting.
A LAMMPS simulation typically has two stages, setup and run. Most
LAMMPS errors are detected at setup time; others like a bond
stretching too far may not occur until the middle of a run.
LAMMPS tries to flag errors and print informative error messages so
you can fix the problem. Of course, LAMMPS cannot figure out your
physics or numerical mistakes, like choosing too big a timestep,
specifying erroneous force field coefficients, or putting 2 atoms on
top of each other! If you run into errors that LAMMPS doesn't catch
that you think it should flag, please send an email to the
"developers"_http://lammps.sandia.gov/authors.html.
If you get an error message about an invalid command in your input
script, you can determine what command is causing the problem by
looking in the log.lammps file or using the "echo command"_echo.html
to see it on the screen. For a given command, LAMMPS expects certain
arguments in a specified order. If you mess this up, LAMMPS will
often flag the error, but it may read a bogus argument and assign a
value that is valid, but not what you wanted. E.g. trying to read the
string "abc" as an integer value and assigning the associated variable
a value of 0.
Generally, LAMMPS will print a message to the screen and logfile and
exit gracefully when it encounters a fatal error. Sometimes it will
print a WARNING to the screen and logfile and continue on; you can
decide if the WARNING is important or not. A WARNING message that is
generated in the middle of a run is only printed to the screen, not to
the logfile, to avoid cluttering up thermodynamic output. If LAMMPS
crashes or hangs without spitting out an error message first then it
could be a bug (see "this section"_#err_2) or one of the following
cases:
LAMMPS runs in the available memory a processor allows to be
allocated. Most reasonable MD runs are compute limited, not memory
limited, so this shouldn't be a bottleneck on most platforms. Almost
all large memory allocations in the code are done via C-style malloc's
which will generate an error message if you run out of memory.
Smaller chunks of memory are allocated via C++ "new" statements. If
you are unlucky you could run out of memory just when one of these
small requests is made, in which case the code will crash or hang (in
parallel), since LAMMPS doesn't trap on those errors.
Illegal arithmetic can cause LAMMPS to run slow or crash. This is
typically due to invalid physics and numerics that your simulation is
computing. If you see wild thermodynamic values or NaN values in your
LAMMPS output, something is wrong with your simulation. If you
suspect this is happening, it is a good idea to print out
thermodynamic info frequently (e.g. every timestep) via the
"thermo"_thermo.html so you can monitor what is happening.
Visualizing the atom movement is also a good idea to insure your model
is behaving as you expect.
In parallel, one way LAMMPS can hang is due to how different MPI
implementations handle buffering of messages. If the code hangs
without an error message, it may be that you need to specify an MPI
setting or two (usually via an environment variable) to enable
buffering or boost the sizes of messages that can be buffered.
:line
12.2 Reporting bugs :link(err_2),h4
If you are confident that you have found a bug in LAMMPS, follow these
steps.
Check the "New features and bug
fixes"_http://lammps.sandia.gov/bug.html section of the "LAMMPS WWW
site"_lws to see if the bug has already been reported or fixed or the
"Unfixed bug"_http://lammps.sandia.gov/unbug.html to see if a fix is
pending.
Check the "mailing list"_http://lammps.sandia.gov/mail.html
to see if it has been discussed before.
If not, send an email to the mailing list describing the problem with
any ideas you have as to what is causing it or where in the code the
problem might be. The developers will ask for more info if needed,
such as an input script or data files.
The most useful thing you can do to help us fix the bug is to isolate
the problem. Run it on the smallest number of atoms and fewest number
of processors and with the simplest input script that reproduces the
bug and try to identify what command or combination of commands is
causing the problem.
As a last resort, you can send an email directly to the
"developers"_http://lammps.sandia.gov/authors.html.
:line
12.3 Error & warning messages :h4,link(err_3)
These are two alphabetic lists of the "ERROR"_#error and
"WARNING"_#warn messages LAMMPS prints out and the reason why. If the
explanation here is not sufficient, the documentation for the
offending command may help.
Error and warning messages also list the source file and line number
where the error was generated. For example, this message
ERROR: Illegal velocity command (velocity.cpp:78)
means that line #78 in the file src/velocity.cpp generated the error.
Looking in the source code may help you figure out what went wrong.
Note that error messages from "user-contributed
packages"_Section_start.html#start_3 are not listed here. If such an
error occurs and is not self-explanatory, you'll need to look in the
source code or contact the author of the package.
Errors: :h4,link(error)
:dlb
{1-3 bond count is inconsistent} :dt
An inconsistency was detected when computing the number of 1-3
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined. :dd
{1-4 bond count is inconsistent} :dt
An inconsistency was detected when computing the number of 1-4
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined. :dd
{Accelerated style in input script but no fix gpu} :dt
GPU acceleration requires fix gpu in the input script. :dd
{Accelerator sharing is not currently supported on system.} :dt
You cannot use more MPI processes than accelerators on the
system as currently configured. For NVIDIA GPUs, the compute
mode must be changed using nvidia-smi to support sharing. :dd
{All angle coeffs are not set} :dt
All angle coefficients must be set in the data file or by the
angle_coeff command before running a simulation. :dd
{All bond coeffs are not set} :dt
All bond coefficients must be set in the data file or by the
bond_coeff command before running a simulation. :dd
{All dihedral coeffs are not set} :dt
All dihedral coefficients must be set in the data file or by the
dihedral_coeff command before running a simulation. :dd
{All dipole moments are not set} :dt
For atom styles that define dipole moments for each atom type, all
moments must be set in the data file or by the dipole command before
running a simulation. :dd
{All improper coeffs are not set} :dt
All improper coefficients must be set in the data file or by the
improper_coeff command before running a simulation. :dd
{All masses are not set} :dt
For atom styles that define masses for each atom type, all masses must
be set in the data file or by the mass command before running a
simulation. They must also be set before using the velocity
command. :dd
{All pair coeffs are not set} :dt
All pair coefficients must be set in the data file or by the
pair_coeff command before running a simulation. :dd
{All shapes are not set} :dt
All atom types must have a shape setting, even if the particles
are spherical. :dd
{All universe/uloop variables must have same # of values} :dt
Self-explanatory. :dd
{All variables in next command must be same style} :dt
Self-explanatory. :dd
{Angle atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
angle on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid angle. :dd
{Angle atom missing in set command} :dt
The set command cannot find one or more atoms in a particular angle on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid angle. :dd
{Angle atoms %d %d %d missing on proc %d at step} :dt
One or more of 3 atoms needed to compute a particular angle are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the angle has blown apart and an atom is
too far away. :dd
{Angle coeff for hybrid has invalid style} :dt
Angle style hybrid uses another angle style as one of its
coefficients. The angle style used in the angle_coeff command or read
from a restart file is not recognized. :dd
{Angle coeffs are not set} :dt
No angle coefficients have been assigned in the data file or via the
angle_coeff command. :dd
{Angle potential must be defined for SHAKE} :dt
When shaking angles, an angle_style potential must be used. :dd
{Angle style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Angle style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Angle style hybrid cannot use same pair style twice} :dt
Self-explanatory. :dd
{Angle table must range from 0 to 180 degrees} :dt
Self-explanatory. :dd
{Angle table parameters did not set N} :dt
List of angle table parameters must include N setting. :dd
{Angle_coeff command before angle_style is defined} :dt
Coefficients cannot be set in the data file or via the angle_coeff
command until an angle_style has been assigned. :dd
{Angle_coeff command before simulation box is defined} :dt
The angle_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Angle_coeff command when no angles allowed} :dt
The chosen atom style does not allow for angles to be defined. :dd
{Angle_style command when no angles allowed} :dt
The chosen atom style does not allow for angles to be defined. :dd
{Angles assigned incorrectly} :dt
Angles read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Angles defined but no angle types} :dt
The data file header lists angles but no angle types. :dd
{Another input script is already being processed} :dt
Cannot attempt to open a 2nd input script, when the original file is
still being processed. :dd
{Arccos of invalid value in variable formula} :dt
Argument of arccos() must be between -1 and 1. :dd
{Arcsin of invalid value in variable formula} :dt
Argument of arcsin() must be between -1 and 1. :dd
{Atom IDs must be consecutive for velocity create loop all} :dt
Self-explanatory. :dd
{Atom count changed in fix neb} :dt
This is not allowed in a NEB calculation. :dd
{Atom count is inconsistent, cannot write restart file} :dt
Sum of atoms across processors does not equal initial total count.
This is probably because you have lost some atoms. :dd
{Atom in too many rigid bodies - boost MAXBODY} :dt
Fix poems has a parameter MAXBODY (in fix_poems.cpp) which determines
the maximum number of rigid bodies a single atom can belong to (i.e. a
multibody joint). The bodies you have defined exceed this limit. :dd
{Atom sort did not operate correctly} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Atom sorting has bin size = 0.0} :dt
The neighbor cutoff is being used as the bin size, but it is zero.
Thus you must explicitly list a bin size in the atom_modify sort
command or turn off sorting. :dd
{Atom style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Atom style hybrid cannot use same atom style twice} :dt
Self-explanatory. :dd
{Atom vector in equal-style variable formula} :dt
Atom vectors generate one value per atom which is not allowed
in an equal-style variable. :dd
{Atom-style variable in equal-style variable formula} :dt
Atom-style variables generate one value per atom which is not allowed
in an equal-style variable. :dd
{Atom_modify map command after simulation box is defined} :dt
The atom_modify map command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Atom_modify sort and first options cannot be used together} :dt
Self-explanatory. :dd
{Atom_style command after simulation box is defined} :dt
The atom_style command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Attempt to pop empty stack in fix box/relax} :dt
Internal LAMMPS error. Please report it to the developers. :dd
{Attempt to push beyond stack limit in fix box/relax} :dt
Internal LAMMPS error. Please report it to the developers. :dd
{Attempting to rescale a 0.0 temperature} :dt
Cannot rescale a temperature that is already 0.0. :dd
{Bad FENE bond} :dt
Two atoms in a FENE bond have become so far apart that the bond cannot
be computed. :dd
{Bad TIP4P angle type for PPPM/TIP4P} :dt
Specified angle type is not valid. :dd
{Bad TIP4P bond type for PPPM/TIP4P} :dt
Specified bond type is not valid. :dd
{Bad grid of processors} :dt
The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on. :dd
{Bad kspace_modify slab parameter} :dt
Kspace_modify value for the slab/volume keyword must be >= 2.0. :dd
{Bad principal moments} :dt
Fix rigid did not compute the principal moments of inertia of a rigid
group of atoms correctly. :dd
{Bias compute does not calculate a velocity bias} :dt
The specified compute must compute a bias for temperature. :dd
{Bias compute does not calculate temperature} :dt
The specified compute must compute temperature. :dd
{Bias compute group does not match compute group} :dt
The specified compute must operate on the same group as the parent
compute. :dd
{Big particle in fix srd cannot be point particle} :dt
Big particles must be extended spheriods or ellipsoids. :dd
{Bigint setting in lmptype.h is invalid} :dt
Size of bigint is less than size of tagint. :dd
{Bigint setting in lmptype.h is not compatible} :dt
Bigint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Bitmapped lookup tables require int/float be same size} :dt
Cannot use pair tables on this machine, because of word sizes. Use
the pair_modify command with table 0 instead. :dd
{Bitmapped table in file does not match requested table} :dt
Setting for bitmapped table in pair_coeff command must match table
in file exactly. :dd
{Bitmapped table is incorrect length in table file} :dt
Number of table entries is not a correct power of 2. :dd
{Bond and angle potentials must be defined for TIP4P} :dt
Cannot use TIP4P pair potential unless bond and angle potentials
are defined. :dd
{Bond atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
bond on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid bond. :dd
{Bond atom missing in set command} :dt
The set command cannot find one or more atoms in a particular bond on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid bond. :dd
{Bond atoms %d %d missing on proc %d at step} :dt
One or both of 2 atoms needed to compute a particular bond are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the bond has blown apart and an atom is
too far away. :dd
{Bond coeff for hybrid has invalid style} :dt
Bond style hybrid uses another bond style as one of its coefficients.
The bond style used in the bond_coeff command or read from a restart
file is not recognized. :dd
{Bond coeffs are not set} :dt
No bond coefficients have been assigned in the data file or via the
bond_coeff command. :dd
{Bond potential must be defined for SHAKE} :dt
Cannot use fix shake unless bond potential is defined. :dd
{Bond style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Bond style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Bond style hybrid cannot use same pair style twice} :dt
Self-explanatory. :dd
{Bond style quartic cannot be used with 3,4-body interactions} :dt
No angle, dihedral, or improper styles can be defined when using
bond style quartic. :dd
{Bond style quartic requires special_bonds = 1,1,1} :dt
This is a restriction of the current bond quartic implementation. :dd
{Bond table parameters did not set N} :dt
List of bond table parameters must include N setting. :dd
{Bond table values are not increasing} :dt
The values in the tabulated file must be monotonically increasing. :dd
{Bond_coeff command before bond_style is defined} :dt
Coefficients cannot be set in the data file or via the bond_coeff
command until an bond_style has been assigned. :dd
{Bond_coeff command before simulation box is defined} :dt
The bond_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Bond_coeff command when no bonds allowed} :dt
The chosen atom style does not allow for bonds to be defined. :dd
{Bond_style command when no bonds allowed} :dt
The chosen atom style does not allow for bonds to be defined. :dd
{Bonds assigned incorrectly} :dt
Bonds read in from the data file were not assigned correctly to atoms.
This means there is something invalid about the topology definitions. :dd
{Bonds defined but no bond types} :dt
The data file header lists bonds but no bond types. :dd
{Both sides of boundary must be periodic} :dt
Cannot specify a boundary as periodic only on the lo or hi side. Must
be periodic on both sides. :dd
{Boundary command after simulation box is defined} :dt
The boundary command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Box bounds are invalid} :dt
The box boundaries specified in the read_data file are invalid. The
lo value must be less than the hi value for all 3 dimensions. :dd
{Can not specify Pxy/Pxz/Pyz in fix box/relax with non-triclinic box} :dt
Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details. :dd
{Can not specify Pxy/Pxz/Pyz in fix nvt/npt/nph with non-triclinic box} :dt
Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details. :dd
{Can only use NEB with 1-processor replicas} :dt
This is current restriction for NEB as implemented in LAMMPS. :dd
{Can only use TAD with 1-processor replicas for NEB} :dt
This is current restriction for NEB as implemented in LAMMPS. :dd
{Cannot (yet) use PPPM with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot add atoms to fix move variable} :dt
Atoms can not be added afterwards to this fix option. :dd
{Cannot change box to orthogonal when tilt is non-zero} :dt
Self-explanatory :dd
{Cannot change box with certain fixes defined} :dt
The change_box command cannot be used when fix ave/spatial or
fix/deform are defined . :dd
{Cannot change box with dumps defined} :dt
Self-explanatory. :dd
{Cannot change dump_modify every for dump dcd} :dt
The frequency of writing dump dcd snapshots cannot be changed. :dd
{Cannot change dump_modify every for dump xtc} :dt
The frequency of writing dump xtc snapshots cannot be changed. :dd
{Cannot change timestep once fix srd is setup} :dt
This is because various SRD properties depend on the timestep
size. :dd
{Cannot change timestep with fix pour} :dt
This fix pre-computes some values based on the timestep, so it cannot
be changed during a simulation run. :dd
{Cannot compute PPPM G} :dt
LAMMPS failed to compute a valid approximation for the PPPM g_ewald
factor that partitions the computation between real space and k-space. :dd
{Cannot create an atom map unless atoms have IDs} :dt
The simulation requires a mapping from global atom IDs to local atoms,
but the atoms that have been defined have no IDs. :dd
{Cannot create atoms with undefined lattice} :dt
Must use the lattice command before using the create_atoms
command. :dd
{Cannot create/grow a vector/array of pointers for %s} :dt
LAMMPS code is making an illegal call to the templated memory
allocaters, to create a vector or array of pointers. :dd
{Cannot create_atoms after reading restart file with per-atom info} :dt
The per-atom info was stored to be used when by a fix that you
may re-define. If you add atoms before re-defining the fix, then
there will not be a correct amount of per-atom info. :dd
{Cannot create_box after simulation box is defined} :dt
The create_box command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Cannot currently use pair reax with pair hybrid} :dt
This is not yet supported. :dd
{Cannot delete group all} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a compute} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a dump} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a fix} :dt
Self-explanatory. :dd
{Cannot delete group currently used by atom_modify first} :dt
Self-explanatory. :dd
{Cannot displace_atoms after reading restart file with per-atom info} :dt
This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms. :dd
{Cannot displace_box after reading restart file with per-atom info} :dt
This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms. :dd
{Cannot displace_box on a non-periodic boundary} :dt
Self-explanatory. :dd
{Cannot dump sort on atom IDs with no atom IDs defined} :dt
Self-explanatory. :dd
{Cannot evaporate atoms in atom_modify first group} :dt
This is a restriction due to the way atoms are organized in
a list to enable the atom_modify first command. :dd
{Cannot find delete_bonds group ID} :dt
Group ID used in the delete_bonds command does not exist. :dd
{Cannot have both pair_modify shift and tail set to yes} :dt
These 2 options are contradictory. :dd
{Cannot open AIREBO potential file %s} :dt
The specified AIREBO potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open COMB potential file %s} :dt
The specified COMB potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open EAM potential file %s} :dt
The specified EAM potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open EIM potential file %s} :dt
The specified EIM potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open MEAM potential file %s} :dt
The specified MEAM potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open Stillinger-Weber potential file %s} :dt
The specified SW potential file cannot be opened. Check that the path
and name are correct. :dd
{Cannot open Tersoff potential file %s} :dt
The specified Tersoff potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open dir to search for restart file} :dt
Using a "*" in the name of the restart file will open the current
directory to search for matching file names. :dd
{Cannot open dump file} :dt
The output file for the dump command cannot be opened. Check that the
path and name are correct. :dd
{Cannot open file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/correlate file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/histo file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/spatial file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/time file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix poems file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix print file %s} :dt
The output file generated by the fix print command cannot be opened :dd
{Cannot open fix qeq/comb file %s} :dt
The output file for the fix qeq/combs command cannot be opened.
Check that the path and name are correct. :dd
{Cannot open fix reax/bonds file %s} :dt
The output file for the fix reax/bonds command cannot be opened.
Check that the path and name are correct. :dd
{Cannot open fix tmd file %s} :dt
The output file for the fix tmd command cannot be opened. Check that
the path and name are correct. :dd
{Cannot open fix ttm file %s} :dt
The output file for the fix ttm command cannot be opened. Check that
the path and name are correct. :dd
{Cannot open gzipped file} :dt
LAMMPS is attempting to open a gzipped version of the specified file
but was unsuccessful. Check that the path and name are correct. :dd
{Cannot open input script %s} :dt
Self-explanatory. :dd
{Cannot open log.lammps} :dt
The default LAMMPS log file cannot be opened. Check that the
directory you are running in allows for files to be created. :dd
{Cannot open logfile %s} :dt
The LAMMPS log file specified in the input script cannot be opened.
Check that the path and name are correct. :dd
{Cannot open logfile} :dt
The LAMMPS log file named in a command-line argument cannot be opened.
Check that the path and name are correct. :dd
{Cannot open pair_write file} :dt
The specified output file for pair energies and forces cannot be
opened. Check that the path and name are correct. :dd
{Cannot open restart file %s} :dt
Self-explanatory. :dd
{Cannot open screen file} :dt
The screen file specified as a command-line argument cannot be
opened. Check that the directory you are running in allows for files
to be created. :dd
{Cannot open universe log file} :dt
For a multi-partition run, the master log file cannot be opened.
Check that the directory you are running in allows for files to be
created. :dd
{Cannot open universe screen file} :dt
For a multi-partition run, the master screen file cannot be opened.
Check that the directory you are running in allows for files to be
created. :dd
{Cannot read_data after simulation box is defined} :dt
The read_data command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Cannot read_restart after simulation box is defined} :dt
The read_restart command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Cannot redefine variable as a different style} :dt
An equal-style variable can be re-defined but only if it was
originally an equal-style variable. :dd
{Cannot replicate 2d simulation in z dimension} :dt
The replicate command cannot replicate a 2d simulation in the z
dimension. :dd
{Cannot replicate with fixes that store atom quantities} :dt
Either fixes are defined that create and store atom-based vectors or a
restart file was read which included atom-based vectors for fixes.
The replicate command cannot duplicate that information for new atoms.
You should use the replicate command before fixes are applied to the
system. :dd
{Cannot reset timestep with a dynamic region defined} :dt
Dynamic regions (see the region command) have a time dependence.
Thus you cannot change the timestep when one or more of these
are defined. :dd
{Cannot reset timestep with a time-dependent fix defined} :dt
You cannot reset the timestep when a fix that keeps track of elapsed
time is in place. :dd
{Cannot reset timestep with dump file already written to} :dt
Changing the timestep will confuse when a dump file is written. Use
the undump command, then restart the dump file. :dd
{Cannot reset timestep with restart file already written} :dt
Changing the timestep will confuse when a restart file is written.
Use the "restart 0" command to turn off restarts, then start them
again. :dd
{Cannot restart fix rigid/nvt with different # of chains} :dt
This is because the restart file contains per-chain info. :dd
{Cannot run 2d simulation with nonperiodic Z dimension} :dt
Use the boundary command to make the z dimension periodic in order to
run a 2d simulation. :dd
{Cannot set both respa pair and inner/middle/outer} :dt
In the rRESPA integrator, you must compute pairwise potentials either
all together (pair), or in pieces (inner/middle/outer). You can't do
both. :dd
{Cannot set dipole for this atom style} :dt
This atom style does not support dipole settings for each atom type. :dd
{Cannot set dump_modify flush for dump xtc} :dt
Self-explanatory. :dd
{Cannot set mass for this atom style} :dt
This atom style does not support mass settings for each atom type.
Instead they are defined on a per-atom basis in the data file. :dd
{Cannot set non-zero image flag for non-periodic dimension} :dt
Self-explanatory. :dd
{Cannot set non-zero z velocity for 2d simulation} :dt
Self-explanatory. :dd
{Cannot set respa middle without inner/outer} :dt
In the rRESPA integrator, you must define both a inner and outer
setting in order to use a middle setting. :dd
{Cannot set shape for this atom style} :dt
The atom style does not support this setting. :dd
{Cannot set this attribute for this atom style} :dt
The attribute being set does not exist for the defined atom style. :dd
{Cannot set variable z velocity for 2d simulation} :dt
Self-explanatory. :dd
{Cannot skew triclinic box in z for 2d simulation} :dt
Self-explanatory. :dd
{Cannot use Ewald with 2d simulation} :dt
The kspace style ewald cannot be used in 2d simulations. You can use
2d Ewald in a 3d simulation; see the kspace_modify command. :dd
{Cannot use Ewald with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot use NEB unless atom map exists} :dt
Use the atom_modify command to create an atom map. :dd
{Cannot use NEB with a single replica} :dt
Self-explanatory. :dd
{Cannot use NEB with atom_modify sort enabled} :dt
This is current restriction for NEB implemented in LAMMPS. :dd
{Cannot use PPPM with 2d simulation} :dt
The kspace style pppm cannot be used in 2d simulations. You can use
2d PPPM in a 3d simulation; see the kspace_modify command. :dd
{Cannot use PRD with a time-dependent fix defined} :dt
PRD alters the timestep in ways that will mess up these fixes. :dd
{Cannot use PRD with a time-dependent region defined} :dt
PRD alters the timestep in ways that will mess up these regions. :dd
{Cannot use PRD with atom_modify sort enabled} :dt
This is a current restriction of PRD. You must turn off sorting,
which is enabled by default, via the atom_modify command. :dd
{Cannot use PRD with multi-processor replicas unless atom map exists} :dt
Use the atom_modify command to create an atom map. :dd
{Cannot use TAD unless atom map exists for NEB} :dt
See atom_modify map command to set this. :dd
{Cannot use TAD with a single replica for NEB} :dt
NEB requires multiple replicas. :dd
{Cannot use TAD with atom_modify sort enabled for NEB} :dt
This is a current restriction of NEB. :dd
{Cannot use a damped dynamics min style with fix box/relax} :dt
This is a current restriction in LAMMPS. Use another minimizer
style. :dd
{Cannot use a damped dynamics min style with per-atom DOF} :dt
This is a current restriction in LAMMPS. Use another minimizer
style. :dd
{Cannot use compute cluster/atom unless atoms have IDs} :dt
Atom IDs are used to identify clusters. :dd
{Cannot use cwiggle in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use delete_atoms unless atoms have IDs} :dt
Your atoms do not have IDs, so the delete_atoms command cannot be
used. :dd
{Cannot use delete_bonds with non-molecular system} :dt
Your choice of atom style does not have bonds. :dd
{Cannot use fix TMD unless atom map exists} :dt
Using this fix requires the ability to lookup an atom index, which is
provided by an atom map. An atom map does not exist (by default) for
non-molecular problems. Using the atom_modify map command will force
an atom map to be created. :dd
{Cannot use fix ave/spatial z for 2 dimensional model} :dt
Self-explanatory. :dd
{Cannot use fix bond/break with non-molecular systems} :dt
Self-explanatory. :dd
{Cannot use fix bond/create with non-molecular systems} :dt
Self-explanatory. :dd
{Cannot use fix box/relax on a 2nd non-periodic dimension} :dt
When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic. :dd
{Cannot use fix box/relax on a non-periodic dimension} :dt
When specifying a diagonal pressure component, the dimension must be
periodic. :dd
{Cannot use fix deform on a 2nd non-periodic boundary} :dt
When specifying a tilt factor change, the 2nd of the two dimensions
must be periodic. E.g. if the xy tilt is specified, then the y
dimension must be periodic. :dd
{Cannot use fix deform on a non-periodic boundary} :dt
When specifying a change is a box dimension, the dimension must be
periodic. :dd
{Cannot use fix deform trate on a box with zero tilt} :dt
The trate style alters the current strain. :dd
{Cannot use fix enforce2d with 3d simulation} :dt
Self-explanatory. :dd
{Cannot use fix msst without per-type mass defined} :dt
Self-explanatory. :dd
{Cannot use fix npt and fix deform on same component of stress tensor} :dt
This would be changing the same box dimension twice. :dd
{Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension} :dt
When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic. :dd
{Cannot use fix nvt/npt/nph on a non-periodic dimension} :dt
When specifying a diagonal pressure component, the dimension must be
periodic. :dd
{Cannot use fix pour with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot use fix press/berendsen and fix deform on same component of stress tensor} :dt
These commands both change the box size/shape, so you cannot use both
together. :dd
{Cannot use fix press/berendsen on a non-periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix press/berendsen with triclinic box} :dt
Self-explanatory. :dd
{Cannot use fix reax/bonds without pair_style reax} :dt
Self-explantory. :dd
{Cannot use fix shake with non-molecular system} :dt
Your choice of atom style does not have bonds. :dd
{Cannot use fix ttm with 2d simulation} :dt
This is a current restriction of this fix due to the grid it creates. :dd
{Cannot use fix ttm with triclinic box} :dt
This is a current restriction of this fix due to the grid it creates. :dd
{Cannot use fix wall in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use fix wall/reflect in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall/reflect zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd more than once} :dt
Nor is their a need to since multiple walls can be specified
in one command. :dd
{Cannot use fix wall/srd without fix srd} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use force/neigh with triclinic box} :dt
This is a current limitation of the GPU implementation
in LAMMPS. :dd
{Cannot use kspace solver on system with no charge} :dt
No atoms in system have a non-zero charge. :dd
{Cannot use neigh_modify exclude with GPU neighbor builds} :dt
This is a current limitation of the GPU implementation
in LAMMPS. :dd
{Cannot use neighbor bins - box size << cutoff} :dt
Too many neighbor bins will be created. This typically happens when
the simulation box is very small in some dimension, compared to the
neighbor cutoff. Use the "nsq" style instead of "bin" style. :dd
{Cannot use newton pair with GPU CHARMM pair style} :dt
See the newton command to change the setting. :dd
{Cannot use newton pair with GPU Gay-Berne pair style} :dt
See the newton command to change the setting. :dd
{Cannot use newton pair with GPU LJ pair style} :dt
See the newton command to change the setting. :dd
{Cannot use newton pair with GPU LJ96 pair style} :dt
See the newton command to change the setting. :dd
{Cannot use non-zero forces in an energy minimization} :dt
Fix setforce cannot be used in this manner. Use fix addforce
instead. :dd
{Cannot use nonperiodic boundares with fix ttm} :dt
This fix requires a fully periodic simulation box. :dd
{Cannot use nonperiodic boundaries with Ewald} :dt
For kspace style ewald, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension. :dd
{Cannot use nonperiodic boundaries with PPPM} :dt
For kspace style pppm, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension. :dd
{Cannot use pair hybrid with GPU neighbor builds} :dt
See documentation for fix gpu. :dd
{Cannot use pair tail corrections with 2d simulations} :dt
The correction factors are only currently defined for 3d systems. :dd
{Cannot use ramp in variable formula between runs} :dt
This is because the ramp() function is time dependent. :dd
{Cannot use region INF or EDGE when box does not exist} :dt
Regions that extend to the box boundaries can only be used after the
create_box command has been used. :dd
{Cannot use set atom with no atom IDs defined} :dt
Atom IDs are not defined, so they cannot be used to identify an atom. :dd
{Cannot use swiggle in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use variable energy with constant force in fix addforce} :dt
This is because for constant force, LAMMPS can compute the change
in energy directly. :dd
{Cannot use variable every setting for dump dcd} :dt
The format of DCD dump files requires snapshots be output
at a constant frequency. :dd
{Cannot use variable every setting for dump xtc} :dt
The format of this file requires snapshots at regular intervals. :dd
{Cannot use vdisplace in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use velocity create loop all unless atoms have IDs} :dt
Atoms in the simulation to do not have IDs, so this style
of velocity creation cannot be performed. :dd
{Cannot use wall in periodic dimension} :dt
Self-explanatory. :dd
{Cannot wiggle and shear fix wall/gran} :dt
Cannot specify both options at the same time. :dd
{Cannot zero momentum of 0 atoms} :dt
The collection of atoms for which momentum is being computed has no
atoms. :dd
{Change_box command before simulation box is defined} :dt
Self-explanatory. :dd
{Change_box operation is invalid} :dt
Cannot change orthogonal box to orthogonal or a triclinic box to
triclinic. :dd
{Communicate group != atom_modify first group} :dt
Self-explanatory. :dd
{Compute ID for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Compute ID for compute reduce does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix store/state does not exist} :dt
Self-explanatory. :dd
{Compute ID must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Compute angle/local used when angles are not allowed} :dt
The atom style does not support angles. :dd
{Compute atom/molecule compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate per-atom values} :dt
Self-explanatory. :dd
{Compute atom/molecule fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate per-atom values} :dt
Self-explanatory. :dd
{Compute atom/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute atom/molecule variable is not atom-style variable} :dt
Self-explanatory. :dd
{Compute bond/local used when bonds are not allowed} :dt
The atom style does not support bonds. :dd
{Compute centro/atom requires a pair style be defined} :dt
This is because the computation of the centro-symmetry values
uses a pairwise neighbor list. :dd
{Compute cluster/atom cutoff is longer than pairwise cutoff} :dt
Cannot identify clusters beyond cutoff. :dd
{Compute cluster/atom requires a pair style be defined} :dt
This is so that the pair style defines a cutoff distance which
is used to find clusters. :dd
{Compute cna/atom cutoff is longer than pairwise cutoff} :dt
Self-explantory. :dd
{Compute cna/atom requires a pair style be defined} :dt
Self-explantory. :dd
{Compute com/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute coord/atom cutoff is longer than pairwise cutoff} :dt
Cannot compute coordination at distances longer than the pair cutoff,
since those atoms are not in the neighbor list. :dd
{Compute coord/atom requires a pair style be defined} :dt
Self-explantory. :dd
{Compute damage/atom requires peridynamic potential} :dt
Damage is a Peridynamic-specific metric. It requires you
to be running a Peridynamics simulation. :dd
{Compute dihedral/local used when dihedrals are not allowed} :dt
The atom style does not support dihedrals. :dd
{Compute does not allow an extra compute or fix to be reset} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Compute erotate/asphere cannot be used with atom attributes diameter or rmass} :dt
These attributes override the shape and mass settings, so cannot be
used. :dd
{Compute erotate/asphere requires atom attributes angmom, quat, shape} :dt
An atom style that defines these attributes must be used. :dd
{Compute erotate/asphere requires extended particles} :dt
This compute cannot be used with point paritlces. :dd
{Compute erotate/sphere requires atom attribute omega} :dt
An atom style that defines this attribute must be used. :dd
{Compute erotate/sphere requires atom attribute radius or shape} :dt
An atom style that defines these attributes must be used. :dd
{Compute erotate/sphere requires spherical particle shapes} :dt
Self-explanatory. :dd
{Compute event/displace has invalid fix event assigned} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Compute group/group group ID does not exist} :dt
Self-explanatory. :dd
{Compute gyration/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute ke/atom} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute pe/atom} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute stress/atom} :dt
Self-explanatory. :dd
{Compute improper/local used when impropers are not allowed} :dt
The atom style does not support impropers. :dd
{Compute msd/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute pair must use group all} :dt
Pair styles accumlate energy on all atoms. :dd
{Compute pe must use group all} :dt
Energies computed by potentials (pair, bond, etc) are computed on all
atoms. :dd
{Compute pressure must use group all} :dt
Virial contributions computed by potentials (pair, bond, etc) are
computed on all atoms. :dd
{Compute pressure temperature ID does not compute temperature} :dt
The compute ID assigned to a pressure computation must compute
temperature. :dd
{Compute property/atom for atom property that isn't allocated} :dt
Self-explanatory. :dd
{Compute property/local cannot use these inputs together} :dt
Only inputs that generate the same number of datums can be used
togther. E.g. bond and angle quantities cannot be mixed. :dd
{Compute property/local for property that isn't allocated} :dt
Self-explanatory. :dd
{Compute property/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute rdf requires a pair style be defined} :dt
Self-explanatory. :dd
{Compute reduce compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute reduce compute calculates global values} :dt
A compute that calculates peratom or local values is required. :dd
{Compute reduce compute does not calculate a local array} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a local vector} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute reduce fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute reduce fix calculates global values} :dt
A fix that calculates peratom or local values is required. :dd
{Compute reduce fix does not calculate a local array} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a local vector} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute reduce replace requires min or max mode} :dt
Self-explanatory. :dd
{Compute reduce variable is not atom-style variable} :dt
Self-explanatory. :dd
{Compute temp/asphere cannot be used with atom attributes diameter or rmass} :dt
These attributes override the shape and mass settings, so cannot be
used. :dd
{Compute temp/asphere requires atom attributes angmom, quat, shape} :dt
An atom style that defines these attributes must be used. :dd
{Compute temp/asphere requires extended particles} :dt
This compute cannot be used with point paritlces. :dd
{Compute temp/partial cannot use vz for 2d systemx} :dt
Self-explanatory. :dd
{Compute temp/profile cannot bin z for 2d systems} :dt
Self-explanatory. :dd
{Compute temp/profile cannot use vz for 2d systemx} :dt
Self-explanatory. :dd
{Compute temp/sphere requires atom attribute omega} :dt
An atom style that defines this attribute must be used. :dd
{Compute temp/sphere requires atom attribute radius or shape} :dt
An atom style that defines these attributes must be used. :dd
{Compute temp/sphere requires spherical particle shapes} :dt
Self-explanatory. :dd
{Compute ti kspace style does not exist} :dt
Self-explanatory. :dd
{Compute ti pair style does not exist} :dt
Self-explanatory. :dd
{Compute ti tail when pair style does not compute tail corrections} :dt
Self-explanatory. :dd
{Compute used in variable between runs is not current} :dt
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info. :dd
{Compute used in variable thermo keyword between runs is not current} :dt
Some thermo keywords rely on a compute to calculate their value(s).
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info. :dd
{Computed temperature for fix temp/berendsen cannot be 0.0} :dt
Self-explanatory. :dd
{Computed temperature for fix temp/rescale cannot be 0.0} :dt
Cannot rescale the temperature to a new value if the current
temperature is 0.0. :dd
{Could not count initial bonds in fix bond/create} :dt
Could not find one of the atoms in a bond on this processor. :dd
{Could not create 3d FFT plan} :dt
The FFT setup in pppm failed. :dd
{Could not create 3d remap plan} :dt
The FFT setup in pppm failed. :dd
{Could not find atom_modify first group ID} :dt
Self-explanatory. :dd
{Could not find compute ID for PRD} :dt
Self-explanatory. :dd
{Could not find compute ID for TAD} :dt
Self-explanatory. :dd
{Could not find compute ID for temperature bias} :dt
Self-explanatory. :dd
{Could not find compute ID to delete} :dt
Self-explanatory. :dd
{Could not find compute displace/atom fix ID} :dt
Self-explanatory. :dd
{Could not find compute event/displace fix ID} :dt
Self-explanatory. :dd
{Could not find compute group ID} :dt
Self-explanatory. :dd
{Could not find compute heat/flux compute ID} :dt
Self-explanatory. :dd
{Could not find compute msd fix ID} :dt
Self-explanatory. :dd
{Could not find compute pressure temperature ID} :dt
The compute ID for calculating temperature does not exist. :dd
{Could not find compute_modify ID} :dt
Self-explanatory. :dd
{Could not find delete_atoms group ID} :dt
Group ID used in the delete_atoms command does not exist. :dd
{Could not find delete_atoms region ID} :dt
Region ID used in the delete_atoms command does not exist. :dd
{Could not find displace_atoms group ID} :dt
Group ID used in the displace_atoms command does not exist. :dd
{Could not find displace_box group ID} :dt
Group ID used in the displace_box command does not exist. :dd
{Could not find dump cfg compute ID} :dt
Self-explanatory. :dd
{Could not find dump cfg fix ID} :dt
Self-explanatory. :dd
{Could not find dump cfg variable name} :dt
Self-explanatory. :dd
{Could not find dump custom compute ID} :dt
The compute ID needed by dump custom to compute a per-atom quantity
does not exist. :dd
{Could not find dump custom fix ID} :dt
Self-explanatory. :dd
{Could not find dump custom variable name} :dt
Self-explanatory. :dd
{Could not find dump group ID} :dt
A group ID used in the dump command does not exist. :dd
{Could not find dump local compute ID} :dt
Self-explanatory. :dd
{Could not find dump local fix ID} :dt
Self-explanatory. :dd
{Could not find dump modify compute ID} :dt
Self-explanatory. :dd
{Could not find dump modify fix ID} :dt
Self-explanatory. :dd
{Could not find dump modify variable name} :dt
Self-explanatory. :dd
{Could not find fix ID to delete} :dt
Self-explanatory. :dd
{Could not find fix group ID} :dt
A group ID used in the fix command does not exist. :dd
{Could not find fix msst compute ID} :dt
Self-explanatory. :dd
{Could not find fix poems group ID} :dt
A group ID used in the fix poems command does not exist. :dd
{Could not find fix recenter group ID} :dt
A group ID used in the fix recenter command does not exist. :dd
{Could not find fix rigid group ID} :dt
A group ID used in the fix rigid command does not exist. :dd
{Could not find fix srd group ID} :dt
Self-explanatory. :dd
{Could not find fix_modify ID} :dt
A fix ID used in the fix_modify command does not exist. :dd
{Could not find fix_modify pressure ID} :dt
The compute ID for computing pressure does not exist. :dd
{Could not find fix_modify temperature ID} :dt
The compute ID for computing temperature does not exist. :dd
{Could not find group delete group ID} :dt
Self-explanatory. :dd
{Could not find/initialize a specified accelerator device} :dt
Your GPU setup is invalid. :dd
{Could not find set group ID} :dt
Group ID specified in set command does not exist. :dd
{Could not find thermo compute ID} :dt
Compute ID specified in thermo_style command does not exist. :dd
{Could not find thermo custom compute ID} :dt
The compute ID needed by thermo style custom to compute a requested
quantity does not exist. :dd
{Could not find thermo custom fix ID} :dt
The fix ID needed by thermo style custom to compute a requested
quantity does not exist. :dd
{Could not find thermo custom variable name} :dt
Self-explanatory. :dd
{Could not find thermo fix ID} :dt
Fix ID specified in thermo_style command does not exist. :dd
{Could not find thermo_modify pressure ID} :dt
The compute ID needed by thermo style custom to compute pressure does
not exist. :dd
{Could not find thermo_modify temperature ID} :dt
The compute ID needed by thermo style custom to compute temperature does
not exist. :dd
{Could not find undump ID} :dt
A dump ID used in the undump command does not exist. :dd
{Could not find velocity group ID} :dt
A group ID used in the velocity command does not exist. :dd
{Could not find velocity temperature ID} :dt
The compute ID needed by the velocity command to compute temperature
does not exist. :dd
{Could not grab element entry from EIM potential file} :dt
Self-explanatory :dd
{Could not grab global entry from EIM potential file} :dt
Self-explanatory. :dd
{Could not grab pair entry from EIM potential file} :dt
Self-explanatory. :dd
{Could not set finite-size particle attribute in fix rigid} :dt
The particle has a finite size but its attributes could not be
determined. :dd
{Coulomb cutoffs of pair hybrid sub-styles do not match} :dt
If using a Kspace solver, all Coulomb cutoffs of long pair styles must
be the same. :dd
{Cound not find dump_modify ID} :dt
Self-explanatory. :dd
{Create_atoms command before simulation box is defined} :dt
The create_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Create_atoms region ID does not exist} :dt
A region ID used in the create_atoms command does not exist. :dd
{Create_box region ID does not exist} :dt
A region ID used in the create_box command does not exist. :dd
{Create_box region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the create_box command. :dd
{Cyclic loop in joint connections} :dt
Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a ring (or cycle). :dd
{Degenerate lattice primitive vectors} :dt
Invalid set of 3 lattice vectors for lattice command. :dd
{Delete region ID does not exist} :dt
Self-explanatory. :dd
{Delete_atoms command before simulation box is defined} :dt
The delete_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Delete_atoms cutoff > neighbor cutoff} :dt
Cannot delete atoms further away than a processor knows about. :dd
{Delete_atoms requires a pair style be defined} :dt
This is because atom deletion within a cutoff uses a pairwise
neighbor list. :dd
{Delete_bonds command before simulation box is defined} :dt
The delete_bonds command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Delete_bonds command with no atoms existing} :dt
No atoms are yet defined so the delete_bonds command cannot be used. :dd
{Deposition region extends outside simulation box} :dt
Self-explanatory. :dd
{Did not assign all atoms correctly} :dt
Atoms read in from a data file were not assigned correctly to
processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box. :dd
{Did not find all elements in MEAM library file} :dt
The requested elements were not found in the MEAM file. :dd
{Did not find fix shake partner info} :dt
Could not find bond partners implied by fix shake command. This error
can be triggered if the delete_bonds command was used before fix
shake, and it removed bonds without resetting the 1-2, 1-3, 1-4
weighting list via the special keyword. :dd
{Did not find keyword in table file} :dt
Keyword used in pair_coeff command was not found in table file. :dd
{Did not set temp for fix rigid/nvt} :dt
The temp keyword must be used. :dd
{Dihedral atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
dihedral on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid dihedral. :dd
{Dihedral atom missing in set command} :dt
The set command cannot find one or more atoms in a particular dihedral
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid dihedral. :dd
{Dihedral atoms %d %d %d %d missing on proc %d at step} :dt
One or more of 4 atoms needed to compute a particular dihedral are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the dihedral has blown apart and an atom is
too far away. :dd
{Dihedral charmm is incompatible with Pair style} :dt
Dihedral style charmm must be used with a pair style charmm
in order for the 1-4 epsilon/sigma parameters to be defined. :dd
{Dihedral coeff for hybrid has invalid style} :dt
Dihedral style hybrid uses another dihedral style as one of its
coefficients. The dihedral style used in the dihedral_coeff command
or read from a restart file is not recognized. :dd
{Dihedral coeffs are not set} :dt
No dihedral coefficients have been assigned in the data file or via
the dihedral_coeff command. :dd
{Dihedral style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Dihedral style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Dihedral style hybrid cannot use same dihedral style twice} :dt
Self-explanatory. :dd
{Dihedral_coeff command before dihedral_style is defined} :dt
Coefficients cannot be set in the data file or via the dihedral_coeff
command until an dihedral_style has been assigned. :dd
{Dihedral_coeff command before simulation box is defined} :dt
The dihedral_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Dihedral_coeff command when no dihedrals allowed} :dt
The chosen atom style does not allow for dihedrals to be defined. :dd
{Dihedral_style command when no dihedrals allowed} :dt
The chosen atom style does not allow for dihedrals to be defined. :dd
{Dihedrals assigned incorrectly} :dt
Dihedrals read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Dihedrals defined but no dihedral types} :dt
The data file header lists dihedrals but no dihedral types. :dd
{Dimension command after simulation box is defined} :dt
The dimension command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Dipole command before simulation box is defined} :dt
The dipole command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Displace_atoms command before simulation box is defined} :dt
The displace_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Displace_box command before simulation box is defined} :dt
Self-explanatory. :dd
{Displace_box tilt factors require triclinic box} :dt
Cannot use tilt factors unless the simulation box is
non-orthogonal. :dd
{Distance must be > 0 for compute event/displace} :dt
Self-explanatory. :dd
{Divide by 0 in influence function of pair peri/lps} :dt
This should not normally occur. It is likely a problem with your
model. :dd
{Divide by 0 in variable formula} :dt
Self-explanatory. :dd
{Domain too large for neighbor bins} :dt
The domain has become extremely large so that neighbor bins cannot be
used. Most likely, one or more atoms have been blown out of the
simulation box to a great distance. :dd
{Double precision is not supported on this accelerator.} :dt
In this case, you must compile the GPU library for single precision. :dd
{Dump cfg and fix not computed at compatible times} :dt
The fix must produce per-atom quantities on timesteps that dump cfg
needs them. :dd
{Dump cfg arguments must start with 'id type xs ys zs'} :dt
This is a requirement of the CFG output format. :dd
{Dump cfg requires one snapshot per file} :dt
Use the wildcard "*" character in the filename. :dd
{Dump custom and fix not computed at compatible times} :dt
The fix must produce per-atom quantities on timesteps that dump custom
needs them. :dd
{Dump custom compute does not calculate per-atom array} :dt
Self-explanatory. :dd
{Dump custom compute does not calculate per-atom vector} :dt
Self-explanatory. :dd
{Dump custom compute does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump custom compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump custom fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump custom variable is not atom-style variable} :dt
Only atom-style variables generate per-atom quantities, needed for
dump output. :dd
{Dump dcd of non-matching # of atoms} :dt
Every snapshot written by dump dcd must contain the same # of atoms. :dd
{Dump dcd requires sorting by atom ID} :dt
Use the dump_modify sort command to enable this. :dd
{Dump every variable returned a bad timestep} :dt
The variable must return a timestep greater than the current timestep. :dd
{Dump local and fix not computed at compatible times} :dt
The fix must produce per-atom quantities on timesteps that dump local
needs them. :dd
{Dump local attributes contain no compute or fix} :dt
Self-explanatory. :dd
{Dump local cannot sort by atom ID} :dt
This is because dump local does not really dump per-atom info. :dd
{Dump local compute does not calculate local array} :dt
Self-explanatory. :dd
{Dump local compute does not calculate local vector} :dt
Self-explanatory. :dd
{Dump local compute does not compute local info} :dt
Self-explanatory. :dd
{Dump local compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump local count is not consistent across input fields} :dt
Every column of output must be the same length. :dd
{Dump local fix does not compute local array} :dt
Self-explanatory. :dd
{Dump local fix does not compute local info} :dt
Self-explanatory. :dd
{Dump local fix does not compute local vector} :dt
Self-explanatory. :dd
{Dump local fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump modify compute ID vector is not large enough} :dt
Self-explanatory. :dd
{Dump modify element names do not match atom types} :dt
Number of element names must equal number of atom types. :dd
{Dump modify fix ID does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump modify fix ID does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump modify fix ID does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump modify fix ID vector is not large enough} :dt
Self-explanatory. :dd
{Dump modify variable is not atom-style variable} :dt
Self-explanatory. :dd
{Dump sort column is invalid} :dt
Self-explanatory. :dd
{Dump xtc requires sorting by atom ID} :dt
Use the dump_modify sort command to enable this. :dd
{Dump_modify region ID does not exist} :dt
Self-explanatory. :dd
{Dumping an atom property that isn't allocated} :dt
The chosen atom style does not define the per-atom quantity being
dumped. :dd
{Dumping an atom quantity that isn't allocated} :dt
Only per-atom quantities that are defined for the atom style being
used are allowed. :dd
{Duplicate particle in PeriDynamic bond - simulation box is too small} :dt
This is likely because your box length is shorter than 2 times
the bond length. :dd
{Electronic temperature dropped below zero} :dt
Something has gone wrong with the fix ttm electron temperature model. :dd
{Empty brackets in variable} :dt
There is no variable syntax that uses empty brackets. Check
the variable doc page. :dd
{Energy was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Expected floating point parameter in input script or data file} :dt
The quantity being read is an integer on non-numeric value. :dd
{Expected floating point parameter in variable definition} :dt
The quantity being read is a non-numeric value. :dd
{Expected integer parameter in input script or data file} :dt
The quantity being read is a floating point or non-numeric value. :dd
{Expected integer parameter in variable definition} :dt
The quantity being read is a floating point or non-numeric value. :dd
{Failed to allocate %d bytes for array %s} :dt
Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors. :dd
{Failed to reallocate %d bytes for array %s} :dt
Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors. :dd
{Fewer SRD bins than processors in some dimension} :dt
This is not allowed. Make your SRD bin size smaller. :dd
{Final box dimension due to fix deform is < 0.0} :dt
Self-explanatory. :dd
{Fix gpu split must be positive for hybrid pair styles.} :dt
See documentation for fix gpu. :dd
{Fix ID for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Fix ID for compute reduce does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix store/state does not exist} :dt
Self-explanatory :dd
{Fix ID must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Fix SRD cannot have both atom attributes angmom and omega} :dt
Use either spheroid solute particles or fully generalized
aspherical solute particles. :dd
{Fix SRD no-slip requires atom attribute torque} :dt
This is because the SRD collisions will impart torque to the solute
particles. :dd
{Fix SRD requires atom attribute angmom or omega} :dt
This is because the SRD collisions with cause the solute particles to
rotate. :dd
{Fix SRD requires atom attribute radius or shape} :dt
This is because the solute particles must be finite-size particles,
not point particles. :dd
{Fix SRD: bad bin assignment for SRD advection} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: bad search bin assignment} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: bad stencil bin for big particle} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: too many big particles in bin} :dt
Reset the ATOMPERBIN parameter at the top of fix_srd.cpp
to a larger value, and re-compile the code. :dd
{Fix SRD: too many walls in bin} :dt
This should not happen unless your system has been setup incorrectly. :dd
{Fix adapt kspace style does not exist} :dt
Self-explanatory. :dd
{Fix adapt pair style does not exist} :dt
Self-explanatory :dd
{Fix adapt pair style param not supported} :dt
The pair style does not know about the parameter you specified. :dd
{Fix adapt requires atom attribute diameter} :dt
The atom style being used does not specify an atom diameter. :dd
{Fix adapt type pair range is not valid for pair hybrid sub-style} :dt
Self-explanatory. :dd
{Fix ave/atom compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/atom compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/atom compute does not calculate a per-atom vector} :dt
A compute used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom compute does not calculate per-atom values} :dt
A compute used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/atom fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/atom fix does not calculate a per-atom vector} :dt
A fix used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom fix does not calculate per-atom values} :dt
A fix used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom variable is not atom-style variable} :dt
A variable used by fix ave/atom must generate per-atom values. :dd
{Fix ave/histo cannot input local values in scalar mode} :dt
Self-explanatory. :dd
{Fix ave/histo cannot input per-atom values in scalar mode} :dt
Self-explanatory. :dd
{Fix ave/histo compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global scalar} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a local array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a local vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate local values} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate per-atom values} :dt
Self-explanatory. :dd
{Fix ave/histo compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global scalar} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a local array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a local vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate local values} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate per-atom values} :dt
Self-explanatory. :dd
{Fix ave/histo fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid compute} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid fix} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid variable} :dt
Self-explanatory. :dd
{Fix ave/histo inputs are not all global, peratom, or local} :dt
All inputs in a single fix ave/histo command must be of the
same style. :dd
{Fix ave/spatial compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/spatial compute does not calculate a per-atom vector} :dt
A compute used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial compute does not calculate per-atom values} :dt
A compute used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/spatial fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/spatial fix does not calculate a per-atom vector} :dt
A fix used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial fix does not calculate per-atom values} :dt
A fix used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/spatial for triclinic boxes requires units reduced} :dt
Self-explanatory. :dd
{Fix ave/spatial settings invalid with changing box} :dt
If the ave setting is "running" or "window" and the box size/shape
changes during the simulation, then the units setting must be
"reduced", else the number of bins may change. :dd
{Fix ave/spatial variable is not atom-style variable} :dt
A variable used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/time cannot set output array intensive/extensive from these inputs} :dt
One of more of the vector inputs has individual elements which are
flagged as intensive or extensive. Such an input cannot be flagged as
all intensive/extensive when turned into an array by fix ave/time. :dd
{Fix ave/time cannot use variable with vector mode} :dt
Variables produce scalar values. :dd
{Fix ave/time columns are inconsistent lengths} :dt
Self-explanatory. :dd
{Fix ave/time compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/time compute does not calculate a scalar} :dt
Only computes that calculate a scalar or vector quantity (not a
per-atom quantity) can be used with fix ave/time. :dd
{Fix ave/time compute does not calculate a vector} :dt
Only computes that calculate a scalar or vector quantity (not a
per-atom quantity) can be used with fix ave/time. :dd
{Fix ave/time compute does not calculate an array} :dt
Self-explanatory. :dd
{Fix ave/time compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/time fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/time fix does not calculate a scalar} :dt
A fix used by fix ave/time must generate global values. :dd
{Fix ave/time fix does not calculate a vector} :dt
A fix used by fix ave/time must generate global values. :dd
{Fix ave/time fix does not calculate an array} :dt
Self-explanatory. :dd
{Fix ave/time fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/time variable is not equal-style variable} :dt
A variable used by fix ave/time must generate a global value. :dd
{Fix bond/break requires special_bonds = 0,1,1} :dt
This is a restriction of the current fix bond/break implementation. :dd
{Fix bond/create cutoff is longer than pairwise cutoff} :dt
This is not allowed because bond creation is done using the
pairwise neighbor list. :dd
{Fix bond/create requires special_bonds coul = 0,1,1} :dt
Self-explanatory. :dd
{Fix bond/create requires special_bonds lj = 0,1,1} :dt
Self-explanatory. :dd
{Fix bond/swap cannot use dihedral or improper styles} :dt
These styles cannot be defined when using this fix. :dd
{Fix bond/swap requires pair and bond styles} :dt
Self-explanatory. :dd
{Fix bond/swap requires special_bonds = 0,1,1} :dt
Self-explanatory. :dd
{Fix box/relax generated negative box length} :dt
The pressure being applied is likely too large. Try applying
it incrementally, to build to the high pressure. :dd
{Fix command before simulation box is defined} :dt
The fix command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Fix deform is changing yz by too much with changing xy} :dt
When both yz and xy are changing, it induces changes in xz if the
box must flip from one tilt extreme to another. Thus it is not
allowed for yz to grow so much that a flip is induced. :dd
{Fix deform tilt factors require triclinic box} :dt
Cannot deform the tilt factors of a simulation box unless it
is a triclinic (non-orthogonal) box. :dd
{Fix deform volume setting is invalid} :dt
Cannot use volume style unless other dimensions are being controlled. :dd
{Fix deposit region cannot be dynamic} :dt
Only static regions can be used with fix deposit. :dd
{Fix deposit region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the fix deposit command. :dd
{Fix efield requires atom attribute q} :dt
Self-explanatory. :dd
{Fix evaporate molecule requires atom attribute molecule} :dt
The atom style being used does not define a molecule ID. :dd
{Fix external callback function not set} :dt
This must be done by an external program in order to use this fix. :dd
{Fix for fix ave/atom not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/atom is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/correlate not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/correlate
is requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/histo not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/histo is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/spatial not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/spatial is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/time not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/time
is requesting a value on a non-allowed timestep. :dd
{Fix for fix store/state not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix store/state
is requesting a value on a non-allowed timestep. :dd
{Fix freeze requires atom attribute torque} :dt
The atom style defined does not have this attribute. :dd
{Fix heat group has no atoms} :dt
Self-explanatory. :dd
{Fix heat kinetic energy went negative} :dt
This will cause the velocity rescaling about to be performed by fix
heat to be invalid. :dd
{Fix in variable not computed at compatible time} :dt
Fixes generate their values on specific timesteps. The variable is
requesting the values on a non-allowed timestep. :dd
{Fix langevin period must be > 0.0} :dt
The time window for temperature relaxation must be > 0 :dd
{Fix momentum group has no atoms} :dt
Self-explanatory. :dd
{Fix move cannot define z or vz variable for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot have 0 length rotation vector} :dt
Self-explanatory. :dd
{Fix move cannot rotate aroung non z-axis for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot set linear z motion for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot set wiggle z motion for 2d problem} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute potential energy} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute pressure} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute temperature} :dt
Self-explanatory. :dd
{Fix msst requires a periodic box} :dt
Self-explanatory. :dd
{Fix msst tscale must satisfy 0 <= tscale < 1} :dt
Self-explanatory. :dd
{Fix npt/nph has tilted box too far - box flips are not yet implemented} :dt
This feature has not yet been added. However, if you are applying
an off-diagonal pressure to a fluid, the box may want to tilt indefinitely,
because the fluid cannot support the pressure you are imposing. :dd
{Fix nve/asphere cannot be used with atom attributes diameter or rmass} :dt
These attributes override the shape and mass settings, so cannot be
used. :dd
{Fix nve/asphere requires atom attributes angmom, quat, torque, shape} :dt
An atom style that specifies these quantities is needed. :dd
{Fix nve/asphere requires extended particles} :dt
This fix can only be used for particles with a shape setting. :dd
{Fix nve/sphere requires atom attribute diameter or shape} :dt
An atom style that specifies these quantities is needed. :dd
{Fix nve/sphere requires atom attribute mu} :dt
An atom style with this attribute is needed. :dd
{Fix nve/sphere requires atom attributes omega, torque} :dt
An atom style with these attributes is needed. :dd
{Fix nve/sphere requires extended particles} :dt
This fix can only be used for particles of a finite size. :dd
{Fix nve/sphere requires spherical particle shapes} :dt
Self-explanatory. :dd
{Fix nvt/nph/npt asphere cannot be used with atom attributes diameter or rmass} :dt
Those attributes are for spherical particles. :dd
{Fix nvt/nph/npt asphere requires atom attributes quat, angmom, torque, shape} :dt
Those attributes are what are used to define aspherical particles. :dd
{Fix nvt/nph/npt asphere requires extended particles} :dt
The shape setting for a particle in the fix group has shape = 0.0,
which means it is a point particle. :dd
{Fix nvt/nph/npt sphere requires atom attribute diameter or shape} :dt
An atom style that specifies these quantities is needed. :dd
{Fix nvt/nph/npt sphere requires atom attributes omega, torque} :dt
Those attributes are what are used to define spherical particles. :dd
{Fix nvt/npt/nph damping parameters must be > 0.0} :dt
Self-explanatory. :dd
{Fix nvt/sphere requires extended particles} :dt
This fix can only be used for particles of a finite size. :dd
{Fix nvt/sphere requires spherical particle shapes} :dt
Self-explanatory. :dd
{Fix orient/fcc file open failed} :dt
The fix orient/fcc command could not open a specified file. :dd
{Fix orient/fcc file read failed} :dt
The fix orient/fcc command could not read the needed parameters from a
specified file. :dd
{Fix orient/fcc found self twice} :dt
The neighbor lists used by fix orient/fcc are messed up. If this
error occurs, it is likely a bug, so send an email to the
"developers"_http://lammps.sandia.gov/authors.html. :dd
{Fix peri neigh does not exist} :dt
Somehow a fix that the pair style defines has been deleted. :dd
{Fix pour region ID does not exist} :dt
Self-explanatory. :dd
{Fix pour region cannot be dynamic} :dt
Only static regions can be used with fix pour. :dd
{Fix pour region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the fix pour command. :dd
{Fix pour requires atom attributes radius, rmass} :dt
The atom style defined does not have these attributes. :dd
{Fix press/berendsen damping parameters must be > 0.0} :dt
Self-explanatory. :dd
{Fix qeq/comb group has no atoms} :dt
Self-explanatory. :dd
{Fix qeq/comb requires atom attribute q} :dt
An atom style with charge must be used to perform charge equilibration. :dd
{Fix reax/bonds numbonds > nsbmax_most} :dt
The limit of the number of bonds expected by the ReaxFF force field
was exceeded. :dd
{Fix recenter group has no atoms} :dt
Self-explanatory. :dd
{Fix rigid atom has non-zero image flag in a non-periodic dimension} :dt
You cannot set image flags for non-periodic dimensions. :dd
{Fix rigid molecule requires atom attribute molecule} :dt
Self-explanatory. :dd
{Fix rigid/nvt period must be > 0.0} :dt
Self-explanatory :dd
{Fix rigid: Bad principal moments} :dt
The principal moments of inertia computed for a rigid body
are not within the required tolerances. :dd
{Fix shake cannot be used with minimization} :dt
Cannot use fix shake while doing an energy minimization since
it turns off bonds that should contribute to the energy. :dd
{Fix spring couple group ID does not exist} :dt
Self-explanatory. :dd
{Fix srd lamda must be >= 0.6 of SRD grid size} :dt
This is a requirement for accuracy reasons. :dd
{Fix srd requires SRD particles all have same mass} :dt
Self-explanatory. :dd
{Fix srd requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Fix srd requires newton pair on} :dt
Self-explanatory. :dd
{Fix store/state compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix store/state compute does not calculate a per-atom array} :dt
The compute calculates a per-atom vector. :dd
{Fix store/state compute does not calculate a per-atom vector} :dt
The compute calculates a per-atom vector. :dd
{Fix store/state compute does not calculate per-atom values} :dt
Computes that calculate global or local quantities cannot be used
with fix store/state. :dd
{Fix store/state fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix store/state fix does not calculate a per-atom array} :dt
The fix calculates a per-atom vector. :dd
{Fix store/state fix does not calculate a per-atom vector} :dt
The fix calculates a per-atom array. :dd
{Fix store/state fix does not calculate per-atom values} :dt
Fixes that calculate global or local quantities cannot be used with
fix store/state. :dd
{Fix store/state for atom property that isn't allocated} :dt
Self-explanatory. :dd
{Fix store/state variable is not atom-style variable} :dt
Only atom-style variables calculate per-atom quantities. :dd
{Fix temp/berendsen period must be > 0.0} :dt
Self-explanatory. :dd
{Fix thermal/conductivity swap value must be positive} :dt
Self-explanatory. :dd
{Fix tmd must come after integration fixes} :dt
Any fix tmd command must appear in the input script after all time
integration fixes (nve, nvt, npt). See the fix tmd documentation for
details. :dd
{Fix ttm electron temperatures must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_density must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_specific_heat must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_thermal_conductivity must be >= 0.0} :dt
Self-explanatory. :dd
{Fix ttm gamma_p must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm gamma_s must be >= 0.0} :dt
Self-explanatory. :dd
{Fix ttm number of nodes must be > 0} :dt
Self-explanatory. :dd
{Fix ttm v_0 must be >= 0.0} :dt
Self-explanatory. :dd
{Fix used in compute atom/molecule not computed at compatible time} :dt
The fix must produce per-atom quantities on timesteps that the compute
needs them. :dd
{Fix used in compute reduce not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Compute sum is
requesting a value on a non-allowed timestep. :dd
{Fix viscosity swap value must be positive} :dt
Self-explanatory. :dd
{Fix viscosity vtarget value must be positive} :dt
Self-explanatory. :dd
{Fix wall cutoff <= 0.0} :dt
Self-explanatory. :dd
{Fix wall/colloid cannot be used with atom attribute diameter} :dt
Only finite-size particles defined by the shape command can be used. :dd
{Fix wall/colloid requires atom attribute shape} :dt
Self-explanatory. :dd
{Fix wall/colloid requires extended particles} :dt
Self-explanatory. :dd
{Fix wall/colloid requires spherical particles} :dt
Self-explanatory. :dd
{Fix wall/gran is incompatible with Pair style} :dt
Must use a granular pair style to define the parameters needed for
this fix. :dd
{Fix wall/gran requires atom attributes radius, omega, torque} :dt
The atom style defined does not have these attributes. :dd
{Fix wall/region colloid cannot be used with atom attribute diameter} :dt
Only finite-size particles defined by the shape command can be used. :dd
{Fix wall/region colloid requires atom attribute shape} :dt
Self-explanatory. :dd
{Fix wall/region colloid requires extended particles} :dt
Self-explanatory. :dd
{Fix wall/region colloid requires spherical particles} :dt
Self-explanatory. :dd
{Fix wall/region cutoff <= 0.0} :dt
Self-explanatory. :dd
{Fix_modify order must be 3 or 5} :dt
Self-explanatory. :dd
{Fix_modify pressure ID does not compute pressure} :dt
The compute ID assigned to the fix must compute pressure. :dd
{Fix_modify temperature ID does not compute temperature} :dt
The compute ID assigned to the fix must compute temperature. :dd
{Found no restart file matching pattern} :dt
When using a "*" in the restart file name, no matching file was found. :dd
{GPU is not the first fix for this run} :dt
This is the way the fix must be defined in your input script. :dd
{GPU library not compiled for this accelerator} :dt
The GPU library was not built for your accelerator. Check the arch flag in
lib/gpu. :dd
{Gmask function in equal-style variable formula} :dt
Gmask is per-atom operation. :dd
{Gravity changed since fix pour was created} :dt
Gravity must be static and not dynamic for use with fix pour. :dd
{Gravity must point in -y to use with fix pour in 2d} :dt
Gravity must be pointing "down" in a 2d box. :dd
{Gravity must point in -z to use with fix pour in 3d} :dt
Gravity must be pointing "down" in a 3d box, i.e. theta = 180.0. :dd
{Grmask function in equal-style variable formula} :dt
Grmask is per-atom operation. :dd
{Group ID does not exist} :dt
A group ID used in the group command does not exist. :dd
{Group ID in variable formula does not exist} :dt
Self-explanatory. :dd
{Group command before simulation box is defined} :dt
The group command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Group region ID does not exist} :dt
A region ID used in the group command does not exist. :dd
{Illegal ... command} :dt
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line. :dd
{Illegal COMB parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal Stillinger-Weber parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal Tersoff parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal chemical element names} :dt
The name is too long to be a chemical element. :dd
{Illegal fix gpu command} :dt
Self-explanatory. :dd
{Illegal number of angle table entries} :dt
There must be at least 2 table entries. :dd
{Illegal number of bond table entries} :dt
There must be at least 2 table entries. :dd
{Illegal number of pair table entries} :dt
There must be at least 2 table entries. :dd
{Illegal simulation box} :dt
The lower bound of the simulation box is greater than the upper bound. :dd
{Improper atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
improper on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid improper. :dd
{Improper atom missing in set command} :dt
The set command cannot find one or more atoms in a particular improper
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid improper. :dd
{Improper atoms %d %d %d %d missing on proc %d at step} :dt
One or more of 4 atoms needed to compute a particular improper are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the improper has blown apart and an atom is
too far away. :dd
{Improper coeff for hybrid has invalid style} :dt
Improper style hybrid uses another improper style as one of its
coefficients. The improper style used in the improper_coeff command
or read from a restart file is not recognized. :dd
{Improper coeffs are not set} :dt
No improper coefficients have been assigned in the data file or via
the improper_coeff command. :dd
{Improper style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Improper style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Improper style hybrid cannot use same improper style twice} :dt
Self-explanatory. :dd
{Improper_coeff command before improper_style is defined} :dt
Coefficients cannot be set in the data file or via the improper_coeff
command until an improper_style has been assigned. :dd
{Improper_coeff command before simulation box is defined} :dt
The improper_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Improper_coeff command when no impropers allowed} :dt
The chosen atom style does not allow for impropers to be defined. :dd
{Improper_style command when no impropers allowed} :dt
The chosen atom style does not allow for impropers to be defined. :dd
{Impropers assigned incorrectly} :dt
Impropers read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Impropers defined but no improper types} :dt
The data file header lists improper but no improper types. :dd
{Inconsistent iparam/jparam values in fix bond/create command} :dt
If itype and jtype are the same, then their maxbond and newtype
settings must also be the same. :dd
{Incorrect args for angle coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for bond coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for improper coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for pair coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args in pair_style command} :dt
Self-explanatory. :dd
{Incorrect atom format in data file} :dt
Number of values per atom line in the data file is not consistent with
the atom style. :dd
{Incorrect boundaries with slab Ewald} :dt
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with Ewald. :dd
{Incorrect boundaries with slab PPPM} :dt
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with PPPM. :dd
{Incorrect element names in EAM potential file} :dt
The element names in the EAM file do not match those requested. :dd
{Incorrect format in COMB potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in MEAM potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in NEB coordinate file} :dt
Self-explanatory. :dd
{Incorrect format in Stillinger-Weber potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in TMD target file} :dt
Format of file read by fix tmd command is incorrect. :dd
{Incorrect format in Tersoff potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect multiplicity arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect sign arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect velocity format in data file} :dt
Each atom style defines a format for the Velocity section
of the data file. The read-in lines do not match. :dd
{Incorrect weight arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Index between variable brackets must be positive} :dt
Self-explanatory. :dd
{Indexed per-atom vector in variable formula without atom map} :dt
Accessing a value from an atom vector requires the ability to lookup
an atom index, which is provided by an atom map. An atom map does not
exist (by default) for non-molecular problems. Using the atom_modify
map command will force an atom map to be created. :dd
{Induced tilt by displace_box is too large} :dt
The final tilt value must be between -1/2 and 1/2 of the perpendicular
box length. :dd
{Initial temperatures not all set in fix ttm} :dt
Self-explantory. :dd
{Input line too long after variable substitution} :dt
This is a hard (very large) limit defined in the input.cpp file. :dd
{Input line too long: %s} :dt
This is a hard (very large) limit defined in the input.cpp file. :dd
{Insertion region extends outside simulation box} :dt
Region specified with fix pour command extends outside the global
simulation box. :dd
{Insufficient Jacobi rotations for POEMS body} :dt
Eigensolve for rigid body was not sufficiently accurate. :dd
{Insufficient Jacobi rotations for rigid body} :dt
Eigensolve for rigid body was not sufficiently accurate. :dd
{Insufficient memory on accelerator. } :dt
Self-explanatory. :dd
{Invalid Boolean syntax in if command} :dt
Self-explanatory. :dd
{Invalid REAX atom type} :dt
There is a mis-match between LAMMPS atom types and the elements
listed in the ReaxFF force field file. :dd
{Invalid angle style} :dt
The choice of angle style is unknown. :dd
{Invalid angle table length} :dt
Length must be 2 or greater. :dd
{Invalid angle type in Angles section of data file} :dt
Angle type must be positive integer and within range of specified angle
types. :dd
{Invalid angle type index for fix shake} :dt
Self-explanatory. :dd
{Invalid atom ID in Angles section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Atoms section of data file} :dt
Atom IDs must be positive integers. :dd
{Invalid atom ID in Bonds section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Dihedrals section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Impropers section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Velocities section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom mass for fix shake} :dt
Mass specified in fix shake command must be > 0.0. :dd
{Invalid atom style} :dt
The choice of atom style is unknown. :dd
{Invalid atom type in Atoms section of data file} :dt
Atom types must range from 1 to specified # of types. :dd
{Invalid atom type in create_atoms command} :dt
The create_box command specified the range of valid atom types.
An invalid type is being requested. :dd
{Invalid atom type in fix bond/create command} :dt
Self-explanatory. :dd
{Invalid atom type in neighbor exclusion list} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom type index for fix shake} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom types in pair_write command} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom vector in variable formula} :dt
The atom vector is not recognized. :dd
{Invalid attribute in dump custom command} :dt
Self-explantory. :dd
{Invalid attribute in dump local command} :dt
Self-explantory. :dd
{Invalid attribute in dump modify command} :dt
Self-explantory. :dd
{Invalid bond style} :dt
The choice of bond style is unknown. :dd
{Invalid bond table length} :dt
Length must be 2 or greater. :dd
{Invalid bond type in Bonds section of data file} :dt
Bond type must be positive integer and within range of specified bond
types. :dd
{Invalid bond type in fix bond/break command} :dt
Self-explanatory. :dd
{Invalid bond type in fix bond/create command} :dt
Self-explanatory. :dd
{Invalid bond type index for fix shake} :dt
Self-explanatory. Check the fix shake command in the input script. :dd
{Invalid coeffs for this dihedral style} :dt
Cannot set class 2 coeffs in data file for this dihedral style. :dd
{Invalid command-line argument} :dt
One or more command-line arguments is invalid. Check the syntax of
the command you are using to launch LAMMPS. :dd
{Invalid compute ID in variable formula} :dt
The compute is not recognized. :dd
{Invalid compute style} :dt
Self-explanatory. :dd
{Invalid cutoff in communicate command} :dt
Specified cutoff must be >= 0.0. :dd
{Invalid cutoffs in pair_write command} :dt
Inner cutoff must be larger than 0.0 and less than outer cutoff. :dd
{Invalid d1 or d2 value for pair colloid coeff} :dt
Neither d1 or d2 can be < 0. :dd
{Invalid data file section: Angle Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: AngleAngle Coeffs} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: AngleAngleTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: AngleTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Angles} :dt
Atom style does not allow angles. :dd
{Invalid data file section: Bond Coeffs} :dt
Atom style does not allow bonds. :dd
{Invalid data file section: BondAngle Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: BondBond Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: BondBond13 Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Bonds} :dt
Atom style does not allow bonds. :dd
{Invalid data file section: Dihedral Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Dihedrals} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: EndBondTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Improper Coeffs} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: Impropers} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: MiddleBondTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid delta_conf in tad command} :dt
The value must be between 0 and 1 inclusive. :dd
{Invalid density in Atoms section of data file} :dt
Density value cannot be <= 0.0. :dd
{Invalid dihedral style} :dt
The choice of dihedral style is unknown. :dd
{Invalid dihedral type in Dihedrals section of data file} :dt
Dihedral type must be positive integer and within range of specified
dihedral types. :dd
{Invalid dipole line in data file} :dt
Self-explanatory. :dd
{Invalid dipole value} :dt
Self-explanatory. :dd
{Invalid dump dcd filename} :dt
Filenames used with the dump dcd style cannot be binary or compressed
or cause multiple files to be written. :dd
{Invalid dump frequency} :dt
Dump frequency must be 1 or greater. :dd
{Invalid dump style} :dt
The choice of dump style is unknown. :dd
{Invalid dump xtc filename} :dt
Filenames used with the dump xtc style cannot be binary or compressed
or cause multiple files to be written. :dd
{Invalid dump xyz filename} :dt
Filenames used with the dump xyz style cannot be binary or cause files
to be written by each processor. :dd
{Invalid dump_modify threshhold operator} :dt
Operator keyword used for threshold specification in not recognized. :dd
{Invalid fix ID in variable formula} :dt
The fix is not recognized. :dd
{Invalid fix ave/time off column} :dt
Self-explantory. :dd
{Invalid fix box/relax command for a 2d simulation} :dt
Fix box/relax styles involving the z dimension cannot be used in
a 2d simulation. :dd
{Invalid fix box/relax command pressure settings} :dt
If multiple dimensions are coupled, those dimensions must be specified. :dd
{Invalid fix box/relax pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix nvt/npt/nph command for a 2d simulation} :dt
Cannot control z dimension in a 2d model. :dd
{Invalid fix nvt/npt/nph command pressure settings} :dt
If multiple dimensions are coupled, those dimensions must be
specified. :dd
{Invalid fix nvt/npt/nph pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix press/berendsen for a 2d simulation} :dt
The z component of pressure cannot be controlled for a 2d model. :dd
{Invalid fix press/berendsen pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix style} :dt
The choice of fix style is unknown. :dd
{Invalid flag in force field section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid flag in header section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid flag in type arrays section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid frequency in temper command} :dt
Nevery must be > 0. :dd
{Invalid group ID in neigh_modify command} :dt
A group ID used in the neigh_modify command does not exist. :dd
{Invalid group function in variable formula} :dt
Group function is not recognized. :dd
{Invalid group in communicate command} :dt
Self-explanatory. :dd
{Invalid improper style} :dt
The choice of improper style is unknown. :dd
{Invalid improper type in Impropers section of data file} :dt
Improper type must be positive integer and within range of specified
improper types. :dd
{Invalid keyword in angle table parameters} :dt
Self-explanatory. :dd
{Invalid keyword in bond table parameters} :dt
Self-explanatory. :dd
{Invalid keyword in compute angle/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute bond/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute dihedral/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute improper/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute pair/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/atom command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/molecule command} :dt
Self-explanatory. :dd
{Invalid keyword in dump cfg command} :dt
Self-explanatory. :dd
{Invalid keyword in pair table parameters} :dt
Keyword used in list of table parameters is not recognized. :dd
{Invalid keyword in thermo_style custom command} :dt
One or more specified keywords are not recognized. :dd
{Invalid kspace style} :dt
The choice of kspace style is unknown. :dd
{Invalid mass line in data file} :dt
Self-explanatory. :dd
{Invalid mass value} :dt
Self-explanatory. :dd
{Invalid math function in variable formula} :dt
Self-explanatory. :dd
{Invalid math/group/special function in variable formula} :dt
Self-explanatory. :dd
{Invalid option in lattice command for non-custom style} :dt
Certain lattice keywords are not supported unless the
lattice style is "custom". :dd
{Invalid order of forces within respa levels} :dt
For respa, ordering of force computations within respa levels must
obey certain rules. E.g. bonds cannot be compute less frequently than
angles, pairwise forces cannot be computed less frequently than
kspace, etc. :dd
{Invalid pair style} :dt
The choice of pair style is unknown. :dd
{Invalid pair table cutoff} :dt
Cutoffs in pair_coeff command are not valid with read-in pair table. :dd
{Invalid pair table length} :dt
Length of read-in pair table is invalid :dd
{Invalid radius in Atoms section of data file} :dt
Radius must be >= 0.0. :dd
{Invalid random number seed in fix ttm command} :dt
Random number seed must be > 0. :dd
{Invalid random number seed in set command} :dt
Random number seed must be > 0. :dd
{Invalid region style} :dt
The choice of region style is unknown. :dd
{Invalid replace values in compute reduce} :dt
Self-explanatory. :dd
{Invalid run command N value} :dt
The number of timesteps must fit in a 32-bit integer. If you want to
run for more steps than this, perform multiple shorter runs. :dd
{Invalid run command start/stop value} :dt
Self-explanatory. :dd
{Invalid run command upto value} :dt
Self-explanatory. :dd
{Invalid seed for Marsaglia random # generator} :dt
The initial seed for this random number generator must be a positive
integer less than or equal to 900 million. :dd
{Invalid seed for Park random # generator} :dt
The initial seed for this random number generator must be a positive
integer. :dd
{Invalid shape line in data file} :dt
Self-explanatory. :dd
{Invalid shape line in data file} :dt
Self-explanatory. :dd
{Invalid shape value} :dt
Self-explanatory. :dd
{Invalid shear direction for fix wall/gran} :dt
Self-explanatory. :dd
{Invalid special function in variable formula} :dt
Self-explanatory. :dd
{Invalid style in pair_write command} :dt
Self-explanatory. Check the input script. :dd
{Invalid syntax in variable formula} :dt
Self-explanatory. :dd
{Invalid t_event in prd command} :dt
Self-explanatory. :dd
{Invalid t_event in tad command} :dt
The value must be greater than 0. :dd
{Invalid thermo keyword in variable formula} :dt
The keyword is not recognized. :dd
{Invalid tmax in tad command} :dt
The value must be greater than 0.0. :dd
{Invalid type for dipole set} :dt
Dipole command must set a type from 1-N where N is the number of atom
types. :dd
{Invalid type for mass set} :dt
Mass command must set a type from 1-N where N is the number of atom
types. :dd
{Invalid type for shape set} :dt
Atom type is out of bounds. :dd
{Invalid value in set command} :dt
The value specified for the setting is invalid, likely because it is
too small or too large. :dd
{Invalid variable evaluation in variable formula} :dt
A variable used in a formula could not be evaluated. :dd
{Invalid variable in next command} :dt
Self-explanatory. :dd
{Invalid variable name in variable formula} :dt
Variable name is not recognized. :dd
{Invalid variable name} :dt
Variable name used in an input script line is invalid. :dd
{Invalid variable style with next command} :dt
Variable styles {equal} and {world} cannot be used in a next
command. :dd
{Invalid wiggle direction for fix wall/gran} :dt
Self-explanatory. :dd
{Invoked angle equil angle on angle style none} :dt
Self-explanatory. :dd
{Invoked angle single on angle style none} :dt
Self-explanatory. :dd
{Invoked bond equil distance on bond style none} :dt
Self-explanatory. :dd
{Invoked bond single on bond style none} :dt
Self-explanatory. :dd
{Invoked pair single on pair style none} :dt
A command (e.g. a dump) attempted to invoke the single() function on a
pair style none, which is illegal. You are probably attempting to
compute per-atom quantities with an undefined pair style. :dd
{KSpace style has not yet been set} :dt
Cannot use kspace_modify command until a kspace style is set. :dd
{KSpace style is incompatible with Pair style} :dt
Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected. :dd
{Keyword %s in MEAM parameter file not recognized} :dt
Self-explanatory. :dd
{Kspace style requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Label wasn't found in input script} :dt
Self-explanatory. :dd
{Lattice orient vectors are not orthogonal} :dt
The three specified lattice orientation vectors must be mutually
orthogonal. :dd
{Lattice orient vectors are not right-handed} :dt
The three specified lattice orientation vectors must create a
right-handed coordinate system such that a1 cross a2 = a3. :dd
{Lattice primitive vectors are collinear} :dt
The specified lattice primitive vectors do not for a unit cell with
non-zero volume. :dd
{Lattice settings are not compatible with 2d simulation} :dt
One or more of the specified lattice vectors has a non-zero z
component. :dd
{Lattice spacings are invalid} :dt
Each x,y,z spacing must be > 0. :dd
{Lattice style incompatible with simulation dimension} :dt
2d simulation can use sq, sq2, or hex lattice. 3d simulation can use
sc, bcc, or fcc lattice. :dd
{Log of zero/negative value in variable formula} :dt
Self-explanatory. :dd
{MEAM library error %d} :dt
A call to the MEAM Fortran library returned an error. :dd
{MPI_LMP_BIGINT and bigint in lmptype.h are not compatible} :dt
The size of the MPI datatype does not match the size of a bigint. :dd
{MPI_LMP_TAGINT and tagint in lmptype.h are not compatible} :dt
The size of the MPI datatype does not match the size of a tagint. :dd
{Mass command before simulation box is defined} :dt
The mass command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Min_style command before simulation box is defined} :dt
The min_style command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Minimization could not find thermo_pe compute} :dt
This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command. :dd
{Minimize command before simulation box is defined} :dt
The minimize command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Mismatched brackets in variable} :dt
Self-explanatory. :dd
{Mismatched compute in variable formula} :dt
A compute is referenced incorrectly or a compute that produces per-atom
values is used in an equal-style variable formula. :dd
{Mismatched fix in variable formula} :dt
A fix is referenced incorrectly or a fix that produces per-atom
values is used in an equal-style variable formula. :dd
{Mismatched variable in variable formula} :dt
A variable is referenced incorrectly or an atom-style variable that
produces per-atom values is used in an equal-style variable
formula. :dd
{Molecular data file has too many atoms} :dt
These kids of data files are currently limited to a number
of atoms that fits in a 32-bit integer. :dd
{Molecule count changed in compute atom/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute com/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute gyration/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute msd/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute property/molecule} :dt
Number of molecules must remain constant over time. :dd
{More than one fix deform} :dt
Only one fix deform can be defined at a time. :dd
{More than one fix freeze} :dt
Only one of these fixes can be defined, since the granular pair
potentials access it. :dd
{More than one fix shake} :dt
Only one fix shake can be defined. :dd
{Must define angle_style before Angle Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define angle_style before BondAngle Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define angle_style before BondBond Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define bond_style before Bond Coeffs} :dt
Must use a bond_style command before reading a data file that
defines Bond Coeffs. :dd
{Must define dihedral_style before AngleAngleTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines AngleAngleTorsion Coeffs. :dd
{Must define dihedral_style before AngleTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines AngleTorsion Coeffs. :dd
{Must define dihedral_style before BondBond13 Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines BondBond13 Coeffs. :dd
{Must define dihedral_style before Dihedral Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines Dihedral Coeffs. :dd
{Must define dihedral_style before EndBondTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines EndBondTorsion Coeffs. :dd
{Must define dihedral_style before MiddleBondTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines MiddleBondTorsion Coeffs. :dd
{Must define improper_style before AngleAngle Coeffs} :dt
Must use an improper_style command before reading a data file that
defines AngleAngle Coeffs. :dd
{Must define improper_style before Improper Coeffs} :dt
Must use an improper_style command before reading a data file that
defines Improper Coeffs. :dd
{Must define pair_style before Pair Coeffs} :dt
Must use a pair_style command before reading a data file that defines
Pair Coeffs. :dd
{Must have more than one processor partition to temper} :dt
Cannot use the temper command with only one processor partition. Use
the -partition command-line option. :dd
{Must read Atoms before Angles} :dt
The Atoms section of a data file must come before an Angles section. :dd
{Must read Atoms before Bonds} :dt
The Atoms section of a data file must come before a Bonds section. :dd
{Must read Atoms before Dihedrals} :dt
The Atoms section of a data file must come before a Dihedrals section. :dd
{Must read Atoms before Impropers} :dt
The Atoms section of a data file must come before an Impropers
section. :dd
{Must read Atoms before Velocities} :dt
The Atoms section of a data file must come before a Velocities
section. :dd
{Must set both respa inner and outer} :dt
Cannot use just the inner or outer option with respa without using the
other. :dd
{Must specify a region in fix deposit} :dt
The region keyword must be specified with this fix. :dd
{Must specify a region in fix pour} :dt
The region keyword must be specified with this fix. :dd
{Must use -in switch with multiple partitions} :dt
A multi-partition simulation cannot read the input script from stdin.
The -in command-line option must be used to specify a file. :dd
{Must use a block or cylinder region with fix pour} :dt
Self-explanatory. :dd
{Must use a block region with fix pour for 2d simulations} :dt
Self-explanatory. :dd
{Must use a bond style with TIP4P potential} :dt
TIP4P potentials assume bond lengths in water are constrained
by a fix shake command. :dd
{Must use a molecular atom style with fix poems molecule} :dt
Self-explanatory. :dd
{Must use a z-axis cylinder with fix pour} :dt
The axis of the cylinder region used with the fix pour command must
be oriented along the z dimension. :dd
{Must use an angle style with TIP4P potential} :dt
TIP4P potentials assume angles in water are constrained by a fix shake
command. :dd
{Must use atom style with molecule IDs with fix bond/swap} :dt
Self-explanatory. :dd
{Must use pair_style comb with fix qeq/comb} :dt
Self-explanatory. :dd
{Must use variable energy with fix addforce} :dt
Must define an energy vartiable when applyting a dynamic
force during minimization. :dd
{NEB command before simulation box is defined} :dt
Self-explanatory. :dd
{NEB requires damped dynamics minimizer} :dt
Use a different minimization style. :dd
{NEB requires use of fix neb} :dt
Self-explanatory. :dd
{Needed topology not in data file} :dt
The header of the data file indicated that bonds or angles or
dihedrals or impropers would be included, but they were not present. :dd
{Neigh_modify exclude molecule requires atom attribute molecule} :dt
Self-explanatory. :dd
{Neigh_modify include group != atom_modify first group} :dt
Self-explanatory. :dd
{Neighbor delay must be 0 or multiple of every setting} :dt
The delay and every parameters set via the neigh_modify command are
inconsistent. If the delay setting is non-zero, then it must be a
multiple of the every setting. :dd
{Neighbor include group not allowed with ghost neighbors} :dt
This is a current restriction within LAMMPS. :dd
{Neighbor list overflow, boost neigh_modify one or page} :dt
There are too many neighbors of a single atom. Use the neigh_modify
command to increase the neighbor page size and the max number of
neighbors allowed for one atom. :dd
{Neighbor multi not yet enabled for ghost neighbors} :dt
This is a current restriction within LAMMPS. :dd
{Neighbor multi not yet enabled for granular} :dt
Self-explanatory. :dd
{Neighbor multi not yet enabled for rRESPA} :dt
Self-explanatory. :dd
{Neighbor page size must be >= 10x the one atom setting} :dt
This is required to prevent wasting too much memory. :dd
{Neighbors of ghost atoms only allowed for full neighbor lists} :dt
This is a current restriction within LAMMPS. :dd
{New bond exceeded bonds per atom in fix bond/create} :dt
See the read_data command for info on setting the "extra bond per
atom" header value to allow for additional bonds to be formed. :dd
{New bond exceeded special list size in fix bond/create} :dt
See the special_bonds extra command for info on how to leave space in
the special bonds list to allow for additional bonds to be formed. :dd
{Newton bond change after simulation box is defined} :dt
The newton command cannot be used to change the newton bond value
after a read_data, read_restart, or create_box command. :dd
{No angle style is defined for compute angle/local} :dt
Self-explanatory. :dd
{No angles allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No atoms in data file} :dt
The header of the data file indicated that atoms would be included,
but they were not present. :dd
{No basis atoms in lattice} :dt
Basis atoms must be defined for lattice style user. :dd
{No bond style is defined for compute bond/local} :dt
Self-explanatory. :dd
{No bonds allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No dihedral style is defined for compute dihedral/local} :dt
Self-explanatory. :dd
{No dihedrals allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No dump custom arguments specified} :dt
The dump custom command requires that atom quantities be specified to
output to dump file. :dd
{No dump local arguments specified} :dt
Self-explanatory. :dd
{No fix gravity defined for fix pour} :dt
Cannot add poured particles without gravity to move them. :dd
{No improper style is defined for compute improper/local} :dt
Self-explanatory. :dd
{No impropers allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No matching element in EAM potential file} :dt
The EAM potential file does not contain elements that match the
requested elements. :dd
{No pair hbond/dreiding coefficients set} :dt
Self-explanatory. :dd
{No pair style defined for compute group/group} :dt
Cannot calculate group interactions without a pair style defined. :dd
{No pair style is defined for compute pair/local} :dt
Self-explanatory. :dd
{No pair style is defined for compute property/local} :dt
Self-explanatory. :dd
{No rigid bodies defined} :dt
The fix specification did not end up defining any rigid bodies. :dd
{Non digit character between brackets in variable} :dt
Self-explantory. :dd
{Non integer # of swaps in temper command} :dt
Swap frequency in temper command must evenly divide the total # of
timesteps. :dd
{One or more atoms belong to multiple rigid bodies} :dt
Two or more rigid bodies defined by the fix rigid command cannot
contain the same atom. :dd
{One or zero atoms in rigid body} :dt
Any rigid body defined by the fix rigid command must contain 2 or more
atoms. :dd
{Out of range atoms - cannot compute PPPM} :dt
One or more atoms are attempting to map their charge to a PPPM grid
point that is not owned by a processor. This is likely for one of two
reasons, both of them bad. First, it may mean that an atom near the
boundary of a processor's sub-domain has moved more than 1/2 the
"neighbor skin distance"_neighbor.html without neighbor lists being
rebuilt and atoms being migrated to new processors. This also means
you may be missing pairwise interactions that need to be computed.
The solution is to change the re-neighboring criteria via the
"neigh_modify"_neigh_modify command. The safest settings are "delay 0
every 1 check yes". Second, it may mean that an atom has moved far
outside a processor's sub-domain or even the entire simulation box.
This indicates bad physics, e.g. due to highly overlapping atoms, too
large a timestep, etc. :dd
{Overlapping large/large in pair colloid} :dt
This potential is infinite when there is an overlap. :dd
{Overlapping small/large in pair colloid} :dt
This potential is inifinte when there is an overlap. :dd
{POEMS fix must come before NPT/NPH fix} :dt
NPT/NPH fix must be defined in input script after all poems fixes,
else the fix contribution to the pressure virial is incorrect. :dd
{PPPM grid is too large} :dt
The global PPPM grid is larger than OFFSET in one or more dimensions.
OFFSET is currently set to 4096. You likely need to decrease the
requested precision. :dd
{PPPM order cannot be greater than %d} :dt
Self-explanatory. :dd
{PPPM order has been reduced to 0} :dt
LAMMPS has attempted to reduce the PPPM order to enable the simulation
to run, but can reduce the order no further. Try increasing the
accuracy of PPPM by reducing the tolerance size, thus inducing a
larger PPPM grid. :dd
{PRD command before simulation box is defined} :dt
The prd command cannot be used before a read_data,
read_restart, or create_box command. :dd
{PRD nsteps must be multiple of t_event} :dt
Self-explanatory. :dd
{PRD t_corr must be multiple of t_event} :dt
Self-explanatory. :dd
{Pair coeff for hybrid has invalid style} :dt
Style in pair coeff must have been listed in pair_style command. :dd
{Pair cutoff < Respa interior cutoff} :dt
One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs. :dd
{Pair dipole/cut requires atom attributes q, mu, torque, dipole} :dt
An atom style that specifies these quantities is needed. :dd
{Pair distance < table inner cutoff} :dt
Two atoms are closer together than the pairwise table allows. :dd
{Pair distance > table outer cutoff} :dt
Two atoms are further apart than the pairwise table allows. :dd
{Pair dpd requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair gayberne cannot be used with atom attribute diameter} :dt
Finite-size particles must be defined with the shape command. :dd
{Pair gayberne epsilon a,b,c coeffs are not all set} :dt
Each atom type involved in pair_style gayberne must
have these 3 coefficients set at least once. :dd
{Pair gayberne requires atom attributes quat, torque, shape} :dt
An atom style that defines these attributes must be used. :dd
{Pair granular requires atom attributes radius, omega, torque} :dt
The atom style defined does not have these attributes. :dd
{Pair granular requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair granular with shear history requires newton pair off} :dt
This is a current restriction of the implementation of pair
granular styles with history. :dd
{Pair hybrid sub-style does not support single call} :dt
You are attempting to invoke a single() call on a pair style
that doesn't support it. :dd
{Pair hybrid sub-style is not used} :dt
No pair_coeff command used a sub-style specified in the pair_style
command. :dd
{Pair inner cutoff < Respa interior cutoff} :dt
One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs. :dd
{Pair inner cutoff >= Pair outer cutoff} :dt
The specified cutoffs for the pair style are inconsistent. :dd
{Pair lubricate cannot be used with atom attributes diameter or rmass} :dt
These attributes override the shape and mass settings, so cannot be
used. :dd
{Pair lubricate requires atom attribute omega or angmom} :dt
An atom style that defines these attributes must be used. :dd
{Pair lubricate requires atom attributes torque and shape} :dt
An atom style that defines these attributes must be used. :dd
{Pair lubricate requires extended particles} :dt
This pair style can only be used for particles with a shape
setting. :dd
{Pair lubricate requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair lubricate requires spherical, mono-disperse particles} :dt
This is a current restriction of this pair style. :dd
{Pair peri lattice is not identical in x, y, and z} :dt
The lattice defined by the lattice command must be cubic. :dd
{Pair peri requires a lattice be defined} :dt
Use the lattice command for this purpose. :dd
{Pair peri requires an atom map, see atom_modify} :dt
Even for atomic systems, an atom map is required to find Peridynamic
bonds. Use the atom_modify command to define one. :dd
{Pair resquared cannot be used with atom attribute diameter} :dt
This attribute overrides the shape settings, so cannot be used. :dd
{Pair resquared epsilon a,b,c coeffs are not all set} :dt
Self-explanatory. :dd
{Pair resquared epsilon and sigma coeffs are not all set} :dt
Self-explanatory. :dd
{Pair resquared requires atom attributes quat, torque, shape} :dt
An atom style that defines these attributes must be used. :dd
{Pair style AIREBO requires atom IDs} :dt
This is a requirement to use the AIREBO potential. :dd
{Pair style AIREBO requires newton pair on} :dt
See the newton command. This is a restriction to use the AIREBO
potential. :dd
{Pair style COMB requires atom IDs} :dt
This is a requirement to use the AIREBO potential. :dd
{Pair style COMB requires atom attribute q} :dt
Self-explanatory. :dd
{Pair style COMB requires newton pair on} :dt
See the newton command. This is a restriction to use the COMB
potential. :dd
{Pair style MEAM requires newton pair on} :dt
See the newton command. This is a restriction to use the MEAM
potential. :dd
{Pair style Stillinger-Weber requires atom IDs} :dt
This is a requirement to use the SW potential. :dd
{Pair style Stillinger-Weber requires newton pair on} :dt
See the newton command. This is a restriction to use the SW
potential. :dd
{Pair style Tersoff requires atom IDs} :dt
This is a requirement to use the Tersoff potential. :dd
{Pair style Tersoff requires newton pair on} :dt
See the newton command. This is a restriction to use the Tersoff
potential. :dd
{Pair style born/coul/long requires atom attribute q} :dt
An atom style that defines this attribute must be used. :dd
{Pair style buck/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style buck/coul/long requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style coul/cut requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style does not support bond_style quartic} :dt
The pair style does not have a single() function, so it can
not be invoked by bond_style quartic. :dd
{Pair style does not support compute group/group} :dt
The pair_style does not have a single() function, so it cannot be
invokded by the compute group/group command. :dd
{Pair style does not support compute pair/local} :dt
The pair style does not have a single() function, so it can
not be invoked by fix bond/swap. :dd
{Pair style does not support compute property/local} :dt
The pair style does not have a single() function, so it can
not be invoked by fix bond/swap. :dd
{Pair style does not support fix bond/swap} :dt
The pair style does not have a single() function, so it can
not be invoked by fix bond/swap. :dd
{Pair style does not support pair_write} :dt
The pair style does not have a single() function, so it can
not be invoked by pair write. :dd
{Pair style does not support rRESPA inner/middle/outer} :dt
You are attempting to use rRESPA options with a pair style that
does not support them. :dd
{Pair style granular with history requires atoms have IDs} :dt
Atoms in the simulation do not have IDs, so history effects
cannot be tracked by the granular pair potential. :dd
{Pair style hbond/dreiding requires an atom map, see atom_modify} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires atom IDs} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires molecular system} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires newton pair on} :dt
See the newton command for details. :dd
{Pair style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Pair style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Pair style hybrid cannot use same pair style twice} :dt
The sub-style arguments of pair_style hybrid cannot be duplicated.
Check the input script. :dd
{Pair style is incompatible with KSpace style} :dt
If a pair style with a long-range Coulombic component is selected,
then a kspace style must also be used. :dd
{Pair style lj/charmm/coul/charmm requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/charmm/coul/long requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/class2/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/class2/coul/long requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/long requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/long/tip4p requires atom IDs} :dt
There are no atom IDs defined in the system and the TIP4P potential
requires them to find O,H atoms with a water molecule. :dd
{Pair style lj/cut/coul/long/tip4p requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/cut/coul/long/tip4p requires newton pair on} :dt
This is because the computation of constraint forces within a water
molecule adds forces to atoms owned by other processors. :dd
{Pair style lj/gromacs/coul/gromacs requires atom attribute q} :dt
An atom_style with this attribute is needed. :dd
{Pair style peri_lps requires atom style peri} :dt
This is because atom style peri stores quantities needed by
the peridynamic potential. :dd
{Pair style peri_pmb requires atom style peri} :dt
This is because atom style peri stores quantities needed by
the peridynamic potential. :dd
{Pair style reax requires atom IDs} :dt
This is a requirement to use the ReaxFF potential. :dd
{Pair style reax requires newton pair on} :dt
This is a requirement to use the ReaxFF potential. :dd
{Pair table cutoffs must all be equal to use with KSpace} :dt
When using pair style table with a long-range KSpace solver, the
cutoffs for all atom type pairs must all be the same, since the
long-range solver starts at that cutoff. :dd
{Pair table parameters did not set N} :dt
List of pair table parameters must include N setting. :dd
{Pair tersoff/zbl requires metal or real units} :dt
This is a current restriction of this pair potential. :dd
{Pair yukawa/colloid cannot be used with atom attribute diameter} :dt
Only finite-size particles defined by the shape command can be used. :dd
{Pair yukawa/colloid requires atom attribute shape} :dt
Self-explanatory. :dd
{Pair yukawa/colloid requires spherical particles} :dt
Self-explanatory. :dd
{Pair_coeff command before pair_style is defined} :dt
Self-explanatory. :dd
{Pair_coeff command before simulation box is defined} :dt
The pair_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Pair_modify command before pair_style is defined} :dt
Self-explanatory. :dd
{Pair_write command before pair_style is defined} :dt
Self-explanatory. :dd
{Particle on or inside fix wall surface} :dt
Particles must be "exterior" to the wall in order for energy/force to
be calculated. :dd
{Particle on or inside surface of region used in fix wall/region} :dt
Particles must be "exterior" to the region surface in order for
energy/force to be calculated. :dd
{Per-atom compute in equal-style variable formula} :dt
Equal-style variables cannot use per-atom quantities. :dd
{Per-atom energy was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Per-atom fix in equal-style variable formula} :dt
Equal-style variables cannot use per-atom quantities. :dd
{Per-atom virial was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to have
tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Per-processor system is too big} :dt
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer. :dd
{Potential energy ID for fix neb does not exist} :dt
Self-explanatory. :dd
{Potential file has duplicate entry} :dt
The potential file for a SW or Tersoff potential has more than
one entry for the same 3 ordered elements. :dd
{Potential file is missing an entry} :dt
The potential file for a SW or Tersoff potential does not have a
needed entry. :dd
{Power by 0 in variable formula} :dt
Self-explanatory. :dd
{Pressure ID for fix box/relax does not exist} :dt
The compute ID needed to compute pressure for the fix does not
exist. :dd
{Pressure ID for fix modify does not exist} :dt
Self-explanatory. :dd
{Pressure ID for fix npt/nph does not exist} :dt
Self-explanatory. :dd
{Pressure ID for fix press/berendsen does not exist} :dt
The compute ID needed to compute pressure for the fix does not
exist. :dd
{Pressure ID for thermo does not exist} :dt
The compute ID needed to compute pressure for thermodynamics does not
exist. :dd
{Pressure control can not be used with fix nvt/asphere} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt/sllod} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt/sphere} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph/asphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph/sphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph} :dt
Self-explanatory. :dd
{Pressure control must be used with fix npt/asphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix npt/sphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix npt} :dt
Self-explanatory. :dd
{Processor count in z must be 1 for 2d simulation} :dt
Self-explanatory. :dd
{Processor partitions are inconsistent} :dt
The total number of processors in all partitions must match the number
of processors LAMMPS is running on. :dd
{Processors command after simulation box is defined} :dt
The processors command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Quaternion creation numeric error} :dt
A numeric error occurred in the creation of a rigid body by the fix
rigid command. :dd
{R0 < 0 for fix spring command} :dt
Equilibrium spring length is invalid. :dd
{Reax_defs.h setting for NATDEF is too small} :dt
Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS. :dd
{Reax_defs.h setting for NNEIGHMAXDEF is too small} :dt
Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS. :dd
{Region ID for compute reduce/region does not exist} :dt
Self-explanatory. :dd
{Region ID for compute temp/region does not exist} :dt
Self-explanatory. :dd
{Region ID for dump cfg does not exist} :dt
Self-explanatory. :dd
{Region ID for dump custom does not exist} :dt
Self-explanatory. :dd
{Region ID for fix addforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Region ID for fix aveforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix deposit does not exist} :dt
Self-explanatory. :dd
{Region ID for fix evaporate does not exist} :dt
Self-explanatory. :dd
{Region ID for fix heat does not exist} :dt
Self-explanatory. :dd
{Region ID for fix setforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix wall/region does not exist} :dt
Self-explanatory. :dd
{Region ID in variable formula does not exist} :dt
Self-explanatory. :dd
{Region cannot have 0 length rotation vector} :dt
Self-explanatory. :dd
{Region intersect region ID does not exist} :dt
Self-explanatory. :dd
{Region union or intersect cannot be dynamic} :dt
The sub-regions can be dynamic, but not the combined region. :dd
{Region union region ID does not exist} :dt
One or more of the region IDs specified by the region union command
does not exist. :dd
{Replacing a fix, but new style != old style} :dt
A fix ID can be used a 2nd time, but only if the style matches the
previous fix. In this case it is assumed you with to reset a fix's
parameters. This error may mean you are mistakenly re-using a fix ID
when you do not intend to. :dd
{Replicate command before simulation box is defined} :dt
The replicate command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Replicate did not assign all atoms correctly} :dt
Atoms replicated by the replicate command were not assigned correctly
to processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box. :dd
{Replicated molecular system atom IDs are too big} :dt
See the setting for the allowed atom ID size in the src/lmptype.h
file. :dd
{Replicated system is too big} :dt
See the setting for bigint in the src/lmptype.h file. :dd
{Resetting timestep is not allowed with fix move} :dt
This is because fix move is moving atoms based on elapsed time. :dd
{Respa inner cutoffs are invalid} :dt
The first cutoff must be <= the second cutoff. :dd
{Respa levels must be >= 1} :dt
Self-explanatory. :dd
{Respa middle cutoffs are invalid} :dt
The first cutoff must be <= the second cutoff. :dd
{Reuse of compute ID} :dt
A compute ID cannot be used twice. :dd
{Reuse of dump ID} :dt
A dump ID cannot be used twice. :dd
{Reuse of region ID} :dt
A region ID cannot be used twice. :dd
{Rigid body has degenerate moment of inertia} :dt
Fix poems will only work with bodies (collections of atoms) that have
non-zero principal moments of inertia. This means they must be 3 or
more non-collinear atoms, even with joint atoms removed. :dd
{Rigid fix must come before NPT/NPH fix} :dt
NPT/NPH fix must be defined in input script after all rigid fixes,
else the rigid fix contribution to the pressure virial is
incorrect. :dd
{Rmask function in equal-style variable formula} :dt
Rmask is per-atom operation. :dd
{Run command before simulation box is defined} :dt
The run command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Run command start value is after start of run} :dt
Self-explanatory. :dd
{Run command stop value is before end of run} :dt
Self-explanatory. :dd
{Run_style command before simulation box is defined} :dt
The run_style command cannot be used before a read_data,
read_restart, or create_box command. :dd
{SRD bin size for fix srd differs from user request} :dt
Fix SRD had to adjust the bin size to fit the simulation box. :dd
{SRD bins for fix srd are not cubic enough} :dt
The bin shape is not within tolerance of cubic. :dd
{Same dimension twice in fix ave/spatial} :dt
Self-explanatory. :dd
{Set command before simulation box is defined} :dt
The set command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Set command with no atoms existing} :dt
No atoms are yet defined so the set command cannot be used. :dd
{Set region ID does not exist} :dt
Region ID specified in set command does not exist. :dd
{Shake angles have different bond types} :dt
All 3-atom angle-constrained SHAKE clusters specified by the fix shake
command that are the same angle type, must also have the same bond
types for the 2 bonds in the angle. :dd
{Shake atoms %d %d %d %d missing on proc %d at step} :dt
The 4 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake atoms %d %d %d missing on proc %d at step} :dt
The 3 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake atoms %d %d missing on proc %d at step} :dt
The 2 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake cluster of more than 4 atoms} :dt
A single cluster specified by the fix shake command can have no more
than 4 atoms. :dd
{Shake clusters are connected} :dt
A single cluster specified by the fix shake command must have a single
central atom with up to 3 other atoms bonded to it. :dd
{Shake determinant = 0.0} :dt
The determinant of the matrix being solved for a single cluster
specified by the fix shake command is numerically invalid. :dd
{Shake fix must come before NPT/NPH fix} :dt
NPT fix must be defined in input script after SHAKE fix, else the
SHAKE fix contribution to the pressure virial is incorrect. :dd
{Shape command before simulation box is defined} :dt
Self-explanatory. :dd
{Smallint setting in lmptype.h is invalid} :dt
It has to be the size of an integer. :dd
{Smallint setting in lmptype.h is not compatible} :dt
Smallint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Sqrt of negative value in variable formula} :dt
Self-explanatory. :dd
{Substitution for illegal variable} :dt
Input script line contained a variable that could not be substituted
for. :dd
{System in data file is too big} :dt
See the setting for bigint in the src/lmptype.h file. :dd
{TAD nsteps must be multiple of t_event} :dt
Self-explanatory. :dd
{TIP4P hydrogen has incorrect atom type} :dt
The TIP4P pairwise computation found an H atom whose type does not
agree with the specified H type. :dd
{TIP4P hydrogen is missing} :dt
The TIP4P pairwise computation failed to find the correct H atom
within a water molecule. :dd
{TMD target file did not list all group atoms} :dt
The target file for the fix tmd command did not list all atoms in the
fix group. :dd
{Tad command before simulation box is defined} :dt
Self-explanatory. :dd
{Tagint setting in lmptype.h is invalid} :dt
Tagint must be as large or larger than smallint. :dd
{Tagint setting in lmptype.h is not compatible} :dt
Smallint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Target temperature for fix nvt/npt/nph cannot be 0.0} :dt
Self-explanatory. :dd
{Target temperature for fix rigid/nvt cannot be 0.0} :dt
Self-explanatory. :dd
{Temper command before simulation box is defined} :dt
The temper command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Temperature ID for fix bond/swap does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix box/relax does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix nvt/nph/npt does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix press/berendsen does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix temp/berendsen does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix temp/rescale does not exist} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph/asphere} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph/sphere} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph} :dt
Self-explanatory. :dd
{Temperature control must be used with fix npt/asphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix npt/sphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix npt} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/asphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/sllod} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/sphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt} :dt
Self-explanatory. :dd
{Temperature for fix nvt/sllod does not have a bias} :dt
The specified compute must compute temperature with a bias. :dd
{Tempering could not find thermo_pe compute} :dt
This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command. :dd
{Tempering fix ID is not defined} :dt
The fix ID specified by the temper command does not exist. :dd
{Tempering temperature fix is not valid} :dt
The fix specified by the temper command is not one that controls
temperature (nvt or langevin). :dd
{Thermo and fix not computed at compatible times} :dt
Fixes generate values on specific timesteps. The thermo output
does not match these timesteps. :dd
{Thermo compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo compute does not compute array} :dt
Self-explanatory. :dd
{Thermo compute does not compute scalar} :dt
Self-explanatory. :dd
{Thermo compute does not compute vector} :dt
Self-explanatory. :dd
{Thermo compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo custom variable cannot be indexed} :dt
Self-explanatory. :dd
{Thermo custom variable is not equal-style variable} :dt
Only equal-style variables can be output with thermodynamics, not
atom-style variables. :dd
{Thermo every variable returned a bad timestep} :dt
The variable must return a timestep greater than the current timestep. :dd
{Thermo fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo fix does not compute array} :dt
Self-explanatory. :dd
{Thermo fix does not compute scalar} :dt
Self-explanatory. :dd
{Thermo fix does not compute vector} :dt
Self-explanatory. :dd
{Thermo fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo keyword in variable requires lattice be defined} :dt
The xlat, ylat, zlat keywords refer to lattice properties. :dd
{Thermo keyword in variable requires thermo to use/init pe} :dt
You are using a thermo keyword in a variable that requires
potential energy to be calculated, but your thermo output
does not use it. Add it to your thermo output. :dd
{Thermo keyword in variable requires thermo to use/init press} :dt
You are using a thermo keyword in a variable that requires pressure to
be calculated, but your thermo output does not use it. Add it to your
thermo output. :dd
{Thermo keyword in variable requires thermo to use/init temp} :dt
You are using a thermo keyword in a variable that requires temperature
to be calculated, but your thermo output does not use it. Add it to
your thermo output. :dd
{Thermo keyword requires lattice be defined} :dt
The xlat, ylat, zlat keywords refer to lattice properties. :dd
{Thermo style does not use press} :dt
Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity. :dd
{Thermo style does not use temp} :dt
Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity. :dd
{Thermo_modify int format does not contain d character} :dt
Self-explanatory. :dd
{Thermo_modify pressure ID does not compute pressure} :dt
The specified compute ID does not compute pressure. :dd
{Thermo_modify temperature ID does not compute temperature} :dt
The specified compute ID does not compute temperature. :dd
{Thermo_style command before simulation box is defined} :dt
The thermo_style command cannot be used before a read_data,
read_restart, or create_box command. :dd
{This variable thermo keyword cannot be used between runs} :dt
Keywords that refer to time (such as cpu, elapsed) do not
make sense in between runs. :dd
{Threshhold for an atom property that isn't allocated} :dt
A dump threshhold has been requested on a quantity that is
not defined by the atom style used in this simulation. :dd
{Timestep must be >= 0} :dt
Specified timestep size is invalid. :dd
{Too big a problem to use velocity create loop all} :dt
The system size must fit in a 32-bit integer to use this option. :dd
{Too big a timestep for dump dcd} :dt
The timestep must fit in a 32-bit integer to use this dump style. :dd
{Too big a timestep for dump xtc} :dt
The timestep must fit in a 32-bit integer to use this dump style. :dd
{Too few bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
{Too many atom sorting bins} :dt
This is likely due to an immense simulation box that has blown up
to a large size. :dd
{Too many atoms for dump dcd} :dt
The system size must fit in a 32-bit integer to use this dump
style. :dd
{Too many atoms for dump xtc} :dt
The system size must fit in a 32-bit integer to use this dump
style. :dd
{Too many atoms to dump sort} :dt
Cannot sort when running with more than 2^31 atoms. :dd
{Too many exponent bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
{Too many groups} :dt
The maximum number of atom groups (including the "all" group) is
given by MAX_GROUP in group.cpp and is 32. :dd
{Too many iterations} :dt
You must use a number of iterations that fit in a 32-bit integer
for minimization. :dd
{Too many mantissa bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
{Too many masses for fix shake} :dt
The fix shake command cannot list more masses than there are atom
types. :dd
{Too many neighbor bins} :dt
This is likely due to an immense simulation box that has blown up
to a large size. :dd
{Too many timesteps for NEB} :dt
You must use a number of timesteps that fit in a 32-bit integer
for NEB. :dd
{Too many total atoms} :dt
See the setting for bigint in the src/lmptype.h file. :dd
{Too many total bits for bitmapped lookup table} :dt
Table size specified via pair_modify command is too large. Note that
a value of N generates a 2^N size table. :dd
{Too many touching neighbors - boost MAXTOUCH} :dt
A granular simulation has too many neighbors touching one atom. The
MAXTOUCH parameter in fix_shear_history.cpp must be set larger and
LAMMPS must be re-built. :dd
{Too much per-proc info for dump} :dt
Number of local atoms times number of columns must fit in a 32-bit
integer for dump. :dd
{Tree structure in joint connections} :dt
Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a tree structure. :dd
{Triclinic box must be periodic in skewed dimensions} :dt
This is a requirement for using a non-orthogonal box. E.g. to set a
non-zero xy tilt, both x and y must be periodic dimensions. :dd
{Triclinic box skew is too large} :dt
The displacement in a skewed direction must be less than half the box
length in that dimension. E.g. the xy tilt must be between -half and
+half of the x box length. :dd
{Tried to convert a double to int, but input_double > INT_MAX} :dt
Self-explanatory. :dd
{Two groups cannot be the same in fix spring couple} :dt
Self-explanatory. :dd
{Unable to initialize accelerator for use} :dt
One or more specified accelerator(s) cannot currently be used by LAMMPS.
This can happen if the accelerator is already in use by another
process. :dd
{Unbalanced quotes in input line} :dt
No matching end double quote was found following a leading double
quote. :dd
{Unexpected end of data file} :dt
LAMMPS hit the end of the data file while attempting to read a
section. Something is wrong with the format of the data file. :dd
{Units command after simulation box is defined} :dt
The units command cannot be used after a read_data, read_restart, or
create_box command. :dd
{Universe/uloop variable count < # of partitions} :dt
A universe or uloop style variable must specify a number of values >= to the
number of processor partitions. :dd
{Unknown command: %s} :dt
The command is not known to LAMMPS. Check the input script. :dd
{Unknown identifier in data file: %s} :dt
A section of the data file cannot be read by LAMMPS. :dd
{Unknown table style in angle style table} :dt
Self-explanatory. :dd
{Unknown table style in bond style table} :dt
Self-explanatory. :dd
{Unknown table style in pair_style command} :dt
Style of table is invalid for use with pair_style table command. :dd
{Unrecognized lattice type in MEAM file 1} :dt
The lattice type in an entry of the MEAM library file is not
valid. :dd
{Unrecognized lattice type in MEAM file 2} :dt
The lattice type in an entry of the MEAM parameter file is not
valid. :dd
{Unrecognized pair style in compute pair command} :dt
Self-explanatory. :dd
{Use of compute temp/ramp with undefined lattice} :dt
Must use lattice command with compute temp/ramp command if units
option is set to lattice. :dd
{Use of displace_atoms with undefined lattice} :dt
Must use lattice command with displace_atoms command if units option
is set to lattice. :dd
{Use of displace_box with undefined lattice} :dt
Must use lattice command with displace_box command if units option is
set to lattice. :dd
{Use of fix ave/spatial with undefined lattice} :dt
A lattice must be defined to use fix ave/spatial with units = lattice. :dd
{Use of fix deform with undefined lattice} :dt
A lattice must be defined to use fix deform with units = lattice. :dd
{Use of fix deposit with undefined lattice} :dt
Must use lattice command with compute fix deposit command if units
option is set to lattice. :dd
{Use of fix dt/reset with undefined lattice} :dt
Must use lattice command with fix dt/reset command if units option is
set to lattice. :dd
{Use of fix indent with undefined lattice} :dt
The lattice command must be used to define a lattice before using the
fix indent command. :dd
{Use of fix move with undefined lattice} :dt
Must use lattice command with fix move command if units option is
set to lattice. :dd
{Use of fix recenter with undefined lattice} :dt
Must use lattice command with fix recenter command if units option is
set to lattice. :dd
{Use of fix wall with undefined lattice} :dt
Must use lattice command with fix wall command if units option is set
to lattice. :dd
{Use of region with undefined lattice} :dt
If scale = lattice (the default) for the region command, then a
lattice must first be defined via the lattice command. :dd
{Use of velocity with undefined lattice} :dt
If scale = lattice (the default) for the velocity set or velocity ramp
command, then a lattice must first be defined via the lattice command. :dd
{Using fix nvt/sllod with inconsistent fix deform remap option} :dt
Fix nvt/sllod requires that deforming atoms have a velocity profile
provided by "remap v" as a fix deform option. :dd
{Using fix nvt/sllod with no fix deform defined} :dt
Self-explanatory. :dd
{Using fix srd with inconsistent fix deform remap option} :dt
When shearing the box in an SRD simulation, the remap v option for fix
deform needs to be used. :dd
{Variable evaluation before simulation box is defined} :dt
Cannot evaluate a compute or fix or atom-based value in a variable
before the simulation has been setup. :dd
{Variable for compute ti is invalid style} :dt
Self-explanatory. :dd
{Variable for dump every is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix adapt is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix addforce is invalid style} :dt
Self-explanatory. :dd
{Variable for fix aveforce is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix efield is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix indent is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix indent is not equal style} :dt
Only equal-style variables can be used. :dd
{Variable for fix move is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix setforce is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix wall is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix wall/reflect is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix wall/srd is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for region is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for region is not equal style} :dt
Self-explanatory. :dd
{Variable for thermo every is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for velocity set is invalid style} :dt
Only atom-style variables can be used. :dd
{Variable formula compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable name for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Variable name for compute reduce does not exist} :dt
Self-explanatory. :dd
{Variable name for compute ti does not exist} :dt
Self-explanatory. :dd
{Variable name for dump every does not exist} :dt
Self-explanatory. :dd
{Variable name for fix adapt does not exist} :dt
Self-explanatory. :dd
{Variable name for fix addforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Variable name for fix aveforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix efield does not exist} :dt
Self-explanatory. :dd
{Variable name for fix indent does not exist} :dt
Self-explanatory. :dd
{Variable name for fix move does not exist} :dt
Self-explanatory. :dd
{Variable name for fix setforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix store/state does not exist} :dt
Self-explanatory. :dd
{Variable name for fix wall does not exist} :dt
Self-explanatory. :dd
{Variable name for fix wall/reflect does not exist} :dt
Self-explanatory. :dd
{Variable name for fix wall/srd does not exist} :dt
Self-explanatory. :dd
{Variable name for region does not exist} :dt
Self-explanatory. :dd
{Variable name for thermo every does not exist} :dt
Self-explanatory. :dd
{Variable name for velocity set does not exist} :dt
Self-explanatory. :dd
{Variable name must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Velocity command before simulation box is defined} :dt
The velocity command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Velocity command with no atoms existing} :dt
A velocity command has been used, but no atoms yet exist. :dd
{Velocity ramp in z for a 2d problem} :dt
Self-explanatory. :dd
{Velocity temperature ID does not compute temperature} :dt
The compute ID given to the velocity command must compute
temperature. :dd
{Virial was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Wall defined twice in fix wall command} :dt
Self-explanatory. :dd
{Wall defined twice in fix wall/reflect command} :dt
Self-explanatory. :dd
{Wall defined twice in fix wall/srd command} :dt
Self-explanatory. :dd
{Weighted neighbor list values are too big} :dt
You must have less atoms per processor to use this
style neighbor list. :dd
{World variable count doesn't match # of partitions} :dt
A world-style variable must specify a number of values equal to the
number of processor partitions. :dd
{Write_restart command before simulation box is defined} :dt
The write_restart command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Zero-length lattice orient vector} :dt
Self-explanatory. :dd
:dle
Warnings: :h4,link(warn)
:dlb
{All element names have been set to 'C' for dump cfg} :dt
Use the dump_modify command if you wish to override this. :dd
{Atom with molecule ID = 0 included in compute molecule group} :dt
The group used in a compute command that operates on moleclues
includes atoms with no molecule ID. This is probably not what you
want. :dd
{Broken bonds will not alter angles, dihedrals, or impropers} :dt
See the doc page for fix bond/break for more info on this
restriction. :dd
{Building an occasional neighobr list when atoms may have moved too far} :dt
This can cause LAMMPS to crash when the neighbor list is built.
The solution is to check for building the regular neighbor lists
more frequently. :dd
{Compute cna/atom cutoff may be too large to find ghost atom neighbors} :dt
The neighbor cutoff used may not encompass enough ghost atoms
to perform this operation correctly. :dd
{Computing temperature of portions of rigid bodies} :dt
The group defined by the temperature compute does not encompass all
the atoms in one or more rigid bodies, so the change in
degrees-of-freedom for the atoms in those partial rigid bodies will
not be accounted for. :dd
{Created bonds will not create angles, dihedrals, or impropers} :dt
See the doc page for fix bond/create for more info on this
restriction. :dd
{Dihedral problem: %d %d %d %d %d %d} :dt
Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry. :dd
{Dump dcd/xtc timestamp may be wrong with fix dt/reset} :dt
If the fix changes the timestep, the dump dcd file will not
reflect the change. :dd
{FENE bond too long: %d %d %d %g} :dt
A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up. :dd
{FENE bond too long: %d %g} :dt
A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up. :dd
{Fix SRD walls overlap but fix srd overlap not set} :dt
You likely want to set this in your input script. :dd
{Fix bond/swap will ignore defined angles} :dt
See the doc page for fix bond/swap for more info on this
restriction. :dd
{Fix move does not update angular momentum} :dt
Atoms store this quantity, but fix move does not (yet) update it. :dd
{Fix move does not update quaternions} :dt
Atoms store this quantity, but fix move does not (yet) update it. :dd
{Fix recenter should come after all other integration fixes} :dt
Other fixes may change the position of the center-of-mass, so
fix recenter should come last. :dd
{Fix srd SRD moves may trigger frequent reneighboring} :dt
This is because the SRD particles may move long distances. :dd
{Fix srd grid size > 1/4 of big particle diameter} :dt
This may cause accuracy problems. :dd
{Fix srd no-slip wall collisions with bin shifting} :dt
This is an inconsistent setting in your input script. :dd
{Fix srd particle moved outside valid domain} :dt
This may indicate a problem with your simulation parameters. :dd
{Fix srd particles may move > big particle diameter} :dt
This may cause accuracy problems. :dd
{Fix srd viscosity < 0.0 due to low SRD density} :dt
This may cause accuracy problems. :dd
{Fix thermal/conductivity comes before fix ave/spatial} :dt
The order of these 2 fixes in your input script is such that fix
thermal/conductivity comes first. If you are using fix ave/spatial to
measure the temperature profile induced by fix viscosity, then this
may cause a glitch in the profile since you are averaging immediately
after swaps have occurred. Flipping the order of the 2 fixes
typically helps. :dd
{Fix viscosity comes before fix ave/spatial} :dt
The order of these 2 fixes in your input script is such that
fix viscosity comes first. If you are using fix ave/spatial
to measure the velocity profile induced by fix viscosity, then
this may cause a glitch in the profile since you are averaging
immediately after swaps have occurred. Flipping the order
of the 2 fixes typically helps. :dd
{Group for fix_modify temp != fix group} :dt
The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do. :dd
{Improper problem: %d %d %d %d %d %d} :dt
Conformation of the 4 listed improper atoms is extreme; you may want
to check your simulation geometry. :dd
{Kspace_modify slab param < 2.0 may cause unphysical behavior} :dt
The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap. :dd
{Less insertions than requested} :dt
Less atom insertions occurred on this timestep due to the fix pour
command than were scheduled. This is probably because there were too
many overlaps detected. :dd
{Lost atoms: original %.15g current %.15g} :dt
A thermodynamic computation has detected lost atoms. :dd
{Mismatch between velocity and compute groups} :dt
The temperature computation used by the velocity command will not be
on the same group of atoms that velocities are being set for. :dd
{More than one compute centro/atom} :dt
It is not efficient to use compute centro/atom more than once. :dd
{More than one compute cluster/atom} :dt
It is not efficient to use compute cluster/atom more than once. :dd
{More than one compute cna/atom defined} :dt
It is not efficient to use compute cna/atom more than once. :dd
{More than one compute coord/atom} :dt
It is not efficient to use compute coord/atom more than once. :dd
{More than one compute damage/atom} :dt
It is not efficient to use compute ke/atom more than once. :dd
{More than one compute ke/atom} :dt
It is not efficient to use compute ke/atom more than once. :dd
{More than one fix poems} :dt
It is not efficient to use fix poems more than once. :dd
{More than one fix rigid} :dt
It is not efficient to use fix rigid more than once. :dd
{New thermo_style command, previous thermo_modify settings will be lost} :dt
If a thermo_style command is used after a thermo_modify command, the
settings changed by the thermo_modify command will be reset to their
default values. This is because the thermo_modify commmand acts on
the currently defined thermo style, and a thermo_style command creates
a new style. :dd
{No fixes defined, atoms won't move} :dt
If you are not using a fix like nve, nvt, npt then atom velocities and
coordinates will not be updated during timestepping. :dd
{No joints between rigid bodies, use fix rigid instead} :dt
The bodies defined by fix poems are not connected by joints. POEMS
will integrate the body motion, but it would be more efficient to use
fix rigid. :dd
{Not using real units with pair reax} :dt
This is most likely an error, unless you have created your own ReaxFF
parameter file in a different set of units. :dd
{One or more atoms are time integrated more than once} :dt
This is probably an error since you typically do not want to
advance the positions or velocities of an atom more than once
per timestep. :dd
{One or more compute molecules has atoms not in group} :dt
The group used in a compute command that operates on moleclues does
not include all the atoms in some molecules. This is probably not
what you want. :dd
{One or more respa levels compute no forces} :dt
This is computationally inefficient. :dd
{Pair COMB charge %.10f with force %.10f hit max barrier} :dt
Something is possibly wrong with your model. :dd
{Pair COMB charge %.10f with force %.10f hit min barrier} :dt
Something is possibly wrong with your model. :dd
{Pair dsmc: num_of_collisions > number_of_A} :dt
Collision model in DSMC is breaking down. :dd
{Pair dsmc: num_of_collisions > number_of_B} :dt
Collision model in DSMC is breaking down. :dd
{Particle deposition was unsuccessful} :dt
The fix deposit command was not able to insert as many atoms as
needed. The requested volume fraction may be too high, or other atoms
may be in the insertion region. :dd
{Reducing PPPM order b/c stencil extends beyond neighbor processor} :dt
LAMMPS is attempting this in order to allow the simulation
to run. It should not effect the PPPM accuracy. :dd
{Replacing a fix, but new group != old group} :dt
The ID and style of a fix match for a fix you are changing with a fix
command, but the new group you are specifying does not match the old
group. :dd
{Replicating in a non-periodic dimension} :dt
The parameters for a replicate command will cause a non-periodic
dimension to be replicated; this may cause unwanted behavior. :dd
{Resetting reneighboring criteria during PRD} :dt
A PRD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation. :dd
{Resetting reneighboring criteria during TAD} :dt
A TAD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation. :dd
{Resetting reneighboring criteria during minimization} :dt
Minimization requires that neigh_modify settings be delay = 0, every =
1, check = yes. Since these settings were not in place, LAMMPS
changed them and will restore them to their original values after the
minimization. :dd
{Restart file used different # of processors} :dt
The restart file was written out by a LAMMPS simulation running on a
different number of processors. Due to round-off, the trajectories of
your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors. :dd
{Restart file used different 3d processor grid} :dt
The restart file was written out by a LAMMPS simulation running on a
different 3d grid of processors. Due to round-off, the trajectories
of your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors. :dd
{Restart file used different boundary settings, using restart file values} :dt
Your input script cannot change these restart file settings. :dd
{Restart file used different newton bond setting, using restart file value} :dt
The restart file value will override the setting in the input script. :dd
{Restart file used different newton pair setting, using input script value} :dt
The input script value will override the setting in the restart file. :dd
{Restart file version does not match LAMMPS version} :dt
This may cause problems when reading the restart file. :dd
{Running PRD with only one replica} :dt
This is allowed, but you will get no parallel speed-up. :dd
{SRD bin shifting turned on due to small lamda} :dt
This is done to try to preserve accuracy. :dd
{SRD bin size for fix srd differs from user request} :dt
Check if the new bin size is acceptable. :dd
{SRD bins for fix srd are not cubic enough} :dt
Check if the bin shape is acceptable. :dd
{SRD particle %d started inside big particle %d on step %d bounce %d} :dt
This may not be a problem, but indicates one or more SRD particles are
being left inside solute particles. :dd
{Shake determinant < 0.0} :dt
The determinant of the quadratic equation being solved for a single
cluster specified by the fix shake command is numerically suspect. LAMMPS
will set it to 0.0 and continue. :dd
{Should not allow rigid bodies to bounce off relecting walls} :dt
LAMMPS allows this, but their dynamics are not computed correctly. :dd
{System is not charge neutral, net charge = %g} :dt
The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM. :dd
{Table inner cutoff >= outer cutoff} :dt
You specified an inner cutoff for a Coulombic table that is longer
than the global cutoff. Probably not what you wanted. :dd
{Temperature for MSST is not for group all} :dt
User-assigned temperature to MSST fix does not compute temperature for
all atoms. Since MSST computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by MSST could be inaccurate. :dd
{Temperature for NPT is not for group all} :dt
User-assigned temperature to NPT fix does not compute temperature for
all atoms. Since NPT computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by NPT could be inaccurate. :dd
{Temperature for fix modify is not for group all} :dt
The temperature compute is being used with a pressure calculation
which does operate on group all, so this may be inconsistent. :dd
{Temperature for thermo pressure is not for group all} :dt
User-assigned temperature to thermo via the thermo_modify command does
not compute temperature for all atoms. Since thermo computes a global
pressure, the kinetic energy contribution from the temperature is
assumed to also be for all atoms. Thus the pressure printed by thermo
could be inaccurate. :dd
{Too many common neighbors in CNA %d times} :dt
More than the maximum # of neighbors was found multiple times. This
was unexpected. :dd
{Too many inner timesteps in fix ttm} :dt
Self-explanatory. :dd
{Too many neighbors in CNA for %d atoms} :dt
More than the maximum # of neighbors was found multiple times. This
was unexpected. :dd
{Use special bonds = 0,1,1 with bond style fene/expand} :dt
Most FENE models need this setting for the special_bonds command. :dd
{Use special bonds = 0,1,1 with bond style fene} :dt
Most FENE models need this setting for the special_bonds command. :dd
{Using compute temp/deform with inconsistent fix deform remap option} :dt
Fix nvt/sllod assumes deforming atoms have a velocity profile provided
by "remap v" or "remap none" as a fix deform option. :dd
{Using compute temp/deform with no fix deform defined} :dt
This is probably an error, since it makes little sense to use
compute temp/deform in this case. :dd
{Using pair tail corrections with nonperiodic system} :dt
This is probably a bogus thing to do, since tail corrections are
computed by integrating the density of a periodic system out to
infinity. :dd
:dle
diff --git a/doc/Section_history.html b/doc/Section_history.html
index 522e4e122..d827db95e 100644
--- a/doc/Section_history.html
+++ b/doc/Section_history.html
@@ -1,127 +1,129 @@
<HTML>
<CENTER><A HREF = "Section_errors.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> -
<A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Manual.html">Next
Section</A>
</CENTER>
<HR>
<H3>13. Future and history
</H3>
-<P>This section lists features we are planning to add to LAMMPS, features
-of previous versions of LAMMPS, and features of other parallel
-molecular dynamics codes I've distributed.
+<P>This section lists features we plan to add to LAMMPS, features of
+previous versions of LAMMPS, and features of other parallel molecular
+dynamics codes our group has distributed.
</P>
13.1 <A HREF = "#hist_1">Coming attractions</A><BR>
13.2 <A HREF = "#hist_2">Past versions</A> <BR>
<HR>
+<HR>
+
<H4><A NAME = "hist_1"></A>13.1 Coming attractions
</H4>
<P>The <A HREF = "http://lammps.sandia.gov/future.html">Wish list link</A> on the
LAMMPS WWW page gives a list of features we are hoping to add to
LAMMPS in the future, including contact names of individuals you can
email if you are interested in contributing to the developement or
would be a future user of that feature.
</P>
<P>You can also send <A HREF = "http://lammps.sandia.gov/authors.html">email to the
developers</A> if you want to add
your wish to the list.
</P>
<HR>
<H4><A NAME = "hist_2"></A>13.2 Past versions
</H4>
<P>LAMMPS development began in the mid 1990s under a cooperative research
& development agreement (CRADA) between two DOE labs (Sandia and LLNL)
and 3 companies (Cray, Bristol Myers Squibb, and Dupont). The goal was
to develop a large-scale parallel classical MD code; the coding effort
was led by Steve Plimpton at Sandia.
</P>
<P>After the CRADA ended, a final F77 version, LAMMPS 99, was
released. As development of LAMMPS continued at Sandia, its memory
management was converted to F90; a final F90 version was released as
LAMMPS 2001.
</P>
<P>The current LAMMPS is a rewrite in C++ and was first publicly released
as an open source code in 2004. It includes many new features beyond
those in LAMMPS 99 or 2001. It also includes features from older
parallel MD codes written at Sandia, namely ParaDyn, Warp, and
GranFlow (see below).
</P>
<P>In late 2006 we began merging new capabilities into LAMMPS that were
developed by Aidan Thompson at Sandia for his MD code GRASP, which has
a parallel framework similar to LAMMPS. Most notably, these have
included many-body potentials - Stillinger-Weber, Tersoff, ReaxFF -
and the associated charge-equilibration routines needed for ReaxFF.
</P>
<P>The <A HREF = "http://lammps.sandia.gov/history.html">History link</A> on the
LAMMPS WWW page gives a timeline of features added to the
C++ open-source version of LAMMPS over the last several years.
</P>
<P>These older codes are available for download from the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
site</A>, except for Warp & GranFlow which were primarily used
internally. A brief listing of their features is given here.
</P>
<P>LAMMPS 2001
</P>
<UL><LI> F90 + MPI
<LI> dynamic memory
<LI> spatial-decomposition parallelism
<LI> NVE, NVT, NPT, NPH, rRESPA integrators
<LI> LJ and Coulombic pairwise force fields
<LI> all-atom, united-atom, bead-spring polymer force fields
<LI> CHARMM-compatible force fields
<LI> class 2 force fields
<LI> 3d/2d Ewald & PPPM
<LI> various force and temperature constraints
<LI> SHAKE
<LI> Hessian-free truncated-Newton minimizer
<LI> user-defined diagnostics
</UL>
<P>LAMMPS 99
</P>
<UL><LI> F77 + MPI
<LI> static memory allocation
<LI> spatial-decomposition parallelism
<LI> most of the LAMMPS 2001 features with a few exceptions
<LI> no 2d Ewald & PPPM
<LI> molecular force fields are missing a few CHARMM terms
<LI> no SHAKE
</UL>
<P>Warp
</P>
<UL><LI> F90 + MPI
<LI> spatial-decomposition parallelism
<LI> embedded atom method (EAM) metal potentials + LJ
<LI> lattice and grain-boundary atom creation
<LI> NVE, NVT integrators
<LI> boundary conditions for applying shear stresses
<LI> temperature controls for actively sheared systems
<LI> per-atom energy and centro-symmetry computation and output
</UL>
<P>ParaDyn
</P>
<UL><LI> F77 + MPI
<LI> atom- and force-decomposition parallelism
<LI> embedded atom method (EAM) metal potentials
<LI> lattice atom creation
<LI> NVE, NVT, NPT integrators
<LI> all serial DYNAMO features for controls and constraints
</UL>
<P>GranFlow
</P>
<UL><LI> F90 + MPI
<LI> spatial-decomposition parallelism
<LI> frictional granular potentials
<LI> NVE integrator
<LI> boundary conditions for granular flow and packing and walls
<LI> particle insertion
</UL>
</HTML>
diff --git a/doc/Section_history.txt b/doc/Section_history.txt
index 92600b7e2..2c6582537 100644
--- a/doc/Section_history.txt
+++ b/doc/Section_history.txt
@@ -1,122 +1,123 @@
"Previous Section"_Section_errors.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Manual.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
13. Future and history :h3
-This section lists features we are planning to add to LAMMPS, features
-of previous versions of LAMMPS, and features of other parallel
-molecular dynamics codes I've distributed.
+This section lists features we plan to add to LAMMPS, features of
+previous versions of LAMMPS, and features of other parallel molecular
+dynamics codes our group has distributed.
13.1 "Coming attractions"_#hist_1
13.2 "Past versions"_#hist_2 :all(b)
+:line
:line
13.1 Coming attractions :h4,link(hist_1)
The "Wish list link"_http://lammps.sandia.gov/future.html on the
LAMMPS WWW page gives a list of features we are hoping to add to
LAMMPS in the future, including contact names of individuals you can
email if you are interested in contributing to the developement or
would be a future user of that feature.
You can also send "email to the
developers"_http://lammps.sandia.gov/authors.html if you want to add
your wish to the list.
:line
13.2 Past versions :h4,link(hist_2)
LAMMPS development began in the mid 1990s under a cooperative research
& development agreement (CRADA) between two DOE labs (Sandia and LLNL)
and 3 companies (Cray, Bristol Myers Squibb, and Dupont). The goal was
to develop a large-scale parallel classical MD code; the coding effort
was led by Steve Plimpton at Sandia.
After the CRADA ended, a final F77 version, LAMMPS 99, was
released. As development of LAMMPS continued at Sandia, its memory
management was converted to F90; a final F90 version was released as
LAMMPS 2001.
The current LAMMPS is a rewrite in C++ and was first publicly released
as an open source code in 2004. It includes many new features beyond
those in LAMMPS 99 or 2001. It also includes features from older
parallel MD codes written at Sandia, namely ParaDyn, Warp, and
GranFlow (see below).
In late 2006 we began merging new capabilities into LAMMPS that were
developed by Aidan Thompson at Sandia for his MD code GRASP, which has
a parallel framework similar to LAMMPS. Most notably, these have
included many-body potentials - Stillinger-Weber, Tersoff, ReaxFF -
and the associated charge-equilibration routines needed for ReaxFF.
The "History link"_http://lammps.sandia.gov/history.html on the
LAMMPS WWW page gives a timeline of features added to the
C++ open-source version of LAMMPS over the last several years.
These older codes are available for download from the "LAMMPS WWW
site"_lws, except for Warp & GranFlow which were primarily used
internally. A brief listing of their features is given here.
LAMMPS 2001
F90 + MPI
dynamic memory
spatial-decomposition parallelism
NVE, NVT, NPT, NPH, rRESPA integrators
LJ and Coulombic pairwise force fields
all-atom, united-atom, bead-spring polymer force fields
CHARMM-compatible force fields
class 2 force fields
3d/2d Ewald & PPPM
various force and temperature constraints
SHAKE
Hessian-free truncated-Newton minimizer
user-defined diagnostics :ul
LAMMPS 99
F77 + MPI
static memory allocation
spatial-decomposition parallelism
most of the LAMMPS 2001 features with a few exceptions
no 2d Ewald & PPPM
molecular force fields are missing a few CHARMM terms
no SHAKE :ul
Warp
F90 + MPI
spatial-decomposition parallelism
embedded atom method (EAM) metal potentials + LJ
lattice and grain-boundary atom creation
NVE, NVT integrators
boundary conditions for applying shear stresses
temperature controls for actively sheared systems
per-atom energy and centro-symmetry computation and output :ul
ParaDyn
F77 + MPI
atom- and force-decomposition parallelism
embedded atom method (EAM) metal potentials
lattice atom creation
NVE, NVT, NPT integrators
all serial DYNAMO features for controls and constraints :ul
GranFlow
F90 + MPI
spatial-decomposition parallelism
frictional granular potentials
NVE integrator
boundary conditions for granular flow and packing and walls
particle insertion :ul
diff --git a/doc/Section_howto.html b/doc/Section_howto.html
index 7f200f929..bad450038 100644
--- a/doc/Section_howto.html
+++ b/doc/Section_howto.html
@@ -1,1962 +1,1963 @@
<HTML>
<CENTER><A HREF = "Section_accelerate.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_example.html">Next Section</A>
</CENTER>
<HR>
<H3>6. How-to discussions
</H3>
-<P>The following sections describe how to use various options within
-LAMMPS.
+<P>This section describes how to perform common tasks using LAMMPS.
</P>
6.1 <A HREF = "#howto_1">Restarting a simulation</A><BR>
6.2 <A HREF = "#howto_2">2d simulations</A><BR>
6.3 <A HREF = "#howto_3">CHARMM, AMBER, and DREIDING force fields</A><BR>
6.4 <A HREF = "#howto_4">Running multiple simulations from one input script</A><BR>
6.5 <A HREF = "#howto_5">Multi-replica simulations</A><BR>
6.6 <A HREF = "#howto_6">Granular models</A><BR>
6.7 <A HREF = "#howto_7">TIP3P water model</A><BR>
6.8 <A HREF = "#howto_8">TIP4P water model</A><BR>
6.9 <A HREF = "#howto_9">SPC water model</A><BR>
6.10 <A HREF = "#howto_10">Coupling LAMMPS to other codes</A><BR>
6.11 <A HREF = "#howto_11">Visualizing LAMMPS snapshots</A><BR>
6.12 <A HREF = "#howto_12">Triclinic (non-orthogonal) simulation boxes</A><BR>
6.13 <A HREF = "#howto_13">NEMD simulations</A><BR>
6.14 <A HREF = "#howto_14">Extended spherical and aspherical particles</A><BR>
6.15 <A HREF = "#howto_15">Output from LAMMPS (thermo, dumps, computes, fixes, variables)</A><BR>
6.16 <A HREF = "#howto_16">Thermostatting, barostatting and computing temperature</A><BR>
6.17 <A HREF = "#howto_17">Walls</A><BR>
6.18 <A HREF = "#howto_18">Elastic constants</A><BR>
6.19 <A HREF = "#howto_19">Library interface to LAMMPS</A><BR>
6.20 <A HREF = "#howto_20">Calculating thermal conductivity</A><BR>
6.21 <A HREF = "#howto_21">Calculating viscosity</A> <BR>
<P>The example input scripts included in the LAMMPS distribution and
-highlighted in <A HREF = "Section_example.html">this section</A> also show how to
+highlighted in <A HREF = "Section_example.html">Section_example</A> also show how to
setup and run various kinds of simulations.
</P>
<HR>
+<HR>
+
<A NAME = "howto_1"></A><H4>6.1 Restarting a simulation
</H4>
<P>There are 3 ways to continue a long LAMMPS simulation. Multiple
<A HREF = "run.html">run</A> commands can be used in the same input script. Each
run will continue from where the previous run left off. Or binary
restart files can be saved to disk using the <A HREF = "restart.html">restart</A>
command. At a later time, these binary files can be read via a
<A HREF = "read_restart.html">read_restart</A> command in a new script. Or they can
be converted to text data files and read by a
<A HREF = "read_data.html">read_data</A> command in a new script. <A HREF = "Section_tools.html">This
section</A> discusses the <I>restart2data</I> tool that is
used to perform the conversion.
</P>
<P>Here we give examples of 2 scripts that read either a binary restart
file or a converted data file and then issue a new run command to
continue where the previous run left off. They illustrate what
settings must be made in the new script. Details are discussed in the
documentation for the <A HREF = "read_restart.html">read_restart</A> and
<A HREF = "read_data.html">read_data</A> commands.
</P>
<P>Look at the <I>in.chain</I> input script provided in the <I>bench</I> directory
of the LAMMPS distribution to see the original script that these 2
scripts are based on. If that script had the line
</P>
<PRE>restart 50 tmp.restart
</PRE>
<P>added to it, it would produce 2 binary restart files (tmp.restart.50
and tmp.restart.100) as it ran.
</P>
<P>This script could be used to read the 1st restart file and re-run the
last 50 timesteps:
</P>
<PRE>read_restart tmp.restart.50
</PRE>
<PRE>neighbor 0.4 bin
neigh_modify every 1 delay 1
</PRE>
<PRE>fix 1 all nve
fix 2 all langevin 1.0 1.0 10.0 904297
</PRE>
<PRE>timestep 0.012
</PRE>
<PRE>run 50
</PRE>
<P>Note that the following commands do not need to be repeated because
their settings are included in the restart file: <I>units, atom_style,
special_bonds, pair_style, bond_style</I>. However these commands do
need to be used, since their settings are not in the restart file:
<I>neighbor, fix, timestep</I>.
</P>
<P>If you actually use this script to perform a restarted run, you will
notice that the thermodynamic data match at step 50 (if you also put a
"thermo 50" command in the original script), but do not match at step
100. This is because the <A HREF = "fix_langevin.html">fix langevin</A> command
uses random numbers in a way that does not allow for perfect restarts.
</P>
<P>As an alternate approach, the restart file could be converted to a data
file using this tool:
</P>
<PRE>restart2data tmp.restart.50 tmp.restart.data
</PRE>
<P>Then, this script could be used to re-run the last 50 steps:
</P>
<PRE>units lj
atom_style bond
pair_style lj/cut 1.12
pair_modify shift yes
bond_style fene
special_bonds 0.0 1.0 1.0
</PRE>
<PRE>read_data tmp.restart.data
</PRE>
<PRE>neighbor 0.4 bin
neigh_modify every 1 delay 1
</PRE>
<PRE>fix 1 all nve
fix 2 all langevin 1.0 1.0 10.0 904297
</PRE>
<PRE>timestep 0.012
</PRE>
<PRE>reset_timestep 50
run 50
</PRE>
<P>Note that nearly all the settings specified in the original <I>in.chain</I>
script must be repeated, except the <I>pair_coeff</I> and <I>bond_coeff</I>
commands since the new data file lists the force field coefficients.
Also, the <A HREF = "reset_timestep.html">reset_timestep</A> command is used to tell
LAMMPS the current timestep. This value is stored in restart files,
but not in data files.
</P>
<HR>
<A NAME = "howto_2"></A><H4>6.2 2d simulations
</H4>
<P>Use the <A HREF = "dimension.html">dimension</A> command to specify a 2d simulation.
</P>
<P>Make the simulation box periodic in z via the <A HREF = "boundary.html">boundary</A>
command. This is the default.
</P>
<P>If using the <A HREF = "create_box.html">create box</A> command to define a
simulation box, set the z dimensions narrow, but finite, so that the
create_atoms command will tile the 3d simulation box with a single z
plane of atoms - e.g.
</P>
<PRE><A HREF = "create_box.html">create box</A> 1 -10 10 -10 10 -0.25 0.25
</PRE>
<P>If using the <A HREF = "read_data.html">read data</A> command to read in a file of
atom coordinates, set the "zlo zhi" values to be finite but narrow,
similar to the create_box command settings just described. For each
atom in the file, assign a z coordinate so it falls inside the
z-boundaries of the box - e.g. 0.0.
</P>
<P>Use the <A HREF = "fix_enforce2d.html">fix enforce2d</A> command as the last
defined fix to insure that the z-components of velocities and forces
are zeroed out every timestep. The reason to make it the last fix is
so that any forces induced by other fixes will be zeroed out.
</P>
<P>Many of the example input scripts included in the LAMMPS distribution
are for 2d models.
</P>
<P>IMPORTANT NOTE: Some models in LAMMPS treat particles as extended
spheres, as opposed to point particles. In 2d, the particles will
still be spheres, not disks, meaning their moment of inertia will be
the same as in 3d.
</P>
<HR>
<A NAME = "howto_3"></A><H4>6.3 CHARMM, AMBER, and DREIDING force fields
</H4>
<P>A force field has 2 parts: the formulas that define it and the
coefficients used for a particular system. Here we only discuss
formulas implemented in LAMMPS that correspond to formulas commonly
used in the CHARMM, AMBER, and DREIDING force fields. Setting
coefficients is done in the input data file via the
<A HREF = "read_data.html">read_data</A> command or in the input script with
commands like <A HREF = "pair_coeff.html">pair_coeff</A> or
-<A HREF = "bond_coeff.html">bond_coeff</A>. See <A HREF = "Section_tools.html">this section</A>
+<A HREF = "bond_coeff.html">bond_coeff</A>. See <A HREF = "Section_tools.html">Section_tools</A>
for additional tools that can use CHARMM or AMBER to assign force
field coefficients and convert their output into LAMMPS input.
</P>
<P>See <A HREF = "#MacKerell">(MacKerell)</A> for a description of the CHARMM force
field. See <A HREF = "#Cornell">(Cornell)</A> for a description of the AMBER force
field.
</P>
<P>These style choices compute force field formulas that are consistent
with common options in CHARMM or AMBER. See each command's
documentation for the formula it computes.
</P>
<UL><LI><A HREF = "bond_harmonic.html">bond_style</A> harmonic
<LI><A HREF = "angle_charmm.html">angle_style</A> charmm
<LI><A HREF = "dihedral_charmm.html">dihedral_style</A> charmm
<LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/charmm
<LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/charmm/implicit
<LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/long
</UL>
<UL><LI><A HREF = "special_bonds.html">special_bonds</A> charmm
<LI><A HREF = "special_bonds.html">special_bonds</A> amber
</UL>
<P>DREIDING is a generic force field developed by the <A HREF = "http://www.wag.caltech.edu">Goddard
group</A> at Caltech and is useful for
predicting structures and dynamics of organic, biological and
main-group inorganic molecules. The philosophy in DREIDING is to use
general force constants and geometry parameters based on simple
hybridization considerations, rather than individual force constants
and geometric parameters that depend on the particular combinations of
atoms involved in the bond, angle, or torsion terms. DREIDING has an
<A HREF = "pair_hbond_dreiding.html">explicit hydrogen bond term</A> to describe
interactions involving a hydrogen atom on very electronegative atoms
(N, O, F).
</P>
<P>See <A HREF = "#Mayo">(Mayo)</A> for a description of the DREIDING force field
</P>
<P>These style choices compute force field formulas that are consistent
with the DREIDING force field. See each command's
documentation for the formula it computes.
</P>
<UL><LI><A HREF = "bond_harmonic.html">bond_style</A> harmonic
<LI><A HREF = "bond_morse.html">bond_style</A> morse
</UL>
<UL><LI><A HREF = "angle_harmonic.html">angle_style</A> harmonic
<LI><A HREF = "angle_cosine.html">angle_style</A> cosine
<LI><A HREF = "angle_cosine_periodic.html">angle_style</A> cosine/periodic
</UL>
<UL><LI><A HREF = "dihedral_charmm.html">dihedral_style</A> charmm
<LI><A HREF = "improper_umbrella.html">improper_style</A> umbrella
</UL>
<UL><LI><A HREF = "pair_buck.html">pair_style</A> buck
<LI><A HREF = "pair_buck.html">pair_style</A> buck/coul/cut
<LI><A HREF = "pair_buck.html">pair_style</A> buck/coul/long
<LI><A HREF = "pair_lj.html">pair_style</A> lj/cut
<LI><A HREF = "pair_lj.html">pair_style</A> lj/cut/coul/cut
<LI><A HREF = "pair_lj.html">pair_style</A> lj/cut/coul/long
</UL>
<UL><LI><A HREF = "pair_hbond_dreiding.html">pair_style</A> hbond/dreiding/lj
<LI><A HREF = "pair_hbond_dreiding.html">pair_style</A> hbond/dreiding/morse
</UL>
<UL><LI><A HREF = "special_bonds.html">special_bonds</A> dreiding
</UL>
<HR>
<A NAME = "howto_4"></A><H4>6.4 Running multiple simulations from one input script
</H4>
<P>This can be done in several ways. See the documentation for
individual commands for more details on how these examples work.
</P>
<P>If "multiple simulations" means continue a previous simulation for
more timesteps, then you simply use the <A HREF = "run.html">run</A> command
multiple times. For example, this script
</P>
<PRE>units lj
atom_style atomic
read_data data.lj
run 10000
run 10000
run 10000
run 10000
run 10000
</PRE>
<P>would run 5 successive simulations of the same system for a total of
50,000 timesteps.
</P>
<P>If you wish to run totally different simulations, one after the other,
the <A HREF = "clear.html">clear</A> command can be used in between them to
re-initialize LAMMPS. For example, this script
</P>
<PRE>units lj
atom_style atomic
read_data data.lj
run 10000
clear
units lj
atom_style atomic
read_data data.lj.new
run 10000
</PRE>
<P>would run 2 independent simulations, one after the other.
</P>
<P>For large numbers of independent simulations, you can use
<A HREF = "variable.html">variables</A> and the <A HREF = "next.html">next</A> and
<A HREF = "jump.html">jump</A> commands to loop over the same input script
multiple times with different settings. For example, this
script, named in.polymer
</P>
<PRE>variable d index run1 run2 run3 run4 run5 run6 run7 run8
shell cd $d
read_data data.polymer
run 10000
shell cd ..
clear
next d
jump in.polymer
</PRE>
<P>would run 8 simulations in different directories, using a data.polymer
file in each directory. The same concept could be used to run the
same system at 8 different temperatures, using a temperature variable
and storing the output in different log and dump files, for example
</P>
<PRE>variable a loop 8
variable t index 0.8 0.85 0.9 0.95 1.0 1.05 1.1 1.15
log log.$a
read data.polymer
velocity all create $t 352839
fix 1 all nvt $t $t 100.0
dump 1 all atom 1000 dump.$a
run 100000
next t
next a
jump in.polymer
</PRE>
<P>All of the above examples work whether you are running on 1 or
multiple processors, but assumed you are running LAMMPS on a single
partition of processors. LAMMPS can be run on multiple partitions via
the "-partition" command-line switch as described in <A HREF = "Section_start.html#start_6">this
section</A> of the manual.
</P>
<P>In the last 2 examples, if LAMMPS were run on 3 partitions, the same
scripts could be used if the "index" and "loop" variables were
replaced with <I>universe</I>-style variables, as described in the
<A HREF = "variable.html">variable</A> command. Also, the "next t" and "next a"
commands would need to be replaced with a single "next a t" command.
With these modifications, the 8 simulations of each script would run
on the 3 partitions one after the other until all were finished.
Initially, 3 simulations would be started simultaneously, one on each
partition. When one finished, that partition would then start
the 4th simulation, and so forth, until all 8 were completed.
</P>
<HR>
<A NAME = "howto_5"></A><H4>6.5 Multi-replica simulations
</H4>
<P>Several commands in LAMMPS run mutli-replica simulations, meaning
that multiple instances (replicas) of your simulation are run
simultaneously, with small amounts of data exchanged between replicas
periodically.
</P>
<P>These are the relevant commands:
</P>
<UL><LI><A HREF = "neb.html">neb</A> for nudged elastic band calculations
<LI><A HREF = "prd.html">prd</A> for parallel replica dynamics
<LI><A HREF = "tad.html">tad</A> for temperature accelerated dynamics
<LI><A HREF = "temper.html">temper</A> for parallel tempering
</UL>
<P>NEB is a method for finding transition states and barrier energies.
PRD and TAD are methods for performing accelerated dynamics to find
and perform infrequent events. Parallel tempering or replica exchange
runs different replicas at a series of temperature to facilitate
rare-event sampling.
</P>
<P>These command can only be used if LAMMPS was built with the "replica"
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P>In all these cases, you must run with one or more processors per
replica. The processors assigned to each replica are determined at
run-time by using the <A HREF = "Section_start.html#start_6">-partition command-line
switch</A> to launch LAMMPS on multiple
partitions, which in this context are the same as replicas. E.g.
these commands:
</P>
<PRE>mpirun -np 16 lmp_linux -partition 8x2 -in in.temper
mpirun -np 8 lmp_linux -partition 8x1 -in in.neb
</PRE>
<P>would each run 8 replicas, on either 16 or 8 processors. Note the use
of the <A HREF = "Section_start.html#start_6">-in command-line switch</A> to specify
the input script which is required when running in multi-replica mode.
</P>
<P>Also note that with MPI installed on a machine (e.g. your desktop),
you can run on more (virtual) processors than you have physical
processors. Thus the above commands could be run on a
single-processor (or few-processor) desktop so that you can run
a multi-replica simulation on more replicas than you have
physical processors.
</P>
<HR>
<A NAME = "howto_6"></A><H4>6.6 Granular models
</H4>
<P>Granular system are composed of spherical particles with a diameter,
as opposed to point particles. This means they have an angular
velocity and torque can be imparted to them to cause them to rotate.
</P>
<P>To run a simulation of a granular model, you will want to use
the following commands:
</P>
<UL><LI><A HREF = "atom_style.html">atom_style sphere</A>
<LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
<LI><A HREF = "fix_gravity.html">fix gravity</A>
</UL>
<P>This compute
</P>
<UL><LI><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A>
</UL>
<P>calculates rotational kinetic energy which can be <A HREF = "Section_howto.html#howto_15">output with
thermodynamic info</A>.
</P>
<P>Use one of these 3 pair potentials, which compute forces and torques
between interacting pairs of particles:
</P>
<UL><LI><A HREF = "pair_style.html">pair_style</A> gran/history
<LI><A HREF = "pair_style.html">pair_style</A> gran/no_history
<LI><A HREF = "pair_style.html">pair_style</A> gran/hertzian
</UL>
<P>These commands implement fix options specific to granular systems:
</P>
<UL><LI><A HREF = "fix_freeze.html">fix freeze</A>
<LI><A HREF = "fix_pour.html">fix pour</A>
<LI><A HREF = "fix_viscous.html">fix viscous</A>
<LI><A HREF = "fix_wall_gran.html">fix wall/gran</A>
</UL>
<P>The fix style <I>freeze</I> zeroes both the force and torque of frozen
atoms, and should be used for granular system instead of the fix style
<I>setforce</I>.
</P>
<P>For computational efficiency, you can eliminate needless pairwise
computations between frozen atoms by using this command:
</P>
<UL><LI><A HREF = "neigh_modify.html">neigh_modify</A> exclude
</UL>
<HR>
<A NAME = "howto_7"></A><H4>6.7 TIP3P water model
</H4>
<P>The TIP3P water model as implemented in CHARMM
<A HREF = "#MacKerell">(MacKerell)</A> specifies a 3-site rigid water molecule with
charges and Lennard-Jones parameters assigned to each of the 3 atoms.
In LAMMPS the <A HREF = "fix_shake.html">fix shake</A> command can be used to hold
the two O-H bonds and the H-O-H angle rigid. A bond style of
<I>harmonic</I> and an angle style of <I>harmonic</I> or <I>charmm</I> should also be
used.
</P>
<P>These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid TIP3P-CHARMM model with a
cutoff. The K values can be used if a flexible TIP3P model (without
fix shake) is desired. If the LJ epsilon and sigma for HH and OH are
set to 0.0, it corresponds to the original 1983 TIP3P model
<A HREF = "#Jorgensen">(Jorgensen)</A>.
</P>
<P>O mass = 15.9994<BR>
H mass = 1.008 <BR>
</P>
<P>O charge = -0.834<BR>
H charge = 0.417 <BR>
</P>
<P>LJ epsilon of OO = 0.1521<BR>
LJ sigma of OO = 3.1507<BR>
LJ epsilon of HH = 0.0460<BR>
LJ sigma of HH = 0.4000<BR>
LJ epsilon of OH = 0.0836<BR>
LJ sigma of OH = 1.7753 <BR>
</P>
<P>K of OH bond = 450<BR>
r0 of OH bond = 0.9572 <BR>
</P>
<P>K of HOH angle = 55<BR>
theta of HOH angle = 104.52 <BR>
</P>
<P>These are the parameters to use for TIP3P with a long-range Coulombic
solver (Ewald or PPPM in LAMMPS), see <A HREF = "#Price">(Price)</A> for details:
</P>
<P>O mass = 15.9994<BR>
H mass = 1.008 <BR>
</P>
<P>O charge = -0.830<BR>
H charge = 0.415 <BR>
</P>
<P>LJ epsilon of OO = 0.102<BR>
LJ sigma of OO = 3.188<BR>
LJ epsilon, sigma of OH, HH = 0.0 <BR>
</P>
<P>K of OH bond = 450<BR>
r0 of OH bond = 0.9572 <BR>
</P>
<P>K of HOH angle = 55<BR>
theta of HOH angle = 104.52 <BR>
</P>
<P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
models</A>.
</P>
<HR>
<A NAME = "howto_8"></A><H4>6.8 TIP4P water model
</H4>
<P>The four-point TIP4P rigid water model extends the traditional
three-point TIP3P model by adding an additional site, usually
massless, where the charge associated with the oxygen atom is placed.
This site M is located at a fixed distance away from the oxygen along
the bisector of the HOH bond angle. A bond style of <I>harmonic</I> and an
angle style of <I>harmonic</I> or <I>charmm</I> should also be used.
</P>
<P>Currently, only a four-point model for long-range Coulombics is
implemented via the LAMMPS <A HREF = "pair_lj.html">pair style
lj/cut/coul/long/tip4p</A>. A cutoff version may be added
the future. For both models, the bond lengths and bond angles should
be held fixed using the <A HREF = "fix_shake.html">fix shake</A> command.
</P>
<P>These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid TIP4P model with a cutoff
<A HREF = "#Jorgensen">(Jorgensen)</A>. Note that the OM distance is specified in
the <A HREF = "pair_style.html">pair_style</A> command, not as part of the pair
coefficients.
</P>
<P>O mass = 15.9994<BR>
H mass = 1.008 <BR>
</P>
<P>O charge = -1.040<BR>
H charge = 0.520 <BR>
</P>
<P>r0 of OH bond = 0.9572<BR>
theta of HOH angle = 104.52 <BR>
</P>
<P>OM distance = 0.15 <BR>
</P>
<P>LJ epsilon of O-O = 0.1550<BR>
LJ sigma of O-O = 3.1536<BR>
LJ epsilon, sigma of OH, HH = 0.0 <BR>
</P>
<P>These are the parameters to use for TIP4P with a long-range Coulombic
solver (Ewald or PPPM in LAMMPS):
</P>
<P>O mass = 15.9994<BR>
H mass = 1.008 <BR>
</P>
<P>O charge = -1.0484<BR>
H charge = 0.5242 <BR>
</P>
<P>r0 of OH bond = 0.9572<BR>
theta of HOH angle = 104.52 <BR>
</P>
<P>OM distance = 0.1250 <BR>
</P>
<P>LJ epsilon of O-O = 0.16275<BR>
LJ sigma of O-O = 3.16435<BR>
LJ epsilon, sigma of OH, HH = 0.0 <BR>
</P>
<P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
models</A>.
</P>
<HR>
<A NAME = "howto_9"></A><H4>6.9 SPC water model
</H4>
<P>The SPC water model specifies a 3-site rigid water molecule with
charges and Lennard-Jones parameters assigned to each of the 3 atoms.
In LAMMPS the <A HREF = "fix_shake.html">fix shake</A> command can be used to hold
the two O-H bonds and the H-O-H angle rigid. A bond style of
<I>harmonic</I> and an angle style of <I>harmonic</I> or <I>charmm</I> should also be
used.
</P>
<P>These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid SPC model.
</P>
<P>O mass = 15.9994<BR>
H mass = 1.008 <BR>
</P>
<P>O charge = -0.820<BR>
H charge = 0.410 <BR>
</P>
<P>LJ epsilon of OO = 0.1553<BR>
LJ sigma of OO = 3.166<BR>
LJ epsilon, sigma of OH, HH = 0.0 <BR>
</P>
<P>r0 of OH bond = 1.0<BR>
theta of HOH angle = 109.47 <BR>
</P>
<P>Note that as originally proposed, the SPC model was run with a 9
Angstrom cutoff for both LJ and Coulommbic terms. It can also be used
with long-range Coulombics (Ewald or PPPM in LAMMPS), without changing
any of the parameters above, though it becomes a different model in
that mode of usage.
</P>
<P>The SPC/E (extended) water model is the same, except
the partial charge assignemnts change:
</P>
<P>O charge = -0.8476<BR>
H charge = 0.4238 <BR>
</P>
<P>See the <A HREF = "#Berendsen">(Berendsen)</A> reference for more details on both
the SPC and SPC/E models.
</P>
<P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
models</A>.
</P>
<HR>
<A NAME = "howto_10"></A><H4>6.10 Coupling LAMMPS to other codes
</H4>
<P>LAMMPS is designed to allow it to be coupled to other codes. For
example, a quantum mechanics code might compute forces on a subset of
atoms and pass those forces to LAMMPS. Or a continuum finite element
(FE) simulation might use atom positions as boundary conditions on FE
nodal points, compute a FE solution, and return interpolated forces on
MD atoms.
</P>
<P>LAMMPS can be coupled to other codes in at least 3 ways. Each has
advantages and disadvantages, which you'll have to think about in the
context of your application.
</P>
<P>(1) Define a new <A HREF = "fix.html">fix</A> command that calls the other code. In
this scenario, LAMMPS is the driver code. During its timestepping,
the fix is invoked, and can make library calls to the other code,
which has been linked to LAMMPS as a library. This is the way the
<A HREF = "http://www.rpi.edu/~anderk5/lab">POEMS</A> package that performs constrained rigid-body motion on
groups of atoms is hooked to LAMMPS. See the
<A HREF = "fix_poems.html">fix_poems</A> command for more details. See <A HREF = "Section_modify.html">this
section</A> of the documentation for info on how to add
a new fix to LAMMPS.
</P>
<P>(2) Define a new LAMMPS command that calls the other code. This is
conceptually similar to method (1), but in this case LAMMPS and the
other code are on a more equal footing. Note that now the other code
is not called during the timestepping of a LAMMPS run, but between
runs. The LAMMPS input script can be used to alternate LAMMPS runs
with calls to the other code, invoked via the new command. The
<A HREF = "run.html">run</A> command facilitates this with its <I>every</I> option, which
makes it easy to run a few steps, invoke the command, run a few steps,
invoke the command, etc.
</P>
<P>In this scenario, the other code can be called as a library, as in
(1), or it could be a stand-alone code, invoked by a system() call
made by the command (assuming your parallel machine allows one or more
processors to start up another program). In the latter case the
stand-alone code could communicate with LAMMPS thru files that the
command writes and reads.
</P>
-<P>See <A HREF = "Section_modify.html">this section</A> of the documentation for how to
-add a new command to LAMMPS.
+<P>See <A HREF = "Section_modify.html">Section_modify</A> of the documentation for how
+to add a new command to LAMMPS.
</P>
<P>(3) Use LAMMPS as a library called by another code. In this case the
other code is the driver and calls LAMMPS as needed. Or a wrapper
code could link and call both LAMMPS and another code as libraries.
Again, the <A HREF = "run.html">run</A> command has options that allow it to be
invoked with minimal overhead (no setup or clean-up) if you wish to do
multiple short runs, driven by another program.
</P>
<P>Examples of driver codes that call LAMMPS as a library are included in
the "couple" directory of the LAMMPS distribution; see couple/README
for more details:
</P>
<UL><LI>simple: simple driver programs in C++ and C which invoke LAMMPS as a
library
<LI>lammps_quest: coupling of LAMMPS and <A HREF = "http://dft.sandia.gov/Quest">Quest</A>, to run classical
MD with quantum forces calculated by a density functional code
<LI>lammps_spparks: coupling of LAMMPS and <A HREF = "http://www.sandia.gov/~sjplimp/spparks.html">SPPARKS</A>, to couple
a kinetic Monte Carlo model for grain growth using MD to calculate
strain induced across grain boundaries
</UL>
<P><A HREF = "Section_start.html#start_4">This section</A> of the documentation
describes how to build LAMMPS as a library. Once this is done, you
can interface with LAMMPS either via C++, C, Fortran, or Python (or
any other language that supports a vanilla C-like interface). For
example, from C++ you could create one (or more) "instances" of
LAMMPS, pass it an input script to process, or execute individual
commands, all by invoking the correct class methods in LAMMPS. From C
or Fortran you can make function calls to do the same things. See
-<A HREF = "Section_python.html">this section</A> of the manual for a description of
-the Python wrapper provided with LAMMPS that operates through the
+<A HREF = "Section_python.html">Section_python</A> of the manual for a description
+of the Python wrapper provided with LAMMPS that operates through the
LAMMPS library interface.
</P>
<P>The files src/library.cpp and library.h contain the C-style interface
-to LAMMPS. See <A HREF = "Section_howto.html#howto_19">this section</A> of the manual
-for a description of the interface and how to extend it for your
-needs.
+to LAMMPS. See <A HREF = "Section_howto.html#howto_19">Section_howto 19</A> of the
+manual for a description of the interface and how to extend it for
+your needs.
</P>
<P>Note that the lammps_open() function that creates an instance of
LAMMPS takes an MPI communicator as an argument. This means that
instance of LAMMPS will run on the set of processors in the
communicator. Thus the calling code can run LAMMPS on all or a subset
of processors. For example, a wrapper script might decide to
alternate between LAMMPS and another code, allowing them both to run
on all the processors. Or it might allocate half the processors to
LAMMPS and half to the other code and run both codes simultaneously
before syncing them up periodically. Or it might instantiate multiple
instances of LAMMPS to perform different calculations.
</P>
<HR>
<A NAME = "howto_11"></A><H4>6.11 Visualizing LAMMPS snapshots
</H4>
<P>LAMMPS itself does not do visualization, but snapshots from LAMMPS
simulations can be visualized (and analyzed) in a variety of ways.
</P>
<P>LAMMPS snapshots are created by the <A HREF = "dump.html">dump</A> command which can
create files in several formats. The native LAMMPS dump format is a
text file (see "dump atom" or "dump custom") which can be visualized
by the <A HREF = "Section_tools.html#xmovie">xmovie</A> program, included with the
LAMMPS package. This produces simple, fast 2d projections of 3d
systems, and can be useful for rapid debugging of simulation geometry
and atom trajectories.
</P>
<P>Several programs included with LAMMPS as auxiliary tools can convert
native LAMMPS dump files to other formats. See the
<A HREF = "Section_tools.html">Section_tools</A> doc page for details. The first is
the <A HREF = "Section_tools.html#charmm">ch2lmp tool</A>, which contains a
lammps2pdb Perl script which converts LAMMPS dump files into PDB
files. The second is the <A HREF = "Section_tools.html#arc">lmp2arc tool</A> which
converts LAMMPS dump files into Accelrys' Insight MD program files.
The third is the <A HREF = "Section_tools.html#cfg">lmp2cfg tool</A> which converts
LAMMPS dump files into CFG files which can be read into the
<A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A> visualizer.
</P>
<P>A Python-based toolkit distributed by our group can read native LAMMPS
dump files, including custom dump files with additional columns of
user-specified atom information, and convert them to various formats
or pipe them into visualization software directly. See the <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py
WWW site</A> for details. Specifically, Pizza.py can convert
LAMMPS dump files into PDB, XYZ, <A HREF = "http://www.ensight.com">Ensight</A>, and VTK formats.
Pizza.py can pipe LAMMPS dump files directly into the Raster3d and
RasMol visualization programs. Pizza.py has tools that do interactive
3d OpenGL visualization and one that creates SVG images of dump file
snapshots.
</P>
<P>LAMMPS can create XYZ files directly (via "dump xyz") which is a
simple text-based file format used by many visualization programs
including <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A>.
</P>
<P>LAMMPS can create DCD files directly (via "dump dcd") which can be
read by <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> in conjunction with a CHARMM PSF file. Using this
form of output avoids the need to convert LAMMPS snapshots to PDB
files. See the <A HREF = "dump.html">dump</A> command for more information on DCD
files.
</P>
<P>LAMMPS can create XTC files directly (via "dump xtc") which is GROMACS
file format which can also be read by <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> for visualization.
See the <A HREF = "dump.html">dump</A> command for more information on XTC files.
</P>
<HR>
<A NAME = "howto_12"></A><H4>6.12 Triclinic (non-orthogonal) simulation boxes
</H4>
<P>By default, LAMMPS uses an orthogonal simulation box to encompass the
particles. The <A HREF = "boundary.html">boundary</A> command sets the boundary
conditions of the box (periodic, non-periodic, etc). The orthogonal
box has its "origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors
starting from the origin given by <B>a</B> = (xhi-xlo,0,0); <B>b</B> =
(0,yhi-ylo,0); <B>c</B> = (0,0,zhi-zlo). The 6 parameters
(xlo,xhi,ylo,yhi,zlo,zhi) are defined at the time the simluation box
is created, e.g. by the <A HREF = "create_box.html">create_box</A> or
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands. Additionally, LAMMPS defines box size parameters lx,ly,lz
where lx = xhi-xlo, and similarly in the y and z dimensions. The 6
parameters, as well as lx,ly,lz, can be output via the <A HREF = "thermo_style.html">thermo_style
custom</A> command.
</P>
<P>LAMMPS also allows simulations to be perfored in non-orthogonal
simulation boxes shaped as a parallelepiped with triclinic symmetry.
The parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by
3 edge vectors starting from the origin given by <B>a</B> = (xhi-xlo,0,0); <B>b</B>
= (xy,yhi-ylo,0); <B>c</B> = (xz,yz,zhi-zlo). <I>Xy,xz,yz</I> can be 0.0 or
positive or negative values and are called "tilt factors" because they
are the amount of displacement applied to faces of an originally
orthogonal box to transform it into the parallelepiped. Note that in
LAMMPS the triclinic simulation box edge vectors <B>a</B>, <B>b</B>, and <B>c</B> cannot be
arbitrary vectors. As indicated, <B>a</B> must be aligned with the x axis, <B>b</B>
must be in the xy plane, and <B>c</B> is arbitrary. However, this is not a
restriction since it is possible to rotate any set of 3 crystal basis
vectors so that they meet this restriction.
</P>
<P>The 9 parameters (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) are defined at the
time the simluation box is created. This happens in one of 3 ways.
If the <A HREF = "create_box.html">create_box</A> command is used with a region of
style <I>prism</I>, then a triclinic box is setup. See the
<A HREF = "region.html">region</A> command for details. If the
<A HREF = "read_data.html">read_data</A> command is used to define the simulation
box, and the header of the data file contains a line with the "xy xz
yz" keyword, then a triclinic box is setup. See the
<A HREF = "read_data.html">read_data</A> command for details. Finally, if the
<A HREF = "read_restart.html">read_restart</A> command reads a restart file which
was written from a simulation using a triclinic box, then a triclinic
box will be setup for the restarted simulation.
</P>
<P>Note that you can define a triclinic box with all 3 tilt factors =
0.0, so that it is initially orthogonal. This is necessary if the box
will become non-orthogonal, e.g. due to the <A HREF = "fix_nh.html">fix npt</A> or
<A HREF = "fix_deform.html">fix deform</A> commands. Alternatively, you can use the
<A HREF = "change_box.html">change_box</A> command to convert a simulation box from
orthogonal to triclinic and vice versa.
</P>
<P>As with orthogonal boxes, LAMMPS defines triclinic box size parameters
lx,ly,lz where lx = xhi-xlo, and similarly in the y and z dimensions.
The 9 parameters, as well as lx,ly,lz, can be output via the
<A HREF = "thermo_style.html">thermo_style custom</A> command.
</P>
<P>To avoid extremely tilted boxes (which would be computationally
inefficient), no tilt factor can skew the box more than half the
distance of the parallel box length, which is the 1st dimension in the
tilt factor (x for xz). For example, if xlo = 2 and xhi = 12, then
the x box length is 10 and the xy tilt factor must be between -5 and
5. Similarly, both xz and yz must be between -(xhi-xlo)/2 and
+(yhi-ylo)/2. Note that this is not a limitation, since if the
maximum tilt factor is 5 (as in this example), then configurations
with tilt = ..., -15, -5, 5, 15, 25, ... are geometrically all
equivalent.
</P>
<P>Triclinic crystal structures are often defined using three lattice
constants <I>a</I>, <I>b</I>, and <I>c</I>, and three angles <I>alpha</I>, <I>beta</I> and
<I>gamma</I>. Note that in this nomenclature, the a, b, and c lattice constants
are the scalar lengths of the edge vectors <B>a</B>, <B>b</B>, and <B>c</B> defined
above. The
relationship between these 6 quantities (a,b,c,alpha,beta,gamma) and
the LAMMPS box sizes (lx,ly,lz) = (xhi-xlo,yhi-ylo,zhi-zlo) and tilt
factors (xy,xz,yz) is as follows:
</P>
<CENTER><IMG SRC = "Eqs/box.jpg">
</CENTER>
<P>The inverse relationship can be written as follows:
</P>
<CENTER><IMG SRC = "Eqs/box_inverse.jpg">
</CENTER>
<P>The values of <I>a</I>, <I>b</I>, <I>c</I> , <I>alpha</I>, <I>beta</I> , and <I>gamma</I> can be printed
out or accessed by computes using the
<A HREF = "thermo_style.html">thermo_style custom</A> keywords
<I>cella</I>, <I>cellb</I>, <I>cellc</I>, <I>cellalpha</I>, <I>cellbeta</I>, <I>cellgamma</I>,
respectively.
</P>
<P>As discussed on the <A HREF = "dump.html">dump</A> command doc page, when the BOX
BOUNDS for a snapshot is written to a dump file for a triclinic box,
an orthogonal bounding box which encloses the triclinic simulation box
is output, along with the 3 tilt factors (xy, xz, yz) of the triclinic
box, formatted as follows:
</P>
<PRE>ITEM: BOX BOUNDS xy xz yz
xlo_bound xhi_bound xy
ylo_bound yhi_bound xz
zlo_bound zhi_bound yz
</PRE>
<P>This bounding box is convenient for many visualization programs and is
calculated from the 9 triclinic box parameters
(xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) as follows:
</P>
<PRE>xlo_bound = xlo + MIN(0.0,xy,xz,xy+xz)
xhi_bound = xhi + MAX(0.0,xy,xz,xy+xz)
ylo_bound = ylo + MIN(0.0,yz)
yhi_bound = yhi + MAX(0.0,yz)
zlo_bound = zlo
zhi_bound = zhi
</PRE>
<P>These formulas can be inverted if you need to convert the bounding box
back into the triclinic box parameters, e.g. xlo = xlo_bound -
MIN(0.0,xy,xz,xy+xz).
</P>
<P>One use of triclinic simulation boxes is to model solid-state crystals
with triclinic symmetry. The <A HREF = "lattice.html">lattice</A> command can be
used with non-orthogonal basis vectors to define a lattice that will
tile a triclinic simulation box via the
<A HREF = "create_atoms.html">create_atoms</A> command.
</P>
<P>A second use is to run Parinello-Rahman dyanamics via the <A HREF = "fix_nh.html">fix
npt</A> command, which will adjust the xy, xz, yz tilt
factors to compensate for off-diagonal components of the pressure
tensor. The analalog for an <A HREF = "minimize.html">energy minimization</A> is
the <A HREF = "fix_box_relax.html">fix box/relax</A> command.
</P>
<P>A third use is to shear a bulk solid to study the response of the
material. The <A HREF = "fix_deform.html">fix deform</A> command can be used for
this purpose. It allows dynamic control of the xy, xz, yz tilt
factors as a simulation runs. This is discussed in the next section
on non-equilibrium MD (NEMD) simulations.
</P>
<HR>
<A NAME = "howto_13"></A><H4>6.13 NEMD simulations
</H4>
<P>Non-equilibrium molecular dynamics or NEMD simulations are typically
used to measure a fluid's rheological properties such as viscosity.
In LAMMPS, such simulations can be performed by first setting up a
non-orthogonal simulation box (see the preceding Howto section).
</P>
<P>A shear strain can be applied to the simulation box at a desired
strain rate by using the <A HREF = "fix_deform.html">fix deform</A> command. The
<A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> command can be used to thermostat
the sheared fluid and integrate the SLLOD equations of motion for the
system. Fix nvt/sllod uses <A HREF = "compute_temp_deform.html">compute
temp/deform</A> to compute a thermal temperature
by subtracting out the streaming velocity of the shearing atoms. The
velocity profile or other properties of the fluid can be monitored via
the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command.
</P>
<P>As discussed in the previous section on non-orthogonal simulation
boxes, the amount of tilt or skew that can be applied is limited by
LAMMPS for computational efficiency to be 1/2 of the parallel box
length. However, <A HREF = "fix_deform.html">fix deform</A> can continuously strain
a box by an arbitrary amount. As discussed in the <A HREF = "fix_deform.html">fix
deform</A> command, when the tilt value reaches a limit,
the box is re-shaped to the opposite limit which is an equivalent
tiling of periodic space. The strain rate can then continue to change
as before. In a long NEMD simulation these box re-shaping events may
occur many times.
</P>
<P>In a NEMD simulation, the "remap" option of <A HREF = "fix_deform.html">fix
deform</A> should be set to "remap v", since that is what
<A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> assumes to generate a velocity
profile consistent with the applied shear strain rate.
</P>
<P>An alternative method for calculating viscosities is provided via the
<A HREF = "fix_viscosity.html">fix viscosity</A> command.
</P>
<HR>
<A NAME = "howto_14"></A><H4>6.14 Extended spherical and aspherical particles
</H4>
<P>Typical MD models treat atoms or particles as point masses.
Sometimes, however, it is desirable to have a model with finite-size
particles such as spheres or aspherical ellipsoids. The difference is
that such particles have a moment of inertia, rotational energy, and
angular momentum. Rotation is induced by torque from interactions
with other particles.
</P>
<P>LAMMPS has several options for running simulations with these kinds of
particles. The following aspects are discussed in turn:
</P>
<UL><LI>atom styles
<LI>pair potentials
<LI>time integration
<LI>computes, thermodynamics, and dump output
<LI>rigid bodies composed of extended particles
</UL>
<H5>Atom styles
</H5>
<P>There are 2 <A HREF = "atom_style.html">atom styles</A> that allow for definition of
finite-size particles: sphere and ellipsoid. The peri atom style also
treats particles as having a volume, but that is internal to the
<A HREF = "pair_peri.html">pair_style peri</A> potentials. The dipole atom style is
most often used in conjunction with finite-size particles.
</P>
<P>The sphere style defines particles that are spheriods and each
particle can have a unique diameter and mass (or density). These
particles store an angular velocity (omega) and can be acted upon by
torque. The "set" command can be used to modify the diameter and mass
of individual particles, after then are created.
</P>
<P>The ellipsoid style defines particles that are ellipsoids and thus can
be aspherical. Each particle has a shape, specified by 3 diameters,
and mass (or density). These particles store an angular momentum and
their orientation (quaternion), and can be acted upon by torque. They
do not store an angular velocity (omega), which can be in a different
direction than angular momentum, rather they compute it as needed.
The "set" command can be used to modify the diameter, orientation, and
mass of individual particles, after then are created. It also has a
brief explanation of what quaternions are.
</P>
<P>The dipole style does not define extended particles, but is often
used in conjunction with spherical particles, via a command like
</P>
<PRE>atom_style hybrid sphere dipole
</PRE>
<P>This is because when dipoles interact with each other, they induce
torques, and a particle must be extended (i.e. have a moment of
inertia) in order to respond and rotate. See the <A HREF = "atom_style.html">atom_style
dipole</A> command for details. The "set" command can be
used to modify the orientation and length of the dipole moment of
individual particles, after then are created.
</P>
<P>Note that if one of these atom styles is used (or multiple styles via
the <A HREF = "atom_style.html">atom_style hybrid</A> command), not all particles in
the system are required to be finite-size or aspherical. For example,
if the 3 shape parameters are set to the same value, the particle will
be a sphere rather than an ellipsoid. If the 3 shape parameters are
all set to 0.0 or if the diameter is set to 0.0, it will be a point
particle. If the length of the dipole moment is set to zero, the
particle will not have a point dipole associated with it. The pair
styles used to compute pairwise interactions will typically compute
the correct interaction in these simplified (cheaper) cases.
<A HREF = "pair_hybrid.html">Pair_style hybrid</A> can be used to insure the correct
interactions are computed for the appropriate style of interactions.
Likewise, using groups to partition particles (ellipsoids versus
spheres versus point particles) will allow you to use the appropriate
time integrators and temperature computations for each class of
particles. See the doc pages for various commands for details.
</P>
<P>Also note that for <A HREF = "dimension.html">2d simulations</A>, finite-size
spheres and ellipsoids are still treated as 3d particles, rather than
as circular disks or ellipses. This means they have the same moment
of inertia for a 3d extended object. When their temperature is
coomputed, the correct degrees of freedom are used for rotation in a
2d versus 3d system.
</P>
<H5>Pair potentials
</H5>
<P>When a system with extended particles is defined, the particles will
only rotate and experience torque if the force field computes such
interactions. These are the various <A HREF = "pair_style.html">pair styles</A>
that generate torque:
</P>
<UL><LI><A HREF = "pair_gran.html">pair_style gran/history</A>
<LI><A HREF = "pair_gran.html">pair_style gran/hertzian</A>
<LI><A HREF = "pair_gran.html">pair_style gran/no_history</A>
<LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A>
<LI><A HREF = "pair_gayberne.html">pair_style gayberne</A>
<LI><A HREF = "pair_resquared.html">pair_style resquared</A>
<LI><A HREF = "pair_lubricate.html">pair_style lubricate</A>
</UL>
<P>The <A HREF = "pair_gran.html">granular pair styles</A> are used with spherical
particles. The <A HREF = "pair_dipole.html">dipole pair style</A> is used with
<A HREF = "atom_style.html">atom_style dipole</A>, which could be applied to
spherical or ellipsoidal particles. The <A HREF = "pair_gayberne.html">GayBerne</A>
and <A HREF = "pair_resquared.html">REsquared</A> potentials require ellipsoidal
particles, though they will also work if the 3 shape parameters are
the same (a sphere). The <A HREF = "pair_lubricate.html">lubrication potential</A>
works with spherical particles.
</P>
<H5>Time integration
</H5>
<P>There are 3 fixes that perform time integration on extended spherical
particles, meaning the integrators update the rotational orientation
and angular velocity or angular momentum of the particles:
</P>
<UL><LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
<LI><A HREF = "fix_nvt_sphere.html">fix nvt/sphere</A>
<LI><A HREF = "fix_npt_sphere.html">fix npt/sphere</A>
</UL>
<P>Likewise, there are 3 fixes that perform time integration on
ellipsoids as extended aspherical particles:
</P>
<UL><LI><A HREF = "fix_nve_asphere.html">fix nve/asphere</A>
<LI><A HREF = "fix_nvt_asphere.html">fix nvt/asphere</A>
<LI><A HREF = "fix_npt_asphere.html">fix npt/asphere</A>
</UL>
<P>The advantage of these fixes is that those which thermostat the
particles include the rotational degrees of freedom in the temperature
calculation and thermostatting. Other thermostats can be used with
fix nve/sphere or fix nve/asphere, such as fix langevin or fix
temp/berendsen, but those thermostats only operate on the
translational kinetic energy of the extended particles.
</P>
<P>Note that for mixtures of point and extended particles, you should
only use these integration fixes on <A HREF = "group.html">groups</A> which contain
extended particles.
</P>
<H5>Computes, thermodynamics, and dump output
</H5>
<P>There are 4 computes that calculate the temperature or rotational energy
of extended spherical or aspherical particles (ellipsoids):
</P>
<UL><LI><A HREF = "compute_temp_sphere.html">compute temp/sphere</A>
<LI><A HREF = "compute_temp_asphere.html">compute temp/asphere</A>
<LI><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A>
<LI><A HREF = "compute_erotate_asphere.html">compute erotate/asphere</A>
</UL>
<P>These include rotational degrees of freedom in their computation. If
you wish the thermodynamic output of temperature or pressure to use
one of these computes (e.g. for a system entirely composed of extended
particles), then the compute can be defined and the
<A HREF = "thermo_modify.html">thermo_modify</A> command used. Note that by
default thermodynamic quantities will be calculated with a temperature
that only includes translational degrees of freedom. See the
<A HREF = "thermo_style.html">thermo_style</A> command for details.
</P>
<P>The <A HREF = "dump.html">dump custom</A> command can output various attributes of
extended particles, including the dipole moment (mu), the angular
velocity (omega), the angular momentum (angmom), the quaternion
(quat), and the torque (tq) on the particle.
</P>
<H5>Rigid bodies composed of extended particles
</H5>
<P>The <A HREF = "fix_rigid.html">fix rigid</A> command treats a collection of
particles as a rigid body, computes its inertia tensor, sums the total
force and torque on the rigid body each timestep due to forces on its
constituent particles, and integrates the motion of the rigid body.
</P>
<P>If any of the constituent particles of a rigid body are extended
particles (spheres or ellipsoids), then their contribution to the
inertia tensor of the body is different than if they were point
particles. This means the rotational dynamics of the rigid body will
be different. Thus a model of a dimer is different if the dimer
consists of two point masses versus two extended sphereoids, even if
the two particles have the same mass. Extended particles that
experience torque due to their interaction with other particles will
also impart that torque to a rigid body they are part of.
</P>
<P>See the "fix rigid" command for example of complex rigid-body models
it is possible to define in LAMMPS.
</P>
<P>Note that the <A HREF = "fix_shake.html">fix shake</A> command can also be used to
treat 2, 3, or 4 particles as a rigid body, but it always assumes the
particles are point masses.
</P>
<HR>
<A NAME = "howto_15"></A><H4>6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables)
</H4>
<P>There are four basic kinds of LAMMPS output:
</P>
<UL><LI><A HREF = "thermo_style.html">Thermodynamic output</A>, which is a list
of quantities printed every few timesteps to the screen and logfile.
<LI><A HREF = "dump.html">Dump files</A>, which contain snapshots of atoms and various
per-atom values and are written at a specified frequency.
<LI>Certain fixes can output user-specified quantities to files: <A HREF = "fix_ave_time.html">fix
ave/time</A> for time averaging, <A HREF = "fix_ave_spatial.html">fix
ave/spatial</A> for spatial averaging, and <A HREF = "fix_print.html">fix
print</A> for single-line output of
<A HREF = "variable.html">variables</A>. Fix print can also output to the
screen.
<LI><A HREF = "restart.html">Restart files</A>.
</UL>
<P>A simulation prints one set of thermodynamic output and (optionally)
restart files. It can generate any number of dump files and fix
output files, depending on what <A HREF = "dump.html">dump</A> and <A HREF = "fix.html">fix</A>
commands you specify.
</P>
<P>As discussed below, LAMMPS gives you a variety of ways to determine
what quantities are computed and printed when the thermodynamics,
dump, or fix commands listed above perform output. Throughout this
discussion, note that users can also <A HREF = "Section_modify.html">add their own computes and fixes
to LAMMPS</A> which can then generate values that can
then be output with these commands.
</P>
<P>The following sub-sections discuss different LAMMPS command related
to output and the kind of data they operate on and produce:
</P>
<UL><LI><A HREF = "#global">Global/per-atom/local data</A>
<LI><A HREF = "#scalar">Scalar/vector/array data</A>
<LI><A HREF = "#thermo">Thermodynamic output</A>
<LI><A HREF = "#dump">Dump file output</A>
<LI><A HREF = "#fixoutput">Fixes that write output files</A>
<LI><A HREF = "#computeoutput">Computes that process output quantities</A>
<LI><A HREF = "#fixoutput">Fixes that process output quantities</A>
<LI><A HREF = "#compute">Computes that generate values to output</A>
<LI><A HREF = "#fix">Fixes that generate values to output</A>
<LI><A HREF = "#variable">Variables that generate values to output</A>
<LI><A HREF = "#table">Summary table of output options and data flow between commands</A>
</UL>
<H5><A NAME = "global"></A>Global/per-atom/local data
</H5>
<P>Various output-related commands work with three different styles of
data: global, per-atom, or local. A global datum is one or more
system-wide values, e.g. the temperature of the system. A per-atom
datum is one or more values per atom, e.g. the kinetic energy of each
atom. Local datums are calculated by each processor based on the
atoms it owns, but there may be zero or more per atom, e.g. a list of
bond distances.
</P>
<H5><A NAME = "scalar"></A>Scalar/vector/array data
</H5>
<P>Global, per-atom, and local datums can each come in three kinds: a
single scalar value, a vector of values, or a 2d array of values. The
doc page for a "compute" or "fix" or "variable" that generates data
will specify both the style and kind of data it produces, e.g. a
per-atom vector.
</P>
<P>When a quantity is accessed, as in many of the output commands
discussed below, it can be referenced via the following bracket
notation, where ID in this case is the ID of a compute. The leading
"c_" would be replaced by "f_" for a fix, or "v_" for a variable:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >c_ID </TD><TD > entire scalar, vector, or array</TD></TR>
<TR><TD >c_ID[I] </TD><TD > one element of vector, one column of array</TD></TR>
<TR><TD >c_ID[I][J] </TD><TD > one element of array
</TD></TR></TABLE></DIV>
<P>In other words, using one bracket reduces the dimension of the data
once (vector -> scalar, array -> vector). Using two brackets reduces
the dimension twice (array -> scalar). Thus a command that uses
scalar values as input can typically also process elements of a vector
or array.
</P>
<H5><A NAME = "thermo"></A>Thermodynamic output
</H5>
<P>The frequency and format of thermodynamic output is set by the
<A HREF = "thermo.html">thermo</A>, <A HREF = "thermo_style.html">thermo_style</A>, and
<A HREF = "thermo_modify.html">thermo_modify</A> commands. The
<A HREF = "thermo_style.html">thermo_style</A> command also specifies what values
are calculated and written out. Pre-defined keywords can be specified
(e.g. press, etotal, etc). Three additional kinds of keywords can
also be specified (c_ID, f_ID, v_name), where a <A HREF = "compute.html">compute</A>
or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A> provides the value to be
output. In each case, the compute, fix, or variable must generate
global values for input to the <A HREF = "dump.html">thermo_style custom</A>
command.
</P>
<H5><A NAME = "dump"></A>Dump file output
</H5>
<P>Dump file output is specified by the <A HREF = "dump.html">dump</A> and
<A HREF = "dump_modify.html">dump_modify</A> commands. There are several
pre-defined formats (dump atom, dump xtc, etc).
</P>
<P>There is also a <A HREF = "dump.html">dump custom</A> format where the user
specifies what values are output with each atom. Pre-defined atom
attributes can be specified (id, x, fx, etc). Three additional kinds
of keywords can also be specified (c_ID, f_ID, v_name), where a
<A HREF = "compute.html">compute</A> or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A>
provides the values to be output. In each case, the compute, fix, or
variable must generate per-atom values for input to the <A HREF = "dump.html">dump
custom</A> command.
</P>
<P>There is also a <A HREF = "dump.html">dump local</A> format where the user specifies
what local values to output. A pre-defined index keyword can be
specified to enumuerate the local values. Two additional kinds of
keywords can also be specified (c_ID, f_ID), where a
<A HREF = "compute.html">compute</A> or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A>
provides the values to be output. In each case, the compute or fix
must generate local values for input to the <A HREF = "dump.html">dump local</A>
command.
</P>
<H5><A NAME = "fixoutput"></A>Fixes that write output files
</H5>
<P>Sevarl fixes take various quantities as input and can write output
files: <A HREF = "fix_ave_time.html">fix ave/time</A>, <A HREF = "fix_ave_spatial.html">fix
ave/spatial</A>, <A HREF = "fix_ave_histo.html">fix ave/histo</A>,
<A HREF = "fix_ave_correlate.html">fix ave/correlate</A>, and <A HREF = "fix_print.html">fix
print</A>.
</P>
<P>The <A HREF = "fix_ave_time.html">fix ave/time</A> command enables direct output to
a file and/or time-averaging of global scalars or vectors. The user
specifies one or more quantities as input. These can be global
<A HREF = "compute.html">compute</A> values, global <A HREF = "fix.html">fix</A> values, or
<A HREF = "variable.html">variables</A> of any style except the atom style which
produces per-atom values. Since a variable can refer to keywords used
by the <A HREF = "thermo_style.html">thermo_style custom</A> command (like temp or
press) and individual per-atom values, a wide variety of quantities
can be time averaged and/or output in this way. If the inputs are one
or more scalar values, then the fix generate a global scalar or vector
of output. If the inputs are one or more vector values, then the fix
generates a global vector or array of output. The time-averaged
output of this fix can also be used as input to other output commands.
</P>
<P>The <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command enables direct
output to a file of spatial-averaged per-atom quantities like those
output in dump files, within 1d layers of the simulation box. The
per-atom quantities can be atom density (mass or number) or atom
attributes such as position, velocity, force. They can also be
per-atom quantities calculated by a <A HREF = "compute.html">compute</A>, by a
<A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>. The
spatial-averaged output of this fix can also be used as input to other
output commands.
</P>
<P>The <A HREF = "fix_ave_histo.html">fix ave/histo</A> command enables direct output
to a file of histogrammed quantities, which can be global or per-atom
or local quantities. The histogram output of this fix can also be
used as input to other output commands.
</P>
<P>The <A HREF = "fix_ave_histo.html">fix ave/correlate</A> command enables direct
output to a file of time-correlated quantities, which can be global
scalars. The correlation matrix output of this fix can also be used
as input to other output commands.
</P>
<P>The <A HREF = "fix_print.html">fix print</A> command can generate a line of output
written to the screen and log file or to a separate file, periodically
during a running simulation. The line can contain one or more
<A HREF = "variable.html">variable</A> values for any style variable except the atom
style). As explained above, variables themselves can contain
references to global values generated by <A HREF = "thermo_style.html">thermodynamic
keywords</A>, <A HREF = "compute.html">computes</A>,
<A HREF = "fix.html">fixes</A>, or other <A HREF = "variable.html">variables</A>, or to per-atom
values for a specific atom. Thus the <A HREF = "fix_print.html">fix print</A>
command is a means to output a wide variety of quantities separate
from normal thermodynamic or dump file output.
</P>
<H5><A NAME = "computeoutput"></A>Computes that process output quantities
</H5>
<P>The <A HREF = "compute_reduce.html">compute reduce</A> and <A HREF = "compute_reduce.html">compute
reduce/region</A> commands take one or more per-atom
or local vector quantities as inputs and "reduce" them (sum, min, max,
ave) to scalar quantities. These are produced as output values which
can be used as input to other output commands.
</P>
<P>The <A HREF = "compute_slice.html">compute slice</A> command take one or more global
vector or array quantities as inputs and extracts a subset of their
values to create a new vector or array. These are produced as output
values which can be used as input to other output commands.
</P>
<P>The <A HREF = "compute_property_atom.html">compute property/atom</A> command takes a
list of one or more pre-defined atom attributes (id, x, fx, etc) and
stores the values in a per-atom vector or array. These are produced
as output values which can be used as input to other output commands.
The list of atom attributes is the same as for the <A HREF = "dump.html">dump
custom</A> command.
</P>
<P>The <A HREF = "compute_property_local.html">compute property/local</A> command takes
a list of one or more pre-defined local attributes (bond info, angle
info, etc) and stores the values in a local vector or array. These
are produced as output values which can be used as input to other
output commands.
</P>
<P>The <A HREF = "compute_atom_molecule.html">compute atom/molecule</A> command takes a
list of one or more per-atom quantities (from a compute, fix, per-atom
variable) and sums the quantities on a per-molecule basis. It
produces a global vector or array as output values which can be used
as input to other output commands.
</P>
<H5><A NAME = "fixoutput"></A>Fixes that process output quantities
</H5>
<P>The <A HREF = "fix_ave_atom.html">fix ave/atom</A> command performs time-averaging
of per-atom vectors. The per-atom quantities can be atom attributes
such as position, velocity, force. They can also be per-atom
quantities calculated by a <A HREF = "compute.html">compute</A>, by a
<A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>. The
time-averaged per-atom output of this fix can be used as input to
other output commands.
</P>
<P>The <A HREF = "fix_store_state.html">fix store/state</A> command can archive one or
more per-atom attributes at a particular time, so that the old values
can be used in a future calculation or output. The list of atom
attributes is the same as for the <A HREF = "dump.html">dump custom</A> command,
including per-atom quantities calculated by a <A HREF = "compute.html">compute</A>,
by a <A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>.
The output of this fix can be used as input to other output commands.
</P>
<H5><A NAME = "compute"></A>Computes that generate values to output
</H5>
<P>Every <A HREF = "compute.html">compute</A> in LAMMPS produces either global or
per-atom or local values. The values can be scalars or vectors or
arrays of data. These values can be output using the other commands
described in this section. The doc page for each compute command
describes what it produces. Computes that produce per-atom or local
values have the word "atom" or "local" in their style name. Computes
without the word "atom" or "local" produce global values.
</P>
<H5><A NAME = "fix"></A>Fixes that generate values to output
</H5>
<P>Some <A HREF = "fix.html">fixes</A> in LAMMPS produces either global or per-atom or
local values which can be accessed by other commands. The values can
be scalars or vectors or arrays of data. These values can be output
using the other commands described in this section. The doc page for
each fix command tells whether it produces any output quantities and
describes them.
</P>
<H5><A NAME = "variable"></A>Variables that generate values to output
</H5>
<P>Every <A HREF = "variable.html">variables</A> defined in an input script generates
either a global scalar value or a per-atom vector (only atom-style
variables) when it is accessed. The formulas used to define equal-
and atom-style variables can contain references to the thermodynamic
keywords and to global and per-atom data generated by computes, fixes,
and other variables. The values generated by variables can be output
using the other commands described in this section.
</P>
<H5><A NAME = "table"></A>Summary table of output options and data flow between commands
</H5>
<P>This table summarizes the various commands that can be used for
generating output from LAMMPS. Each command produces output data of
some kind and/or writes data to a file. Most of the commands can take
data from other commands as input. Thus you can link many of these
commands together in pipeline form, where data produced by one command
is used as input to another command and eventually written to the
screen or to a file. Note that to hook two commands together the
output and input data types must match, e.g. global/per-atom/local
data and scalar/vector/array data.
</P>
<P>Also note that, as described above, when a command takes a scalar as
input, that could be an element of a vector or array. Likewise a
vector input could be a column of an array.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >Command</TD><TD > Input</TD><TD > Output</TD><TD ></TD></TR>
<TR><TD ><A HREF = "thermo_style.html">thermo_style custom</A></TD><TD > global scalars</TD><TD > screen, log file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "dump.html">dump custom</A></TD><TD > per-atom vectors</TD><TD > dump file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "dump.html">dump local</A></TD><TD > local vectors</TD><TD > dump file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_print.html">fix print</A></TD><TD > global scalar from variable</TD><TD > screen, file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "print.html">print</A></TD><TD > global scalar from variable</TD><TD > screen</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute.html">computes</A></TD><TD > N/A</TD><TD > global/per-atom/local scalar/vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix.html">fixes</A></TD><TD > N/A</TD><TD > global/per-atom/local scalar/vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "variable.html">variables</A></TD><TD > global scalars, per-atom vectors</TD><TD > global scalar, per-atom vector</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute_reduce.html">compute reduce</A></TD><TD > per-atom/local vectors</TD><TD > global scalar/vector</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute_slice.html">compute slice</A></TD><TD > global vectors/arrays</TD><TD > global vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute_property_atom.html">compute property/atom</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute_property_local.html">compute property/local</A></TD><TD > local vectors</TD><TD > local vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "compute_atom_molecule.html">compute atom/molecule</A></TD><TD > per-atom vectors</TD><TD > global vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_ave_atom.html">fix ave/atom</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_ave_time.html">fix ave/time</A></TD><TD > global scalars/vectors</TD><TD > global scalar/vector/array, file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_ave_spatial.html">fix ave/spatial</A></TD><TD > per-atom vectors</TD><TD > global array, file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_ave_histo.html">fix ave/histo</A></TD><TD > global/per-atom/local scalars and vectors</TD><TD > global array, file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_ave_correlate.html">fix ave/correlate</A></TD><TD > global scalars</TD><TD > global array, file</TD><TD ></TD></TR>
<TR><TD ><A HREF = "fix_store_state.html">fix store/state</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
<TR><TD >
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "howto_16"></A><H4>6.16 Thermostatting, barostatting, and computing temperature
</H4>
<P>Thermostatting means controlling the temperature of particles in an MD
simulation. Barostatting means controlling the pressure. Since the
pressure includes a kinetic component due to particle velocities, both
these operations require calculation of the temperature. Typically a
target temperature (T) and/or pressure (P) is specified by the user,
and the thermostat or barostat attempts to equilibrate the system to
the requested T and/or P.
</P>
<P>Temperature is computed as kinetic energy divided by some number of
degrees of freedom (and the Boltzmann constant). Since kinetic energy
is a function of particle velocity, there is often a need to
distinguish between a particle's advection velocity (due to some
aggregate motiion of particles) and its thermal velocity. The sum of
the two is the particle's total velocity, but the latter is often what
is wanted to compute a temperature.
</P>
<P>LAMMPS has several options for computing temperatures, any of which
can be used in thermostatting and barostatting. These <A HREF = "compute.html">compute
commands</A> calculate temperature, and the <A HREF = "compute_pressure.html">compute
pressure</A> command calculates pressure.
</P>
<UL><LI><A HREF = "compute_temp.html">compute temp</A>
<LI><A HREF = "compute_temp_sphere.html">compute temp/sphere</A>
<LI><A HREF = "compute_temp_asphere.html">compute temp/asphere</A>
<LI><A HREF = "compute_temp_com.html">compute temp/com</A>
<LI><A HREF = "compute_temp_deform.html">compute temp/deform</A>
<LI><A HREF = "compute_temp_partial.html">compute temp/partial</A>
<LI><A HREF = "compute_temp_profile.html">compute temp/profile</A>
<LI><A HREF = "compute_temp_ramp.html">compute temp/ramp</A>
<LI><A HREF = "compute_temp_region.html">compute temp/region</A>
</UL>
<P>All but the first 3 calculate velocity biases (i.e. advection
velocities) that are removed when computing the thermal temperature.
<A HREF = "compute_temp_sphere.html">Compute temp/sphere</A> and <A HREF = "compute_temp_asphere.html">compute
temp/asphere</A> compute kinetic energy for
extended particles that includes rotational degrees of freedom. They
both allow, as an extra argument, which is another temperature compute
that subtracts a velocity bias. This allows the translational
velocity of extended spherical or aspherical particles to be adjusted
in prescribed ways.
</P>
<P>Thermostatting in LAMMPS is performed by <A HREF = "fix.html">fixes</A>, or in one
case by a pair style. Four thermostatting fixes are currently
available: Nose-Hoover (nvt), Berendsen, Langevin, and direct
rescaling (temp/rescale). Dissipative particle dynamics (DPD)
thermostatting can be invoked via the <I>dpd/tstat</I> pair style:
</P>
<UL><LI><A HREF = "fix_nh.html">fix nvt</A>
<LI><A HREF = "fix_nvt_sphere.html">fix nvt/sphere</A>
<LI><A HREF = "fix_nvt_asphere.html">fix nvt/asphere</A>
<LI><A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A>
<LI><A HREF = "fix_temp_berendsen.html">fix temp/berendsen</A>
<LI><A HREF = "fix_langevin.html">fix langevin</A>
<LI><A HREF = "fix_temp_rescale.html">fix temp/rescale</A>
<LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A>
</UL>
<P><A HREF = "fix_nh.html">Fix nvt</A> only thermostats the translational velocity of
particles. <A HREF = "fix_nvt_sllod.html">Fix nvt/sllod</A> also does this, except
that it subtracts out a velocity bias due to a deforming box and
integrates the SLLOD equations of motion. See the <A HREF = "#howto_13">NEMD
simulations</A> section of this page for further details. <A HREF = "fix_nvt_sphere.html">Fix
nvt/sphere</A> and <A HREF = "fix_nvt_asphere.html">fix
nvt/asphere</A> thermostat not only translation
velocities but also rotational velocities for spherical and aspherical
particles.
</P>
<P>DPD thermostatting alters pairwise interactions in a manner analagous
to the per-particle thermostatting of <A HREF = "fix_langevin.html">fix
langevin</A>.
</P>
<P>Any of the thermostatting fixes can use temperature computes that
remove bias for two purposes: (a) computing the current temperature to
compare to the requested target temperature, and (b) adjusting only
the thermal temperature component of the particle's velocities. See
the doc pages for the individual fixes and for the
<A HREF = "fix_modify.html">fix_modify</A> command for instructions on how to assign
a temperature compute to a thermostatting fix. For example, you can
apply a thermostat to only the x and z components of velocity by using
it in conjunction with <A HREF = "compute_temp_partial.html">compute
temp/partial</A>.
</P>
<P>IMPORTANT NOTE: Only the nvt fixes perform time integration, meaning
they update the velocities and positions of particles due to forces
and velocities respectively. The other thermostat fixes only adjust
velocities; they do NOT perform time integration updates. Thus they
should be used in conjunction with a constant NVE integration fix such
as these:
</P>
<UL><LI><A HREF = "fix_nve.html">fix nve</A>
<LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
<LI><A HREF = "fix_nve_asphere.html">fix nve/asphere</A>
</UL>
<P>Barostatting in LAMMPS is also performed by <A HREF = "fix.html">fixes</A>. Two
barosttating methods are currently available: Nose-Hoover (npt and
nph) and Berendsen:
</P>
<UL><LI><A HREF = "fix_nh.html">fix npt</A>
<LI><A HREF = "fix_npt_sphere.html">fix npt/sphere</A>
<LI><A HREF = "fix_npt_asphere.html">fix npt/asphere</A>
<LI><A HREF = "fix_nh.html">fix nph</A>
<LI><A HREF = "fix_press_berendsen.html">fix press/berendsen</A>
</UL>
<P>The <A HREF = "fix_nh.html">fix npt</A> commands include a Nose-Hoover thermostat
and barostat. <A HREF = "fix_nh.html">Fix nph</A> is just a Nose/Hoover barostat;
it does no thermostatting. Both <A HREF = "fix_nh.html">fix nph</A> and <A HREF = "fix_press_berendsen.html">fix
press/bernendsen</A> can be used in conjunction
with any of the thermostatting fixes.
</P>
<P>As with the thermostats, <A HREF = "fix_nh.html">fix npt</A> and <A HREF = "fix_nh.html">fix
nph</A> only use translational motion of the particles in
computing T and P and performing thermo/barostatting. <A HREF = "fix_npt_sphere.html">Fix
npt/sphere</A> and <A HREF = "fix_npt_asphere.html">fix
npt/asphere</A> thermo/barostat using not only
translation velocities but also rotational velocities for spherical
and aspherical particles.
</P>
<P>All of the barostatting fixes use the <A HREF = "compute_pressure.html">compute
pressure</A> compute to calculate a current
pressure. By default, this compute is created with a simple <A HREF = "compute_temp.html">compute
temp</A> (see the last argument of the <A HREF = "compute_pressure.html">compute
pressure</A> command), which is used to calculated
the kinetic componenet of the pressure. The barostatting fixes can
also use temperature computes that remove bias for the purpose of
computing the kinetic componenet which contributes to the current
pressure. See the doc pages for the individual fixes and for the
<A HREF = "fix_modify.html">fix_modify</A> command for instructions on how to assign
a temperature or pressure compute to a barostatting fix.
</P>
<P>IMPORTANT NOTE: As with the thermostats, the Nose/Hoover methods (<A HREF = "fix_nh.html">fix
npt</A> and <A HREF = "fix_nh.html">fix nph</A>) perform time
integration. <A HREF = "fix_press_berendsen.html">Fix press/berendsen</A> does NOT,
so it should be used with one of the constant NVE fixes or with one of
the NVT fixes.
</P>
<P>Finally, thermodynamic output, which can be setup via the
<A HREF = "thermo_style.html">thermo_style</A> command, often includes temperature
and pressure values. As explained on the doc page for the
<A HREF = "thermo_style.html">thermo_style</A> command, the default T and P are
setup by the thermo command itself. They are NOT the ones associated
with any thermostatting or barostatting fix you have defined or with
any compute that calculates a temperature or pressure. Thus if you
want to view these values of T and P, you need to specify them
explicitly via a <A HREF = "thermo_style.html">thermo_style custom</A> command. Or
you can use the <A HREF = "thermo_modify.html">thermo_modify</A> command to
re-define what temperature or pressure compute is used for default
thermodynamic output.
</P>
<HR>
<A NAME = "howto_17"></A><H4>6.17 Walls
</H4>
<P>Walls in an MD simulation are typically used to bound particle motion,
i.e. to serve as a boundary condition.
</P>
<P>Walls in LAMMPS can be of rough (made of particles) or idealized
surfaces. Ideal walls can be smooth, generating forces only in the
normal direction, or frictional, generating forces also in the
tangential direction.
</P>
<P>Rough walls, built of particles, can be created in various ways. The
particles themselves can be generated like any other particle, via the
<A HREF = "lattice.html">lattice</A> and <A HREF = "create_atoms.html">create_atoms</A> commands,
or read in via the <A HREF = "read_data.html">read_data</A> command.
</P>
<P>Their motion can be constrained by many different commands, so that
they do not move at all, move together as a group at constant velocity
or in response to a net force acting on them, move in a prescribed
fashion (e.g. rotate around a point), etc. Note that if a time
integration fix like <A HREF = "fix_nve.html">fix nve</A> or <A HREF = "fix_nh.html">fix nvt</A>
is not used with the group that contains wall particles, their
positions and velocities will not be updated.
</P>
<UL><LI><A HREF = "fix_aveforce.html">fix aveforce</A> - set force on particles to average value, so they move together
<LI><A HREF = "fix_setforce.html">fix setforce</A> - set force on particles to a value, e.g. 0.0
<LI><A HREF = "fix_freeze.html">fix freeze</A> - freeze particles for use as granular walls
<LI><A HREF = "fix_nve_noforce.html">fix nve/noforce</A> - advect particles by their velocity, but without force
<LI><A HREF = "fix_move.html">fix move</A> - prescribe motion of particles by a linear velocity, oscillation, rotation, variable
</UL>
<P>The <A HREF = "fix_move.html">fix move</A> command offers the most generality, since
the motion of individual particles can be specified with
<A HREF = "variable.html">variable</A> formula which depends on time and/or the
particle position.
</P>
<P>For rough walls, it may be useful to turn off pairwise interactions
between wall particles via the <A HREF = "neigh_modify.html">neigh_modify
exclude</A> command.
</P>
<P>Rough walls can also be created by specifying frozen particles that do
not move and do not interact with mobile particles, and then tethering
other particles to the fixed particles, via a <A HREF = "bond_style.html">bond</A>.
The bonded particles do interact with other mobile particles.
</P>
<P>Idealized walls can be specified via several fix commands. <A HREF = "fix_wall_gran.html">Fix
wall/gran</A> creates frictional walls for use with
granular particles; all the other commands create smooth walls.
</P>
<UL><LI><A HREF = "fix_wall_reflect.html">fix wall/reflect</A> - reflective flat walls
<LI><A HREF = "fix_wall.html">fix wall/lj93</A> - flat walls, with Lennard-Jones 9/3 potential
<LI><A HREF = "fix_wall.html">fix wall/lj126</A> - flat walls, with Lennard-Jones 12/6 potential
<LI><A HREF = "fix_wall.html">fix wall/colloid</A> - flat walls, with <A HREF = "pair_colloid.html">pair_style colloid</A> potential
<LI><A HREF = "fix_wall.html">fix wall/harmonic</A> - flat walls, with repulsive harmonic spring potential
<LI><A HREF = "fix_wall_region.html">fix wall/region</A> - use region surface as wall
<LI><A HREF = "fix_wall_gran.html">fix wall/gran</A> - flat or curved walls with <A HREF = "pair_gran.html">pair_style granular</A> potential
</UL>
<P>The <I>lj93</I>, <I>lj126</I>, <I>colloid</I>, and <I>harmonic</I> styles all allow the
flat walls to move with a constant velocity, or oscillate in time.
The <A HREF = "fix_wall_region.html">fix wall/region</A> command offers the most
generality, since the region surface is treated as a wall, and the
geometry of the region can be a simple primitive volume (e.g. a
sphere, or cube, or plane), or a complex volume made from the union
and intersection of primitive volumes. <A HREF = "region.html">Regions</A> can also
specify a volume "interior" or "exterior" to the specified primitive
shape or <I>union</I> or <I>intersection</I>. <A HREF = "region.html">Regions</A> can also be
"dynamic" meaning they move with constant velocity, oscillate, or
rotate.
</P>
<P>The only frictional idealized walls currently in LAMMPS are flat or
curved surfaces specified by the <A HREF = "fix_wall_gran.html">fix wall/gran</A>
command. At some point we plan to allow regoin surfaces to be used as
frictional walls, as well as triangulated surfaces.
</P>
<HR>
<A NAME = "howto_18"></A><H4>6.18 Elastic constants
</H4>
<P>Elastic constants characterize the stiffness of a material. The formal
definition is provided by the linear relation that holds between the
stress and strain tensors in the limit of infinitesimal deformation.
In tensor notation, this is expressed as s_ij = C_ijkl * e_kl, where
the repeated indices imply summation. s_ij are the elements of the
symmetric stress tensor. e_kl are the elements of the symmetric strain
tensor. C_ijkl are the elements of the fourth rank tensor of elastic
constants. In three dimensions, this tensor has 3^4=81 elements. Using
Voigt notation, the tensor can be written as a 6x6 matrix, where C_ij
is now the derivative of s_i w.r.t. e_j. Because s_i is itself a
derivative w.r.t. e_i, it follows that C_ij is also symmetric, with at
most 7*6/2 = 21 distinct elements.
</P>
<P>At zero temperature, it is easy to estimate these derivatives by
deforming the cell in one of the six directions using the command
<A HREF = "displace_box.html">displace_box</A> and measuring the change in the
stress tensor. A general-purpose script that does this is given in the
examples/elastic directory described in <A HREF = "Section_example.html">this
section</A>.
</P>
<P>Calculating elastic constants at finite temperature is more
challenging, because it is necessary to run a simulation that perfoms
time averages of differential properties. One way to do this is to
measure the change in average stress tensor in an NVT simulations when
the cell volume undergoes a finite deformation. In order to balance
the systematic and statistical errors in this method, the magnitude of
the deformation must be chosen judiciously, and care must be taken to
fully equilibrate the deformed cell before sampling the stress
tensor. Another approach is to sample the triclinic cell fluctuations
that occur in an NPT simulation. This method can also be slow to
converge and requires careful post-processing <A HREF = "#Shinoda">(Shinoda)</A>
</P>
<HR>
<A NAME = "howto_19"></A><H4>6.19 Library interface to LAMMPS
</H4>
-<P>As described in <A HREF = "Section_start.html#start_4">this section</A>, LAMMPS can
-be built as a library, so that it can be called by another code, used
-in a <A HREF = "Section_howto.html#howto_10">coupled manner</A> with other codes, or
-driven through a <A HREF = "Section_python.html">Python interface</A>.
+<P>As described in <A HREF = "Section_start.html#start_4">Section_start 4</A>, LAMMPS
+can be built as a library, so that it can be called by another code,
+used in a <A HREF = "Section_howto.html#howto_10">coupled manner</A> with other
+codes, or driven through a <A HREF = "Section_python.html">Python interface</A>.
</P>
<P>All of these methodologies use a C-style interface to LAMMPS that is
provided in the files src/library.cpp and src/library.h. The
functions therein have a C-style argument list, but contain C++ code
you could write yourself in a C++ application that was invoking LAMMPS
directly. The C++ code in the functions illustrates how to invoke
internal LAMMPS operations. Note that LAMMPS classes are defined
within a LAMMPS namespace (LAMMPS_NS) if you use them from another C++
application.
</P>
<P>Library.cpp contains these 4 functions:
</P>
<PRE>void lammps_open(int, char **, MPI_Comm, void **);
void lammps_close(void *);
void lammps_file(void *, char *);
char *lammps_command(void *, char *);
</PRE>
<P>The lammps_open() function is used to initialize LAMMPS, passing in a
list of strings as if they were <A HREF = "Section_start.html#start_6">command-line
arguments</A> when LAMMPS is run in
stand-alone mode from the command line, and a MPI communicator for
LAMMPS to run under. It returns a ptr to the LAMMPS object that is
created, and which is used in subsequent library calls. The
lammps_open() function can be called multiple times, to create
multiple instances of LAMMPS.
</P>
<P>LAMMPS will run on the set of processors in the communicator. This
means the calling code can run LAMMPS on all or a subset of
processors. For example, a wrapper script might decide to alternate
between LAMMPS and another code, allowing them both to run on all the
processors. Or it might allocate half the processors to LAMMPS and
half to the other code and run both codes simultaneously before
syncing them up periodically. Or it might instantiate multiple
instances of LAMMPS to perform different calculations.
</P>
<P>The lammps_close() function is used to shut down an instance of LAMMPS
and free all its memory.
</P>
<P>The lammps_file() and lammps_command() functions are used to pass a
file or string to LAMMPS as if it were an input script or single
command in an input script. Thus the calling code can read or
generate a series of LAMMPS commands one line at a time and pass it
thru the library interface to setup a problem and then run it,
interleaving the lammps_command() calls with other calls to extract
information from LAMMPS, perform its own operations, or call another
code's library.
</P>
<P>Other useful functions are also included in library.cpp. For example:
</P>
<PRE>void *lammps_extract_global(void *, char *)
void *lammps_extract_atom(void *, char *)
void *lammps_extract_compute(void *, char *, int, int)
void *lammps_extract_fix(void *, char *, int, int, int, int)
void *lammps_extract_variable(void *, char *, char *)
int lammps_get_natoms(void *)
void lammps_get_coords(void *, double *)
void lammps_put_coords(void *, double *)
</PRE>
<P>These can extract various global or per-atom quantities from LAMMPS as
well as values calculated by a compute, fix, or variable. The "get"
and "put" operations can retrieve and reset atom coordinates.
See the library.cpp file and its associated header file library.h for
details.
</P>
<P>The key idea of the library interface is that you can write any
functions you wish to define how your code talks to LAMMPS and add
them to src/library.cpp and src/library.h, as well as to the <A HREF = "Section_python.html">Python
interface</A>. The routines you add can access
or change any LAMMPS data you wish. The couple and python directories
have example C++ and C and Python codes which show how a driver code
can link to LAMMPS as a library, run LAMMPS on a subset of processors,
grab data from LAMMPS, change it, and put it back into LAMMPS.
</P>
<HR>
<A NAME = "howto_20"></A><H4>6.20 Calculating thermal conductivity
</H4>
<P>The thermal conductivity kappa of a material can be measured in at
least 3 ways using various options in LAMMPS. (See <A HREF = "Section_howto.html#howto_21">this
section</A> of the manual for an analogous
discussion for viscosity). The thermal conducitivity tensor kappa is
a measure of the propensity of a material to transmit heat energy in a
diffusive manner as given by Fourier's law
</P>
<P>J = -kappa grad(T)
</P>
<P>where J is the heat flux in units of energy per area per time and
grad(T) is the spatial gradient of temperature. The thermal
conductivity thus has units of energy per distance per time per degree
K and is often approximated as an isotropic quantity, i.e. as a
scalar.
</P>
<P>The first method is to setup two thermostatted regions at opposite
ends of a simulation box, or one in the middle and one at the end of a
periodic box. By holding the two regions at different temperatures
with a <A HREF = "Section_howto.html#howto_13">thermostatting fix</A>, the energy added
to the hot region should equal the energy subtracted from the cold
region and be proportional to the heat flux moving between the
regions. See the paper by <A HREF = "#Ikeshoji">Ikeshoji and Hafskjold</A> for
details of this idea. Note that thermostatting fixes such as <A HREF = "fix_nh.html">fix
nvt</A>, <A HREF = "fix_langevin.html">fix langevin</A>, and <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A> store the cumulative energy they
add/subtract. Alternatively, the <A HREF = "fix_heat.html">fix heat</A> command can
used in place of thermostats on each of two regions, and the resulting
temperatures of the two regions monitored with the "compute
temp/region" command or the temperature profile of the intermediate
region monitored with the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> and
<A HREF = "compute_ke_atom.html">compute ke/atom</A> commands.
</P>
<P>The second method is to perform a reverse non-equilibrium MD
simulation using the <A HREF = "fix_thermal_conductivity.html">fix
thermal/conductivity</A> command which
implements the rNEMD algorithm of Muller-Plathe. Kinetic energy is
swapped between atoms in two different layers of the simulation box.
This induces a temperature gradient between the two layers which can
be monitored with the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> and
<A HREF = "compute_ke_atom.html">compute ke/atom</A> commands. The fix tallies the
cumulative energy transfer that it performs. See the <A HREF = "fix_thermal_conductivity.html">fix
thermal/conductivity</A> command for
details.
</P>
<P>The third method is based on the Green-Kubo (GK) formula which relates
the ensemble average of the auto-correlation of the heat flux to
kappa. The heat flux can be calculated from the fluctuations of
per-atom potential and kinetic energies and per-atom stress tensor in
a steady-state equilibrated simulation. This is in contrast to the
two preceding non-equilibrium methods, where energy flows continuously
between hot and cold regions of the simulation box.
</P>
<P>The <A HREF = "compute_heat_flux.html">compute heat/flux</A> command can calculate
the needed heat flux and describes how to implement the Green_Kubo
formalism using additional LAMMPS commands, such as the <A HREF = "fix_ave_correlate.html">fix
ave/correlate</A> command to calculate the needed
auto-correlation. See the doc page for the <A HREF = "compute_heat_flux.html">compute
heat/flux</A> command for an example input script
that calculates the thermal conductivity of solid Ar via the GK
formalism.
</P>
<HR>
<A NAME = "howto_21"></A><H4>6.21 Calculating viscosity
</H4>
<P>The shear viscosity eta of a fluid can be measured in at least 3 ways
using various options in LAMMPS. (See <A HREF = "Section_howto.html#howto_20">this
section</A> of the manual for an analogous
discussion for thermal conductivity). Eta is a measure of the
propensity of a fluid to transmit momentum in a direction
perpendicular to the direction of velocity or momentum flow.
Alternatively it is the resistance the fluid has to being sheared. It
is given by
</P>
<P>J = -eta grad(Vstream)
</P>
<P>where J is the momentum flux in units of momentum per area per time.
and grad(Vstream) is the spatial gradient of the velocity of the fluid
moving in another direction, normal to the area through which the
momentum flows. Viscosity thus has units of pressure-time.
</P>
<P>The first method is to perform a non-equlibrium MD (NEMD) simulation
by shearing the simulation box via the <A HREF = "fix_deform.html">fix deform</A>
command, and using the <A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> command to
thermostat the fluid via the SLLOD equations of motion. The velocity
profile setup in the fluid by this procedure can be monitored by the
<A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command, which determines
grad(Vstream) in the equation above. E.g. the derivative in the
y-direction of the Vx component of fluid motion or grad(Vstream) =
dVx/dy. In this case, the Pxy off-diagonal component of the pressure
or stress tensor, as calculated by the <A HREF = "compute_pressure.html">compute
pressure</A> command, can also be monitored, which
is the J term in the equation above. See <A HREF = "Section_howto.html#howto_13">this
section</A> of the manual for details on NEMD
simulations.
</P>
<P>The second method is to perform a reverse non-equilibrium MD
simulation using the <A HREF = "fix_viscosity.html">fix viscosity</A> command which
implements the rNEMD algorithm of Muller-Plathe. Momentum in one
dimension is swapped between atoms in two different layers of the
simulation box in a different dimension. This induces a velocity
gradient which can be monitored with the <A HREF = "fix_ave_spatial.html">fix
ave/spatial</A> command. The fix tallies the
cummulative momentum transfer that it performs. See the <A HREF = "fix_viscosity.html">fix
viscosity</A> command for details.
</P>
<P>The third method is based on the Green-Kubo (GK) formula which relates
the ensemble average of the auto-correlation of the stress/pressure
tensor to eta. This can be done in a steady-state equilibrated
simulation which is in contrast to the two preceding non-equilibrium
methods, where momentum flows continuously through the simulation box.
</P>
<P>Here is an example input script that calculates the viscosity of
liquid Ar via the GK formalism:
</P>
<PRE># Sample LAMMPS input script for viscosity of liquid Ar
</PRE>
<PRE>units real
variable T equal 86.4956
variable V equal vol
variable dt equal 4.0
variable p equal 400 # correlation length
variable s equal 5 # sample interval
variable d equal $p*$s # dump interval
</PRE>
<PRE># convert from LAMMPS real units to SI
</PRE>
<PRE>variable kB equal 1.3806504e-23 # [J/K/</B> Boltzmann
variable atm2Pa equal 101325.0
variable A2m equal 1.0e-10
variable fs2s equal 1.0e-15
variable convert equal ${atm2Pa}*${atm2Pa}*${fs2s}*${A2m}*${A2m}*${A2m}
</PRE>
<PRE># setup problem
</PRE>
<PRE>dimension 3
boundary p p p
lattice fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
region box block 0 4 0 4 0 4
create_box 1 box
create_atoms 1 box
mass 1 39.948
pair_style lj/cut 13.0
pair_coeff * * 0.2381 3.405
timestep ${dt}
thermo $d
</PRE>
<PRE># equilibration and thermalization
</PRE>
<PRE>velocity all create $T 102486 mom yes rot yes dist gaussian
fix NVT all nvt temp $T $T 10 drag 0.2
run 8000
</PRE>
<PRE># viscosity calculation, switch to NVE if desired
</PRE>
<PRE>#unfix NVT
#fix NVE all nve
</PRE>
<PRE>reset_timestep 0
variable pxy equal pxy
variable pxz equal pxz
variable pyz equal pyz
fix SS all ave/correlate $s $p $d &
v_pxy v_pxz v_pyz type auto file S0St.dat ave running
variable scale equal ${convert}/(${kB}*$T)*$V*$s*${dt}
variable v11 equal trap(f_SS[3/</B>)*${scale}
variable v22 equal trap(f_SS[4/</B>)*${scale}
variable v33 equal trap(f_SS[5/</B>)*${scale}
thermo_style custom step temp press v_pxy v_pxz v_pyz v_v11 v_v22 v_v33
run 100000
variable v equal (v_v11+v_v22+v_v33)/3.0
variable ndens equal count(all)/vol
print "average viscosity: $v [Pa.s/</B> @ $T K, ${ndens} /A^3"
</PRE>
<HR>
<HR>
<A NAME = "Berendsen"></A>
<P><B>(Berendsen)</B> Berendsen, Grigera, Straatsma, J Phys Chem, 91,
6269-6271 (1987).
</P>
<A NAME = "Cornell"></A>
<P><B>(Cornell)</B> Cornell, Cieplak, Bayly, Gould, Merz, Ferguson,
Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995).
</P>
<A NAME = "Horn"></A>
<P><B>(Horn)</B> Horn, Swope, Pitera, Madura, Dick, Hura, and Head-Gordon,
J Chem Phys, 120, 9665 (2004).
</P>
<A NAME = "Ikeshoji"></A>
<P><B>(Ikeshoji)</B> Ikeshoji and Hafskjold, Molecular Physics, 81, 251-261
(1994).
</P>
<A NAME = "MacKerell"></A>
<P><B>(MacKerell)</B> MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
</P>
<A NAME = "Mayo"></A>
<P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
</P>
<A NAME = "Jorgensen"></A>
<P><B>(Jorgensen)</B> Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem
Phys, 79, 926 (1983).
</P>
<A NAME = "Price"></A>
<P><B>(Price)</B> Price and Brooks, J Chem Phys, 121, 10096 (2004).
</P>
<A NAME = "Shinoda"></A>
<P><B>(Shinoda)</B> Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004).
</P>
</HTML>
diff --git a/doc/Section_howto.txt b/doc/Section_howto.txt
index 65131975f..50c24d8b8 100644
--- a/doc/Section_howto.txt
+++ b/doc/Section_howto.txt
@@ -1,1938 +1,1938 @@
"Previous Section"_Section_accelerate.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_example.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
6. How-to discussions :h3
-The following sections describe how to use various options within
-LAMMPS.
+This section describes how to perform common tasks using LAMMPS.
6.1 "Restarting a simulation"_#howto_1
6.2 "2d simulations"_#howto_2
6.3 "CHARMM, AMBER, and DREIDING force fields"_#howto_3
6.4 "Running multiple simulations from one input script"_#howto_4
6.5 "Multi-replica simulations"_#howto_5
6.6 "Granular models"_#howto_6
6.7 "TIP3P water model"_#howto_7
6.8 "TIP4P water model"_#howto_8
6.9 "SPC water model"_#howto_9
6.10 "Coupling LAMMPS to other codes"_#howto_10
6.11 "Visualizing LAMMPS snapshots"_#howto_11
6.12 "Triclinic (non-orthogonal) simulation boxes"_#howto_12
6.13 "NEMD simulations"_#howto_13
6.14 "Extended spherical and aspherical particles"_#howto_14
6.15 "Output from LAMMPS (thermo, dumps, computes, fixes, variables)"_#howto_15
6.16 "Thermostatting, barostatting and computing temperature"_#howto_16
6.17 "Walls"_#howto_17
6.18 "Elastic constants"_#howto_18
6.19 "Library interface to LAMMPS"_#howto_19
6.20 "Calculating thermal conductivity"_#howto_20
6.21 "Calculating viscosity"_#howto_21 :all(b)
The example input scripts included in the LAMMPS distribution and
-highlighted in "this section"_Section_example.html also show how to
+highlighted in "Section_example"_Section_example.html also show how to
setup and run various kinds of simulations.
+:line
:line
6.1 Restarting a simulation :link(howto_1),h4
There are 3 ways to continue a long LAMMPS simulation. Multiple
"run"_run.html commands can be used in the same input script. Each
run will continue from where the previous run left off. Or binary
restart files can be saved to disk using the "restart"_restart.html
command. At a later time, these binary files can be read via a
"read_restart"_read_restart.html command in a new script. Or they can
be converted to text data files and read by a
"read_data"_read_data.html command in a new script. "This
section"_Section_tools.html discusses the {restart2data} tool that is
used to perform the conversion.
Here we give examples of 2 scripts that read either a binary restart
file or a converted data file and then issue a new run command to
continue where the previous run left off. They illustrate what
settings must be made in the new script. Details are discussed in the
documentation for the "read_restart"_read_restart.html and
"read_data"_read_data.html commands.
Look at the {in.chain} input script provided in the {bench} directory
of the LAMMPS distribution to see the original script that these 2
scripts are based on. If that script had the line
restart 50 tmp.restart :pre
added to it, it would produce 2 binary restart files (tmp.restart.50
and tmp.restart.100) as it ran.
This script could be used to read the 1st restart file and re-run the
last 50 timesteps:
read_restart tmp.restart.50 :pre
neighbor 0.4 bin
neigh_modify every 1 delay 1 :pre
fix 1 all nve
fix 2 all langevin 1.0 1.0 10.0 904297 :pre
timestep 0.012 :pre
run 50 :pre
Note that the following commands do not need to be repeated because
their settings are included in the restart file: {units, atom_style,
special_bonds, pair_style, bond_style}. However these commands do
need to be used, since their settings are not in the restart file:
{neighbor, fix, timestep}.
If you actually use this script to perform a restarted run, you will
notice that the thermodynamic data match at step 50 (if you also put a
"thermo 50" command in the original script), but do not match at step
100. This is because the "fix langevin"_fix_langevin.html command
uses random numbers in a way that does not allow for perfect restarts.
As an alternate approach, the restart file could be converted to a data
file using this tool:
restart2data tmp.restart.50 tmp.restart.data :pre
Then, this script could be used to re-run the last 50 steps:
units lj
atom_style bond
pair_style lj/cut 1.12
pair_modify shift yes
bond_style fene
special_bonds 0.0 1.0 1.0 :pre
read_data tmp.restart.data :pre
neighbor 0.4 bin
neigh_modify every 1 delay 1 :pre
fix 1 all nve
fix 2 all langevin 1.0 1.0 10.0 904297 :pre
timestep 0.012 :pre
reset_timestep 50
run 50 :pre
Note that nearly all the settings specified in the original {in.chain}
script must be repeated, except the {pair_coeff} and {bond_coeff}
commands since the new data file lists the force field coefficients.
Also, the "reset_timestep"_reset_timestep.html command is used to tell
LAMMPS the current timestep. This value is stored in restart files,
but not in data files.
:line
6.2 2d simulations :link(howto_2),h4
Use the "dimension"_dimension.html command to specify a 2d simulation.
Make the simulation box periodic in z via the "boundary"_boundary.html
command. This is the default.
If using the "create box"_create_box.html command to define a
simulation box, set the z dimensions narrow, but finite, so that the
create_atoms command will tile the 3d simulation box with a single z
plane of atoms - e.g.
"create box"_create_box.html 1 -10 10 -10 10 -0.25 0.25 :pre
If using the "read data"_read_data.html command to read in a file of
atom coordinates, set the "zlo zhi" values to be finite but narrow,
similar to the create_box command settings just described. For each
atom in the file, assign a z coordinate so it falls inside the
z-boundaries of the box - e.g. 0.0.
Use the "fix enforce2d"_fix_enforce2d.html command as the last
defined fix to insure that the z-components of velocities and forces
are zeroed out every timestep. The reason to make it the last fix is
so that any forces induced by other fixes will be zeroed out.
Many of the example input scripts included in the LAMMPS distribution
are for 2d models.
IMPORTANT NOTE: Some models in LAMMPS treat particles as extended
spheres, as opposed to point particles. In 2d, the particles will
still be spheres, not disks, meaning their moment of inertia will be
the same as in 3d.
:line
6.3 CHARMM, AMBER, and DREIDING force fields :link(howto_3),h4
A force field has 2 parts: the formulas that define it and the
coefficients used for a particular system. Here we only discuss
formulas implemented in LAMMPS that correspond to formulas commonly
used in the CHARMM, AMBER, and DREIDING force fields. Setting
coefficients is done in the input data file via the
"read_data"_read_data.html command or in the input script with
commands like "pair_coeff"_pair_coeff.html or
-"bond_coeff"_bond_coeff.html. See "this section"_Section_tools.html
+"bond_coeff"_bond_coeff.html. See "Section_tools"_Section_tools.html
for additional tools that can use CHARMM or AMBER to assign force
field coefficients and convert their output into LAMMPS input.
See "(MacKerell)"_#MacKerell for a description of the CHARMM force
field. See "(Cornell)"_#Cornell for a description of the AMBER force
field.
:link(charmm,http://www.scripps.edu/brooks)
:link(amber,http://amber.scripps.edu)
These style choices compute force field formulas that are consistent
with common options in CHARMM or AMBER. See each command's
documentation for the formula it computes.
"bond_style"_bond_harmonic.html harmonic
"angle_style"_angle_charmm.html charmm
"dihedral_style"_dihedral_charmm.html charmm
"pair_style"_pair_charmm.html lj/charmm/coul/charmm
"pair_style"_pair_charmm.html lj/charmm/coul/charmm/implicit
"pair_style"_pair_charmm.html lj/charmm/coul/long :ul
"special_bonds"_special_bonds.html charmm
"special_bonds"_special_bonds.html amber :ul
DREIDING is a generic force field developed by the "Goddard
group"_http://www.wag.caltech.edu at Caltech and is useful for
predicting structures and dynamics of organic, biological and
main-group inorganic molecules. The philosophy in DREIDING is to use
general force constants and geometry parameters based on simple
hybridization considerations, rather than individual force constants
and geometric parameters that depend on the particular combinations of
atoms involved in the bond, angle, or torsion terms. DREIDING has an
"explicit hydrogen bond term"_pair_hbond_dreiding.html to describe
interactions involving a hydrogen atom on very electronegative atoms
(N, O, F).
See "(Mayo)"_#Mayo for a description of the DREIDING force field
These style choices compute force field formulas that are consistent
with the DREIDING force field. See each command's
documentation for the formula it computes.
"bond_style"_bond_harmonic.html harmonic
"bond_style"_bond_morse.html morse :ul
"angle_style"_angle_harmonic.html harmonic
"angle_style"_angle_cosine.html cosine
"angle_style"_angle_cosine_periodic.html cosine/periodic :ul
"dihedral_style"_dihedral_charmm.html charmm
"improper_style"_improper_umbrella.html umbrella :ul
"pair_style"_pair_buck.html buck
"pair_style"_pair_buck.html buck/coul/cut
"pair_style"_pair_buck.html buck/coul/long
"pair_style"_pair_lj.html lj/cut
"pair_style"_pair_lj.html lj/cut/coul/cut
"pair_style"_pair_lj.html lj/cut/coul/long :ul
"pair_style"_pair_hbond_dreiding.html hbond/dreiding/lj
"pair_style"_pair_hbond_dreiding.html hbond/dreiding/morse :ul
"special_bonds"_special_bonds.html dreiding :ul
:line
6.4 Running multiple simulations from one input script :link(howto_4),h4
This can be done in several ways. See the documentation for
individual commands for more details on how these examples work.
If "multiple simulations" means continue a previous simulation for
more timesteps, then you simply use the "run"_run.html command
multiple times. For example, this script
units lj
atom_style atomic
read_data data.lj
run 10000
run 10000
run 10000
run 10000
run 10000 :pre
would run 5 successive simulations of the same system for a total of
50,000 timesteps.
If you wish to run totally different simulations, one after the other,
the "clear"_clear.html command can be used in between them to
re-initialize LAMMPS. For example, this script
units lj
atom_style atomic
read_data data.lj
run 10000
clear
units lj
atom_style atomic
read_data data.lj.new
run 10000 :pre
would run 2 independent simulations, one after the other.
For large numbers of independent simulations, you can use
"variables"_variable.html and the "next"_next.html and
"jump"_jump.html commands to loop over the same input script
multiple times with different settings. For example, this
script, named in.polymer
variable d index run1 run2 run3 run4 run5 run6 run7 run8
shell cd $d
read_data data.polymer
run 10000
shell cd ..
clear
next d
jump in.polymer :pre
would run 8 simulations in different directories, using a data.polymer
file in each directory. The same concept could be used to run the
same system at 8 different temperatures, using a temperature variable
and storing the output in different log and dump files, for example
variable a loop 8
variable t index 0.8 0.85 0.9 0.95 1.0 1.05 1.1 1.15
log log.$a
read data.polymer
velocity all create $t 352839
fix 1 all nvt $t $t 100.0
dump 1 all atom 1000 dump.$a
run 100000
next t
next a
jump in.polymer :pre
All of the above examples work whether you are running on 1 or
multiple processors, but assumed you are running LAMMPS on a single
partition of processors. LAMMPS can be run on multiple partitions via
the "-partition" command-line switch as described in "this
section"_Section_start.html#start_6 of the manual.
In the last 2 examples, if LAMMPS were run on 3 partitions, the same
scripts could be used if the "index" and "loop" variables were
replaced with {universe}-style variables, as described in the
"variable"_variable.html command. Also, the "next t" and "next a"
commands would need to be replaced with a single "next a t" command.
With these modifications, the 8 simulations of each script would run
on the 3 partitions one after the other until all were finished.
Initially, 3 simulations would be started simultaneously, one on each
partition. When one finished, that partition would then start
the 4th simulation, and so forth, until all 8 were completed.
:line
6.5 Multi-replica simulations :link(howto_5),h4
Several commands in LAMMPS run mutli-replica simulations, meaning
that multiple instances (replicas) of your simulation are run
simultaneously, with small amounts of data exchanged between replicas
periodically.
These are the relevant commands:
"neb"_neb.html for nudged elastic band calculations
"prd"_prd.html for parallel replica dynamics
"tad"_tad.html for temperature accelerated dynamics
"temper"_temper.html for parallel tempering :ul
NEB is a method for finding transition states and barrier energies.
PRD and TAD are methods for performing accelerated dynamics to find
and perform infrequent events. Parallel tempering or replica exchange
runs different replicas at a series of temperature to facilitate
rare-event sampling.
These command can only be used if LAMMPS was built with the "replica"
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
In all these cases, you must run with one or more processors per
replica. The processors assigned to each replica are determined at
run-time by using the "-partition command-line
switch"_Section_start.html#start_6 to launch LAMMPS on multiple
partitions, which in this context are the same as replicas. E.g.
these commands:
mpirun -np 16 lmp_linux -partition 8x2 -in in.temper
mpirun -np 8 lmp_linux -partition 8x1 -in in.neb :pre
would each run 8 replicas, on either 16 or 8 processors. Note the use
of the "-in command-line switch"_Section_start.html#start_6 to specify
the input script which is required when running in multi-replica mode.
Also note that with MPI installed on a machine (e.g. your desktop),
you can run on more (virtual) processors than you have physical
processors. Thus the above commands could be run on a
single-processor (or few-processor) desktop so that you can run
a multi-replica simulation on more replicas than you have
physical processors.
:line
6.6 Granular models :link(howto_6),h4
Granular system are composed of spherical particles with a diameter,
as opposed to point particles. This means they have an angular
velocity and torque can be imparted to them to cause them to rotate.
To run a simulation of a granular model, you will want to use
the following commands:
"atom_style sphere"_atom_style.html
"fix nve/sphere"_fix_nve_sphere.html
"fix gravity"_fix_gravity.html :ul
This compute
"compute erotate/sphere"_compute_erotate_sphere.html :ul
calculates rotational kinetic energy which can be "output with
thermodynamic info"_Section_howto.html#howto_15.
Use one of these 3 pair potentials, which compute forces and torques
between interacting pairs of particles:
"pair_style"_pair_style.html gran/history
"pair_style"_pair_style.html gran/no_history
"pair_style"_pair_style.html gran/hertzian :ul
These commands implement fix options specific to granular systems:
"fix freeze"_fix_freeze.html
"fix pour"_fix_pour.html
"fix viscous"_fix_viscous.html
"fix wall/gran"_fix_wall_gran.html :ul
The fix style {freeze} zeroes both the force and torque of frozen
atoms, and should be used for granular system instead of the fix style
{setforce}.
For computational efficiency, you can eliminate needless pairwise
computations between frozen atoms by using this command:
"neigh_modify"_neigh_modify.html exclude :ul
:line
6.7 TIP3P water model :link(howto_7),h4
The TIP3P water model as implemented in CHARMM
"(MacKerell)"_#MacKerell specifies a 3-site rigid water molecule with
charges and Lennard-Jones parameters assigned to each of the 3 atoms.
In LAMMPS the "fix shake"_fix_shake.html command can be used to hold
the two O-H bonds and the H-O-H angle rigid. A bond style of
{harmonic} and an angle style of {harmonic} or {charmm} should also be
used.
These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid TIP3P-CHARMM model with a
cutoff. The K values can be used if a flexible TIP3P model (without
fix shake) is desired. If the LJ epsilon and sigma for HH and OH are
set to 0.0, it corresponds to the original 1983 TIP3P model
"(Jorgensen)"_#Jorgensen.
O mass = 15.9994
H mass = 1.008 :all(b),p
O charge = -0.834
H charge = 0.417 :all(b),p
LJ epsilon of OO = 0.1521
LJ sigma of OO = 3.1507
LJ epsilon of HH = 0.0460
LJ sigma of HH = 0.4000
LJ epsilon of OH = 0.0836
LJ sigma of OH = 1.7753 :all(b),p
K of OH bond = 450
r0 of OH bond = 0.9572 :all(b),p
K of HOH angle = 55
theta of HOH angle = 104.52 :all(b),p
These are the parameters to use for TIP3P with a long-range Coulombic
solver (Ewald or PPPM in LAMMPS), see "(Price)"_#Price for details:
O mass = 15.9994
H mass = 1.008 :all(b),p
O charge = -0.830
H charge = 0.415 :all(b),p
LJ epsilon of OO = 0.102
LJ sigma of OO = 3.188
LJ epsilon, sigma of OH, HH = 0.0 :all(b),p
K of OH bond = 450
r0 of OH bond = 0.9572 :all(b),p
K of HOH angle = 55
theta of HOH angle = 104.52 :all(b),p
Wikipedia also has a nice article on "water
models"_http://en.wikipedia.org/wiki/Water_model.
:line
6.8 TIP4P water model :link(howto_8),h4
The four-point TIP4P rigid water model extends the traditional
three-point TIP3P model by adding an additional site, usually
massless, where the charge associated with the oxygen atom is placed.
This site M is located at a fixed distance away from the oxygen along
the bisector of the HOH bond angle. A bond style of {harmonic} and an
angle style of {harmonic} or {charmm} should also be used.
Currently, only a four-point model for long-range Coulombics is
implemented via the LAMMPS "pair style
lj/cut/coul/long/tip4p"_pair_lj.html. A cutoff version may be added
the future. For both models, the bond lengths and bond angles should
be held fixed using the "fix shake"_fix_shake.html command.
These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid TIP4P model with a cutoff
"(Jorgensen)"_#Jorgensen. Note that the OM distance is specified in
the "pair_style"_pair_style.html command, not as part of the pair
coefficients.
O mass = 15.9994
H mass = 1.008 :all(b),p
O charge = -1.040
H charge = 0.520 :all(b),p
r0 of OH bond = 0.9572
theta of HOH angle = 104.52 :all(b),p
OM distance = 0.15 :all(b),p
LJ epsilon of O-O = 0.1550
LJ sigma of O-O = 3.1536
LJ epsilon, sigma of OH, HH = 0.0 :all(b),p
These are the parameters to use for TIP4P with a long-range Coulombic
solver (Ewald or PPPM in LAMMPS):
O mass = 15.9994
H mass = 1.008 :all(b),p
O charge = -1.0484
H charge = 0.5242 :all(b),p
r0 of OH bond = 0.9572
theta of HOH angle = 104.52 :all(b),p
OM distance = 0.1250 :all(b),p
LJ epsilon of O-O = 0.16275
LJ sigma of O-O = 3.16435
LJ epsilon, sigma of OH, HH = 0.0 :all(b),p
Wikipedia also has a nice article on "water
models"_http://en.wikipedia.org/wiki/Water_model.
:line
6.9 SPC water model :link(howto_9),h4
The SPC water model specifies a 3-site rigid water molecule with
charges and Lennard-Jones parameters assigned to each of the 3 atoms.
In LAMMPS the "fix shake"_fix_shake.html command can be used to hold
the two O-H bonds and the H-O-H angle rigid. A bond style of
{harmonic} and an angle style of {harmonic} or {charmm} should also be
used.
These are the additional parameters (in real units) to set for O and H
atoms and the water molecule to run a rigid SPC model.
O mass = 15.9994
H mass = 1.008 :all(b),p
O charge = -0.820
H charge = 0.410 :all(b),p
LJ epsilon of OO = 0.1553
LJ sigma of OO = 3.166
LJ epsilon, sigma of OH, HH = 0.0 :all(b),p
r0 of OH bond = 1.0
theta of HOH angle = 109.47 :all(b),p
Note that as originally proposed, the SPC model was run with a 9
Angstrom cutoff for both LJ and Coulommbic terms. It can also be used
with long-range Coulombics (Ewald or PPPM in LAMMPS), without changing
any of the parameters above, though it becomes a different model in
that mode of usage.
The SPC/E (extended) water model is the same, except
the partial charge assignemnts change:
O charge = -0.8476
H charge = 0.4238 :all(b),p
See the "(Berendsen)"_#Berendsen reference for more details on both
the SPC and SPC/E models.
Wikipedia also has a nice article on "water
models"_http://en.wikipedia.org/wiki/Water_model.
:line
6.10 Coupling LAMMPS to other codes :link(howto_10),h4
LAMMPS is designed to allow it to be coupled to other codes. For
example, a quantum mechanics code might compute forces on a subset of
atoms and pass those forces to LAMMPS. Or a continuum finite element
(FE) simulation might use atom positions as boundary conditions on FE
nodal points, compute a FE solution, and return interpolated forces on
MD atoms.
LAMMPS can be coupled to other codes in at least 3 ways. Each has
advantages and disadvantages, which you'll have to think about in the
context of your application.
(1) Define a new "fix"_fix.html command that calls the other code. In
this scenario, LAMMPS is the driver code. During its timestepping,
the fix is invoked, and can make library calls to the other code,
which has been linked to LAMMPS as a library. This is the way the
"POEMS"_poems package that performs constrained rigid-body motion on
groups of atoms is hooked to LAMMPS. See the
"fix_poems"_fix_poems.html command for more details. See "this
section"_Section_modify.html of the documentation for info on how to add
a new fix to LAMMPS.
:link(poems,http://www.rpi.edu/~anderk5/lab)
(2) Define a new LAMMPS command that calls the other code. This is
conceptually similar to method (1), but in this case LAMMPS and the
other code are on a more equal footing. Note that now the other code
is not called during the timestepping of a LAMMPS run, but between
runs. The LAMMPS input script can be used to alternate LAMMPS runs
with calls to the other code, invoked via the new command. The
"run"_run.html command facilitates this with its {every} option, which
makes it easy to run a few steps, invoke the command, run a few steps,
invoke the command, etc.
In this scenario, the other code can be called as a library, as in
(1), or it could be a stand-alone code, invoked by a system() call
made by the command (assuming your parallel machine allows one or more
processors to start up another program). In the latter case the
stand-alone code could communicate with LAMMPS thru files that the
command writes and reads.
-See "this section"_Section_modify.html of the documentation for how to
-add a new command to LAMMPS.
+See "Section_modify"_Section_modify.html of the documentation for how
+to add a new command to LAMMPS.
(3) Use LAMMPS as a library called by another code. In this case the
other code is the driver and calls LAMMPS as needed. Or a wrapper
code could link and call both LAMMPS and another code as libraries.
Again, the "run"_run.html command has options that allow it to be
invoked with minimal overhead (no setup or clean-up) if you wish to do
multiple short runs, driven by another program.
Examples of driver codes that call LAMMPS as a library are included in
the "couple" directory of the LAMMPS distribution; see couple/README
for more details:
simple: simple driver programs in C++ and C which invoke LAMMPS as a
library :ulb,l
lammps_quest: coupling of LAMMPS and "Quest"_quest, to run classical
MD with quantum forces calculated by a density functional code :l
lammps_spparks: coupling of LAMMPS and "SPPARKS"_spparks, to couple
a kinetic Monte Carlo model for grain growth using MD to calculate
strain induced across grain boundaries :l,ule
:link(quest,http://dft.sandia.gov/Quest)
:link(spparks,http://www.sandia.gov/~sjplimp/spparks.html)
"This section"_Section_start.html#start_4 of the documentation
describes how to build LAMMPS as a library. Once this is done, you
can interface with LAMMPS either via C++, C, Fortran, or Python (or
any other language that supports a vanilla C-like interface). For
example, from C++ you could create one (or more) "instances" of
LAMMPS, pass it an input script to process, or execute individual
commands, all by invoking the correct class methods in LAMMPS. From C
or Fortran you can make function calls to do the same things. See
-"this section"_Section_python.html of the manual for a description of
-the Python wrapper provided with LAMMPS that operates through the
+"Section_python"_Section_python.html of the manual for a description
+of the Python wrapper provided with LAMMPS that operates through the
LAMMPS library interface.
The files src/library.cpp and library.h contain the C-style interface
-to LAMMPS. See "this section"_Section_howto.html#howto_19 of the manual
-for a description of the interface and how to extend it for your
-needs.
+to LAMMPS. See "Section_howto 19"_Section_howto.html#howto_19 of the
+manual for a description of the interface and how to extend it for
+your needs.
Note that the lammps_open() function that creates an instance of
LAMMPS takes an MPI communicator as an argument. This means that
instance of LAMMPS will run on the set of processors in the
communicator. Thus the calling code can run LAMMPS on all or a subset
of processors. For example, a wrapper script might decide to
alternate between LAMMPS and another code, allowing them both to run
on all the processors. Or it might allocate half the processors to
LAMMPS and half to the other code and run both codes simultaneously
before syncing them up periodically. Or it might instantiate multiple
instances of LAMMPS to perform different calculations.
:line
6.11 Visualizing LAMMPS snapshots :link(howto_11),h4
LAMMPS itself does not do visualization, but snapshots from LAMMPS
simulations can be visualized (and analyzed) in a variety of ways.
LAMMPS snapshots are created by the "dump"_dump.html command which can
create files in several formats. The native LAMMPS dump format is a
text file (see "dump atom" or "dump custom") which can be visualized
by the "xmovie"_Section_tools.html#xmovie program, included with the
LAMMPS package. This produces simple, fast 2d projections of 3d
systems, and can be useful for rapid debugging of simulation geometry
and atom trajectories.
Several programs included with LAMMPS as auxiliary tools can convert
native LAMMPS dump files to other formats. See the
"Section_tools"_Section_tools.html doc page for details. The first is
the "ch2lmp tool"_Section_tools.html#charmm, which contains a
lammps2pdb Perl script which converts LAMMPS dump files into PDB
files. The second is the "lmp2arc tool"_Section_tools.html#arc which
converts LAMMPS dump files into Accelrys' Insight MD program files.
The third is the "lmp2cfg tool"_Section_tools.html#cfg which converts
LAMMPS dump files into CFG files which can be read into the
"AtomEye"_atomeye visualizer.
A Python-based toolkit distributed by our group can read native LAMMPS
dump files, including custom dump files with additional columns of
user-specified atom information, and convert them to various formats
or pipe them into visualization software directly. See the "Pizza.py
WWW site"_pizza for details. Specifically, Pizza.py can convert
LAMMPS dump files into PDB, XYZ, "Ensight"_ensight, and VTK formats.
Pizza.py can pipe LAMMPS dump files directly into the Raster3d and
RasMol visualization programs. Pizza.py has tools that do interactive
3d OpenGL visualization and one that creates SVG images of dump file
snapshots.
LAMMPS can create XYZ files directly (via "dump xyz") which is a
simple text-based file format used by many visualization programs
including "VMD"_vmd.
LAMMPS can create DCD files directly (via "dump dcd") which can be
read by "VMD"_vmd in conjunction with a CHARMM PSF file. Using this
form of output avoids the need to convert LAMMPS snapshots to PDB
files. See the "dump"_dump.html command for more information on DCD
files.
LAMMPS can create XTC files directly (via "dump xtc") which is GROMACS
file format which can also be read by "VMD"_vmd for visualization.
See the "dump"_dump.html command for more information on XTC files.
:link(pizza,http://www.sandia.gov/~sjplimp/pizza.html)
:link(vmd,http://www.ks.uiuc.edu/Research/vmd)
:link(ensight,http://www.ensight.com)
:link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A)
:line
6.12 Triclinic (non-orthogonal) simulation boxes :link(howto_12),h4
By default, LAMMPS uses an orthogonal simulation box to encompass the
particles. The "boundary"_boundary.html command sets the boundary
conditions of the box (periodic, non-periodic, etc). The orthogonal
box has its "origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors
starting from the origin given by [a] = (xhi-xlo,0,0); [b] =
(0,yhi-ylo,0); [c] = (0,0,zhi-zlo). The 6 parameters
(xlo,xhi,ylo,yhi,zlo,zhi) are defined at the time the simluation box
is created, e.g. by the "create_box"_create_box.html or
"read_data"_read_data.html or "read_restart"_read_restart.html
commands. Additionally, LAMMPS defines box size parameters lx,ly,lz
where lx = xhi-xlo, and similarly in the y and z dimensions. The 6
parameters, as well as lx,ly,lz, can be output via the "thermo_style
custom"_thermo_style.html command.
LAMMPS also allows simulations to be perfored in non-orthogonal
simulation boxes shaped as a parallelepiped with triclinic symmetry.
The parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by
3 edge vectors starting from the origin given by [a] = (xhi-xlo,0,0); [b]
= (xy,yhi-ylo,0); [c] = (xz,yz,zhi-zlo). {Xy,xz,yz} can be 0.0 or
positive or negative values and are called "tilt factors" because they
are the amount of displacement applied to faces of an originally
orthogonal box to transform it into the parallelepiped. Note that in
LAMMPS the triclinic simulation box edge vectors [a], [b], and [c] cannot be
arbitrary vectors. As indicated, [a] must be aligned with the x axis, [b]
must be in the xy plane, and [c] is arbitrary. However, this is not a
restriction since it is possible to rotate any set of 3 crystal basis
vectors so that they meet this restriction.
The 9 parameters (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) are defined at the
time the simluation box is created. This happens in one of 3 ways.
If the "create_box"_create_box.html command is used with a region of
style {prism}, then a triclinic box is setup. See the
"region"_region.html command for details. If the
"read_data"_read_data.html command is used to define the simulation
box, and the header of the data file contains a line with the "xy xz
yz" keyword, then a triclinic box is setup. See the
"read_data"_read_data.html command for details. Finally, if the
"read_restart"_read_restart.html command reads a restart file which
was written from a simulation using a triclinic box, then a triclinic
box will be setup for the restarted simulation.
Note that you can define a triclinic box with all 3 tilt factors =
0.0, so that it is initially orthogonal. This is necessary if the box
will become non-orthogonal, e.g. due to the "fix npt"_fix_nh.html or
"fix deform"_fix_deform.html commands. Alternatively, you can use the
"change_box"_change_box.html command to convert a simulation box from
orthogonal to triclinic and vice versa.
As with orthogonal boxes, LAMMPS defines triclinic box size parameters
lx,ly,lz where lx = xhi-xlo, and similarly in the y and z dimensions.
The 9 parameters, as well as lx,ly,lz, can be output via the
"thermo_style custom"_thermo_style.html command.
To avoid extremely tilted boxes (which would be computationally
inefficient), no tilt factor can skew the box more than half the
distance of the parallel box length, which is the 1st dimension in the
tilt factor (x for xz). For example, if xlo = 2 and xhi = 12, then
the x box length is 10 and the xy tilt factor must be between -5 and
5. Similarly, both xz and yz must be between -(xhi-xlo)/2 and
+(yhi-ylo)/2. Note that this is not a limitation, since if the
maximum tilt factor is 5 (as in this example), then configurations
with tilt = ..., -15, -5, 5, 15, 25, ... are geometrically all
equivalent.
Triclinic crystal structures are often defined using three lattice
constants {a}, {b}, and {c}, and three angles {alpha}, {beta} and
{gamma}. Note that in this nomenclature, the a, b, and c lattice constants
are the scalar lengths of the edge vectors [a], [b], and [c] defined
above. The
relationship between these 6 quantities (a,b,c,alpha,beta,gamma) and
the LAMMPS box sizes (lx,ly,lz) = (xhi-xlo,yhi-ylo,zhi-zlo) and tilt
factors (xy,xz,yz) is as follows:
:c,image(Eqs/box.jpg)
The inverse relationship can be written as follows:
:c,image(Eqs/box_inverse.jpg)
The values of {a}, {b}, {c} , {alpha}, {beta} , and {gamma} can be printed
out or accessed by computes using the
"thermo_style custom"_thermo_style.html keywords
{cella}, {cellb}, {cellc}, {cellalpha}, {cellbeta}, {cellgamma},
respectively.
As discussed on the "dump"_dump.html command doc page, when the BOX
BOUNDS for a snapshot is written to a dump file for a triclinic box,
an orthogonal bounding box which encloses the triclinic simulation box
is output, along with the 3 tilt factors (xy, xz, yz) of the triclinic
box, formatted as follows:
ITEM: BOX BOUNDS xy xz yz
xlo_bound xhi_bound xy
ylo_bound yhi_bound xz
zlo_bound zhi_bound yz :pre
This bounding box is convenient for many visualization programs and is
calculated from the 9 triclinic box parameters
(xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) as follows:
xlo_bound = xlo + MIN(0.0,xy,xz,xy+xz)
xhi_bound = xhi + MAX(0.0,xy,xz,xy+xz)
ylo_bound = ylo + MIN(0.0,yz)
yhi_bound = yhi + MAX(0.0,yz)
zlo_bound = zlo
zhi_bound = zhi :pre
These formulas can be inverted if you need to convert the bounding box
back into the triclinic box parameters, e.g. xlo = xlo_bound -
MIN(0.0,xy,xz,xy+xz).
One use of triclinic simulation boxes is to model solid-state crystals
with triclinic symmetry. The "lattice"_lattice.html command can be
used with non-orthogonal basis vectors to define a lattice that will
tile a triclinic simulation box via the
"create_atoms"_create_atoms.html command.
A second use is to run Parinello-Rahman dyanamics via the "fix
npt"_fix_nh.html command, which will adjust the xy, xz, yz tilt
factors to compensate for off-diagonal components of the pressure
tensor. The analalog for an "energy minimization"_minimize.html is
the "fix box/relax"_fix_box_relax.html command.
A third use is to shear a bulk solid to study the response of the
material. The "fix deform"_fix_deform.html command can be used for
this purpose. It allows dynamic control of the xy, xz, yz tilt
factors as a simulation runs. This is discussed in the next section
on non-equilibrium MD (NEMD) simulations.
:line
6.13 NEMD simulations :link(howto_13),h4
Non-equilibrium molecular dynamics or NEMD simulations are typically
used to measure a fluid's rheological properties such as viscosity.
In LAMMPS, such simulations can be performed by first setting up a
non-orthogonal simulation box (see the preceding Howto section).
A shear strain can be applied to the simulation box at a desired
strain rate by using the "fix deform"_fix_deform.html command. The
"fix nvt/sllod"_fix_nvt_sllod.html command can be used to thermostat
the sheared fluid and integrate the SLLOD equations of motion for the
system. Fix nvt/sllod uses "compute
temp/deform"_compute_temp_deform.html to compute a thermal temperature
by subtracting out the streaming velocity of the shearing atoms. The
velocity profile or other properties of the fluid can be monitored via
the "fix ave/spatial"_fix_ave_spatial.html command.
As discussed in the previous section on non-orthogonal simulation
boxes, the amount of tilt or skew that can be applied is limited by
LAMMPS for computational efficiency to be 1/2 of the parallel box
length. However, "fix deform"_fix_deform.html can continuously strain
a box by an arbitrary amount. As discussed in the "fix
deform"_fix_deform.html command, when the tilt value reaches a limit,
the box is re-shaped to the opposite limit which is an equivalent
tiling of periodic space. The strain rate can then continue to change
as before. In a long NEMD simulation these box re-shaping events may
occur many times.
In a NEMD simulation, the "remap" option of "fix
deform"_fix_deform.html should be set to "remap v", since that is what
"fix nvt/sllod"_fix_nvt_sllod.html assumes to generate a velocity
profile consistent with the applied shear strain rate.
An alternative method for calculating viscosities is provided via the
"fix viscosity"_fix_viscosity.html command.
:line
6.14 Extended spherical and aspherical particles :link(howto_14),h4
Typical MD models treat atoms or particles as point masses.
Sometimes, however, it is desirable to have a model with finite-size
particles such as spheres or aspherical ellipsoids. The difference is
that such particles have a moment of inertia, rotational energy, and
angular momentum. Rotation is induced by torque from interactions
with other particles.
LAMMPS has several options for running simulations with these kinds of
particles. The following aspects are discussed in turn:
atom styles
pair potentials
time integration
computes, thermodynamics, and dump output
rigid bodies composed of extended particles :ul
Atom styles :h5
There are 2 "atom styles"_atom_style.html that allow for definition of
finite-size particles: sphere and ellipsoid. The peri atom style also
treats particles as having a volume, but that is internal to the
"pair_style peri"_pair_peri.html potentials. The dipole atom style is
most often used in conjunction with finite-size particles.
The sphere style defines particles that are spheriods and each
particle can have a unique diameter and mass (or density). These
particles store an angular velocity (omega) and can be acted upon by
torque. The "set" command can be used to modify the diameter and mass
of individual particles, after then are created.
The ellipsoid style defines particles that are ellipsoids and thus can
be aspherical. Each particle has a shape, specified by 3 diameters,
and mass (or density). These particles store an angular momentum and
their orientation (quaternion), and can be acted upon by torque. They
do not store an angular velocity (omega), which can be in a different
direction than angular momentum, rather they compute it as needed.
The "set" command can be used to modify the diameter, orientation, and
mass of individual particles, after then are created. It also has a
brief explanation of what quaternions are.
The dipole style does not define extended particles, but is often
used in conjunction with spherical particles, via a command like
atom_style hybrid sphere dipole :pre
This is because when dipoles interact with each other, they induce
torques, and a particle must be extended (i.e. have a moment of
inertia) in order to respond and rotate. See the "atom_style
dipole"_atom_style.html command for details. The "set" command can be
used to modify the orientation and length of the dipole moment of
individual particles, after then are created.
Note that if one of these atom styles is used (or multiple styles via
the "atom_style hybrid"_atom_style.html command), not all particles in
the system are required to be finite-size or aspherical. For example,
if the 3 shape parameters are set to the same value, the particle will
be a sphere rather than an ellipsoid. If the 3 shape parameters are
all set to 0.0 or if the diameter is set to 0.0, it will be a point
particle. If the length of the dipole moment is set to zero, the
particle will not have a point dipole associated with it. The pair
styles used to compute pairwise interactions will typically compute
the correct interaction in these simplified (cheaper) cases.
"Pair_style hybrid"_pair_hybrid.html can be used to insure the correct
interactions are computed for the appropriate style of interactions.
Likewise, using groups to partition particles (ellipsoids versus
spheres versus point particles) will allow you to use the appropriate
time integrators and temperature computations for each class of
particles. See the doc pages for various commands for details.
Also note that for "2d simulations"_dimension.html, finite-size
spheres and ellipsoids are still treated as 3d particles, rather than
as circular disks or ellipses. This means they have the same moment
of inertia for a 3d extended object. When their temperature is
coomputed, the correct degrees of freedom are used for rotation in a
2d versus 3d system.
Pair potentials :h5
When a system with extended particles is defined, the particles will
only rotate and experience torque if the force field computes such
interactions. These are the various "pair styles"_pair_style.html
that generate torque:
"pair_style gran/history"_pair_gran.html
"pair_style gran/hertzian"_pair_gran.html
"pair_style gran/no_history"_pair_gran.html
"pair_style dipole/cut"_pair_dipole.html
"pair_style gayberne"_pair_gayberne.html
"pair_style resquared"_pair_resquared.html
"pair_style lubricate"_pair_lubricate.html :ul
The "granular pair styles"_pair_gran.html are used with spherical
particles. The "dipole pair style"_pair_dipole.html is used with
"atom_style dipole"_atom_style.html, which could be applied to
spherical or ellipsoidal particles. The "GayBerne"_pair_gayberne.html
and "REsquared"_pair_resquared.html potentials require ellipsoidal
particles, though they will also work if the 3 shape parameters are
the same (a sphere). The "lubrication potential"_pair_lubricate.html
works with spherical particles.
Time integration :h5
There are 3 fixes that perform time integration on extended spherical
particles, meaning the integrators update the rotational orientation
and angular velocity or angular momentum of the particles:
"fix nve/sphere"_fix_nve_sphere.html
"fix nvt/sphere"_fix_nvt_sphere.html
"fix npt/sphere"_fix_npt_sphere.html :ul
Likewise, there are 3 fixes that perform time integration on
ellipsoids as extended aspherical particles:
"fix nve/asphere"_fix_nve_asphere.html
"fix nvt/asphere"_fix_nvt_asphere.html
"fix npt/asphere"_fix_npt_asphere.html :ul
The advantage of these fixes is that those which thermostat the
particles include the rotational degrees of freedom in the temperature
calculation and thermostatting. Other thermostats can be used with
fix nve/sphere or fix nve/asphere, such as fix langevin or fix
temp/berendsen, but those thermostats only operate on the
translational kinetic energy of the extended particles.
Note that for mixtures of point and extended particles, you should
only use these integration fixes on "groups"_group.html which contain
extended particles.
Computes, thermodynamics, and dump output :h5
There are 4 computes that calculate the temperature or rotational energy
of extended spherical or aspherical particles (ellipsoids):
"compute temp/sphere"_compute_temp_sphere.html
"compute temp/asphere"_compute_temp_asphere.html
"compute erotate/sphere"_compute_erotate_sphere.html
"compute erotate/asphere"_compute_erotate_asphere.html :ul
These include rotational degrees of freedom in their computation. If
you wish the thermodynamic output of temperature or pressure to use
one of these computes (e.g. for a system entirely composed of extended
particles), then the compute can be defined and the
"thermo_modify"_thermo_modify.html command used. Note that by
default thermodynamic quantities will be calculated with a temperature
that only includes translational degrees of freedom. See the
"thermo_style"_thermo_style.html command for details.
The "dump custom"_dump.html command can output various attributes of
extended particles, including the dipole moment (mu), the angular
velocity (omega), the angular momentum (angmom), the quaternion
(quat), and the torque (tq) on the particle.
Rigid bodies composed of extended particles :h5
The "fix rigid"_fix_rigid.html command treats a collection of
particles as a rigid body, computes its inertia tensor, sums the total
force and torque on the rigid body each timestep due to forces on its
constituent particles, and integrates the motion of the rigid body.
If any of the constituent particles of a rigid body are extended
particles (spheres or ellipsoids), then their contribution to the
inertia tensor of the body is different than if they were point
particles. This means the rotational dynamics of the rigid body will
be different. Thus a model of a dimer is different if the dimer
consists of two point masses versus two extended sphereoids, even if
the two particles have the same mass. Extended particles that
experience torque due to their interaction with other particles will
also impart that torque to a rigid body they are part of.
See the "fix rigid" command for example of complex rigid-body models
it is possible to define in LAMMPS.
Note that the "fix shake"_fix_shake.html command can also be used to
treat 2, 3, or 4 particles as a rigid body, but it always assumes the
particles are point masses.
:line
6.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) :link(howto_15),h4
There are four basic kinds of LAMMPS output:
"Thermodynamic output"_thermo_style.html, which is a list
of quantities printed every few timesteps to the screen and logfile. :ulb,l
"Dump files"_dump.html, which contain snapshots of atoms and various
per-atom values and are written at a specified frequency. :l
Certain fixes can output user-specified quantities to files: "fix
ave/time"_fix_ave_time.html for time averaging, "fix
ave/spatial"_fix_ave_spatial.html for spatial averaging, and "fix
print"_fix_print.html for single-line output of
"variables"_variable.html. Fix print can also output to the
screen. :l
"Restart files"_restart.html. :l,ule
A simulation prints one set of thermodynamic output and (optionally)
restart files. It can generate any number of dump files and fix
output files, depending on what "dump"_dump.html and "fix"_fix.html
commands you specify.
As discussed below, LAMMPS gives you a variety of ways to determine
what quantities are computed and printed when the thermodynamics,
dump, or fix commands listed above perform output. Throughout this
discussion, note that users can also "add their own computes and fixes
to LAMMPS"_Section_modify.html which can then generate values that can
then be output with these commands.
The following sub-sections discuss different LAMMPS command related
to output and the kind of data they operate on and produce:
"Global/per-atom/local data"_#global
"Scalar/vector/array data"_#scalar
"Thermodynamic output"_#thermo
"Dump file output"_#dump
"Fixes that write output files"_#fixoutput
"Computes that process output quantities"_#computeoutput
"Fixes that process output quantities"_#fixoutput
"Computes that generate values to output"_#compute
"Fixes that generate values to output"_#fix
"Variables that generate values to output"_#variable
"Summary table of output options and data flow between commands"_#table :ul
Global/per-atom/local data :h5,link(global)
Various output-related commands work with three different styles of
data: global, per-atom, or local. A global datum is one or more
system-wide values, e.g. the temperature of the system. A per-atom
datum is one or more values per atom, e.g. the kinetic energy of each
atom. Local datums are calculated by each processor based on the
atoms it owns, but there may be zero or more per atom, e.g. a list of
bond distances.
Scalar/vector/array data :h5,link(scalar)
Global, per-atom, and local datums can each come in three kinds: a
single scalar value, a vector of values, or a 2d array of values. The
doc page for a "compute" or "fix" or "variable" that generates data
will specify both the style and kind of data it produces, e.g. a
per-atom vector.
When a quantity is accessed, as in many of the output commands
discussed below, it can be referenced via the following bracket
notation, where ID in this case is the ID of a compute. The leading
"c_" would be replaced by "f_" for a fix, or "v_" for a variable:
c_ID | entire scalar, vector, or array
c_ID\[I\] | one element of vector, one column of array
c_ID\[I\]\[J\] | one element of array :tb(s=|)
In other words, using one bracket reduces the dimension of the data
once (vector -> scalar, array -> vector). Using two brackets reduces
the dimension twice (array -> scalar). Thus a command that uses
scalar values as input can typically also process elements of a vector
or array.
Thermodynamic output :h5,link(thermo)
The frequency and format of thermodynamic output is set by the
"thermo"_thermo.html, "thermo_style"_thermo_style.html, and
"thermo_modify"_thermo_modify.html commands. The
"thermo_style"_thermo_style.html command also specifies what values
are calculated and written out. Pre-defined keywords can be specified
(e.g. press, etotal, etc). Three additional kinds of keywords can
also be specified (c_ID, f_ID, v_name), where a "compute"_compute.html
or "fix"_fix.html or "variable"_variable.html provides the value to be
output. In each case, the compute, fix, or variable must generate
global values for input to the "thermo_style custom"_dump.html
command.
Dump file output :h5,link(dump)
Dump file output is specified by the "dump"_dump.html and
"dump_modify"_dump_modify.html commands. There are several
pre-defined formats (dump atom, dump xtc, etc).
There is also a "dump custom"_dump.html format where the user
specifies what values are output with each atom. Pre-defined atom
attributes can be specified (id, x, fx, etc). Three additional kinds
of keywords can also be specified (c_ID, f_ID, v_name), where a
"compute"_compute.html or "fix"_fix.html or "variable"_variable.html
provides the values to be output. In each case, the compute, fix, or
variable must generate per-atom values for input to the "dump
custom"_dump.html command.
There is also a "dump local"_dump.html format where the user specifies
what local values to output. A pre-defined index keyword can be
specified to enumuerate the local values. Two additional kinds of
keywords can also be specified (c_ID, f_ID), where a
"compute"_compute.html or "fix"_fix.html or "variable"_variable.html
provides the values to be output. In each case, the compute or fix
must generate local values for input to the "dump local"_dump.html
command.
Fixes that write output files :h5,link(fixoutput)
Sevarl fixes take various quantities as input and can write output
files: "fix ave/time"_fix_ave_time.html, "fix
ave/spatial"_fix_ave_spatial.html, "fix ave/histo"_fix_ave_histo.html,
"fix ave/correlate"_fix_ave_correlate.html, and "fix
print"_fix_print.html.
The "fix ave/time"_fix_ave_time.html command enables direct output to
a file and/or time-averaging of global scalars or vectors. The user
specifies one or more quantities as input. These can be global
"compute"_compute.html values, global "fix"_fix.html values, or
"variables"_variable.html of any style except the atom style which
produces per-atom values. Since a variable can refer to keywords used
by the "thermo_style custom"_thermo_style.html command (like temp or
press) and individual per-atom values, a wide variety of quantities
can be time averaged and/or output in this way. If the inputs are one
or more scalar values, then the fix generate a global scalar or vector
of output. If the inputs are one or more vector values, then the fix
generates a global vector or array of output. The time-averaged
output of this fix can also be used as input to other output commands.
The "fix ave/spatial"_fix_ave_spatial.html command enables direct
output to a file of spatial-averaged per-atom quantities like those
output in dump files, within 1d layers of the simulation box. The
per-atom quantities can be atom density (mass or number) or atom
attributes such as position, velocity, force. They can also be
per-atom quantities calculated by a "compute"_compute.html, by a
"fix"_fix.html, or by an atom-style "variable"_variable.html. The
spatial-averaged output of this fix can also be used as input to other
output commands.
The "fix ave/histo"_fix_ave_histo.html command enables direct output
to a file of histogrammed quantities, which can be global or per-atom
or local quantities. The histogram output of this fix can also be
used as input to other output commands.
The "fix ave/correlate"_fix_ave_histo.html command enables direct
output to a file of time-correlated quantities, which can be global
scalars. The correlation matrix output of this fix can also be used
as input to other output commands.
The "fix print"_fix_print.html command can generate a line of output
written to the screen and log file or to a separate file, periodically
during a running simulation. The line can contain one or more
"variable"_variable.html values for any style variable except the atom
style). As explained above, variables themselves can contain
references to global values generated by "thermodynamic
keywords"_thermo_style.html, "computes"_compute.html,
"fixes"_fix.html, or other "variables"_variable.html, or to per-atom
values for a specific atom. Thus the "fix print"_fix_print.html
command is a means to output a wide variety of quantities separate
from normal thermodynamic or dump file output.
Computes that process output quantities :h5,link(computeoutput)
The "compute reduce"_compute_reduce.html and "compute
reduce/region"_compute_reduce.html commands take one or more per-atom
or local vector quantities as inputs and "reduce" them (sum, min, max,
ave) to scalar quantities. These are produced as output values which
can be used as input to other output commands.
The "compute slice"_compute_slice.html command take one or more global
vector or array quantities as inputs and extracts a subset of their
values to create a new vector or array. These are produced as output
values which can be used as input to other output commands.
The "compute property/atom"_compute_property_atom.html command takes a
list of one or more pre-defined atom attributes (id, x, fx, etc) and
stores the values in a per-atom vector or array. These are produced
as output values which can be used as input to other output commands.
The list of atom attributes is the same as for the "dump
custom"_dump.html command.
The "compute property/local"_compute_property_local.html command takes
a list of one or more pre-defined local attributes (bond info, angle
info, etc) and stores the values in a local vector or array. These
are produced as output values which can be used as input to other
output commands.
The "compute atom/molecule"_compute_atom_molecule.html command takes a
list of one or more per-atom quantities (from a compute, fix, per-atom
variable) and sums the quantities on a per-molecule basis. It
produces a global vector or array as output values which can be used
as input to other output commands.
Fixes that process output quantities :h5,link(fixoutput)
The "fix ave/atom"_fix_ave_atom.html command performs time-averaging
of per-atom vectors. The per-atom quantities can be atom attributes
such as position, velocity, force. They can also be per-atom
quantities calculated by a "compute"_compute.html, by a
"fix"_fix.html, or by an atom-style "variable"_variable.html. The
time-averaged per-atom output of this fix can be used as input to
other output commands.
The "fix store/state"_fix_store_state.html command can archive one or
more per-atom attributes at a particular time, so that the old values
can be used in a future calculation or output. The list of atom
attributes is the same as for the "dump custom"_dump.html command,
including per-atom quantities calculated by a "compute"_compute.html,
by a "fix"_fix.html, or by an atom-style "variable"_variable.html.
The output of this fix can be used as input to other output commands.
Computes that generate values to output :h5,link(compute)
Every "compute"_compute.html in LAMMPS produces either global or
per-atom or local values. The values can be scalars or vectors or
arrays of data. These values can be output using the other commands
described in this section. The doc page for each compute command
describes what it produces. Computes that produce per-atom or local
values have the word "atom" or "local" in their style name. Computes
without the word "atom" or "local" produce global values.
Fixes that generate values to output :h5,link(fix)
Some "fixes"_fix.html in LAMMPS produces either global or per-atom or
local values which can be accessed by other commands. The values can
be scalars or vectors or arrays of data. These values can be output
using the other commands described in this section. The doc page for
each fix command tells whether it produces any output quantities and
describes them.
Variables that generate values to output :h5,link(variable)
Every "variables"_variable.html defined in an input script generates
either a global scalar value or a per-atom vector (only atom-style
variables) when it is accessed. The formulas used to define equal-
and atom-style variables can contain references to the thermodynamic
keywords and to global and per-atom data generated by computes, fixes,
and other variables. The values generated by variables can be output
using the other commands described in this section.
Summary table of output options and data flow between commands :h5,link(table)
This table summarizes the various commands that can be used for
generating output from LAMMPS. Each command produces output data of
some kind and/or writes data to a file. Most of the commands can take
data from other commands as input. Thus you can link many of these
commands together in pipeline form, where data produced by one command
is used as input to another command and eventually written to the
screen or to a file. Note that to hook two commands together the
output and input data types must match, e.g. global/per-atom/local
data and scalar/vector/array data.
Also note that, as described above, when a command takes a scalar as
input, that could be an element of a vector or array. Likewise a
vector input could be a column of an array.
Command: Input: Output:
"thermo_style custom"_thermo_style.html: global scalars: screen, log file:
"dump custom"_dump.html: per-atom vectors: dump file:
"dump local"_dump.html: local vectors: dump file:
"fix print"_fix_print.html: global scalar from variable: screen, file:
"print"_print.html: global scalar from variable: screen:
"computes"_compute.html: N/A: global/per-atom/local scalar/vector/array:
"fixes"_fix.html: N/A: global/per-atom/local scalar/vector/array:
"variables"_variable.html: global scalars, per-atom vectors: global scalar, per-atom vector:
"compute reduce"_compute_reduce.html: per-atom/local vectors: global scalar/vector:
"compute slice"_compute_slice.html: global vectors/arrays: global vector/array:
"compute property/atom"_compute_property_atom.html: per-atom vectors: per-atom vector/array:
"compute property/local"_compute_property_local.html: local vectors: local vector/array:
"compute atom/molecule"_compute_atom_molecule.html: per-atom vectors: global vector/array:
"fix ave/atom"_fix_ave_atom.html: per-atom vectors: per-atom vector/array:
"fix ave/time"_fix_ave_time.html: global scalars/vectors: global scalar/vector/array, file:
"fix ave/spatial"_fix_ave_spatial.html: per-atom vectors: global array, file:
"fix ave/histo"_fix_ave_histo.html: global/per-atom/local scalars and vectors: global array, file:
"fix ave/correlate"_fix_ave_correlate.html: global scalars: global array, file:
"fix store/state"_fix_store_state.html: per-atom vectors: per-atom vector/array:
:tb(s=:)
:line
6.16 Thermostatting, barostatting, and computing temperature :link(howto_16),h4
Thermostatting means controlling the temperature of particles in an MD
simulation. Barostatting means controlling the pressure. Since the
pressure includes a kinetic component due to particle velocities, both
these operations require calculation of the temperature. Typically a
target temperature (T) and/or pressure (P) is specified by the user,
and the thermostat or barostat attempts to equilibrate the system to
the requested T and/or P.
Temperature is computed as kinetic energy divided by some number of
degrees of freedom (and the Boltzmann constant). Since kinetic energy
is a function of particle velocity, there is often a need to
distinguish between a particle's advection velocity (due to some
aggregate motiion of particles) and its thermal velocity. The sum of
the two is the particle's total velocity, but the latter is often what
is wanted to compute a temperature.
LAMMPS has several options for computing temperatures, any of which
can be used in thermostatting and barostatting. These "compute
commands"_compute.html calculate temperature, and the "compute
pressure"_compute_pressure.html command calculates pressure.
"compute temp"_compute_temp.html
"compute temp/sphere"_compute_temp_sphere.html
"compute temp/asphere"_compute_temp_asphere.html
"compute temp/com"_compute_temp_com.html
"compute temp/deform"_compute_temp_deform.html
"compute temp/partial"_compute_temp_partial.html
"compute temp/profile"_compute_temp_profile.html
"compute temp/ramp"_compute_temp_ramp.html
"compute temp/region"_compute_temp_region.html :ul
All but the first 3 calculate velocity biases (i.e. advection
velocities) that are removed when computing the thermal temperature.
"Compute temp/sphere"_compute_temp_sphere.html and "compute
temp/asphere"_compute_temp_asphere.html compute kinetic energy for
extended particles that includes rotational degrees of freedom. They
both allow, as an extra argument, which is another temperature compute
that subtracts a velocity bias. This allows the translational
velocity of extended spherical or aspherical particles to be adjusted
in prescribed ways.
Thermostatting in LAMMPS is performed by "fixes"_fix.html, or in one
case by a pair style. Four thermostatting fixes are currently
available: Nose-Hoover (nvt), Berendsen, Langevin, and direct
rescaling (temp/rescale). Dissipative particle dynamics (DPD)
thermostatting can be invoked via the {dpd/tstat} pair style:
"fix nvt"_fix_nh.html
"fix nvt/sphere"_fix_nvt_sphere.html
"fix nvt/asphere"_fix_nvt_asphere.html
"fix nvt/sllod"_fix_nvt_sllod.html
"fix temp/berendsen"_fix_temp_berendsen.html
"fix langevin"_fix_langevin.html
"fix temp/rescale"_fix_temp_rescale.html
"pair_style dpd/tstat"_pair_dpd.html :ul
"Fix nvt"_fix_nh.html only thermostats the translational velocity of
particles. "Fix nvt/sllod"_fix_nvt_sllod.html also does this, except
that it subtracts out a velocity bias due to a deforming box and
integrates the SLLOD equations of motion. See the "NEMD
simulations"_#howto_13 section of this page for further details. "Fix
nvt/sphere"_fix_nvt_sphere.html and "fix
nvt/asphere"_fix_nvt_asphere.html thermostat not only translation
velocities but also rotational velocities for spherical and aspherical
particles.
DPD thermostatting alters pairwise interactions in a manner analagous
to the per-particle thermostatting of "fix
langevin"_fix_langevin.html.
Any of the thermostatting fixes can use temperature computes that
remove bias for two purposes: (a) computing the current temperature to
compare to the requested target temperature, and (b) adjusting only
the thermal temperature component of the particle's velocities. See
the doc pages for the individual fixes and for the
"fix_modify"_fix_modify.html command for instructions on how to assign
a temperature compute to a thermostatting fix. For example, you can
apply a thermostat to only the x and z components of velocity by using
it in conjunction with "compute
temp/partial"_compute_temp_partial.html.
IMPORTANT NOTE: Only the nvt fixes perform time integration, meaning
they update the velocities and positions of particles due to forces
and velocities respectively. The other thermostat fixes only adjust
velocities; they do NOT perform time integration updates. Thus they
should be used in conjunction with a constant NVE integration fix such
as these:
"fix nve"_fix_nve.html
"fix nve/sphere"_fix_nve_sphere.html
"fix nve/asphere"_fix_nve_asphere.html :ul
Barostatting in LAMMPS is also performed by "fixes"_fix.html. Two
barosttating methods are currently available: Nose-Hoover (npt and
nph) and Berendsen:
"fix npt"_fix_nh.html
"fix npt/sphere"_fix_npt_sphere.html
"fix npt/asphere"_fix_npt_asphere.html
"fix nph"_fix_nh.html
"fix press/berendsen"_fix_press_berendsen.html :ul
The "fix npt"_fix_nh.html commands include a Nose-Hoover thermostat
and barostat. "Fix nph"_fix_nh.html is just a Nose/Hoover barostat;
it does no thermostatting. Both "fix nph"_fix_nh.html and "fix
press/bernendsen"_fix_press_berendsen.html can be used in conjunction
with any of the thermostatting fixes.
As with the thermostats, "fix npt"_fix_nh.html and "fix
nph"_fix_nh.html only use translational motion of the particles in
computing T and P and performing thermo/barostatting. "Fix
npt/sphere"_fix_npt_sphere.html and "fix
npt/asphere"_fix_npt_asphere.html thermo/barostat using not only
translation velocities but also rotational velocities for spherical
and aspherical particles.
All of the barostatting fixes use the "compute
pressure"_compute_pressure.html compute to calculate a current
pressure. By default, this compute is created with a simple "compute
temp"_compute_temp.html (see the last argument of the "compute
pressure"_compute_pressure.html command), which is used to calculated
the kinetic componenet of the pressure. The barostatting fixes can
also use temperature computes that remove bias for the purpose of
computing the kinetic componenet which contributes to the current
pressure. See the doc pages for the individual fixes and for the
"fix_modify"_fix_modify.html command for instructions on how to assign
a temperature or pressure compute to a barostatting fix.
IMPORTANT NOTE: As with the thermostats, the Nose/Hoover methods ("fix
npt"_fix_nh.html and "fix nph"_fix_nh.html) perform time
integration. "Fix press/berendsen"_fix_press_berendsen.html does NOT,
so it should be used with one of the constant NVE fixes or with one of
the NVT fixes.
Finally, thermodynamic output, which can be setup via the
"thermo_style"_thermo_style.html command, often includes temperature
and pressure values. As explained on the doc page for the
"thermo_style"_thermo_style.html command, the default T and P are
setup by the thermo command itself. They are NOT the ones associated
with any thermostatting or barostatting fix you have defined or with
any compute that calculates a temperature or pressure. Thus if you
want to view these values of T and P, you need to specify them
explicitly via a "thermo_style custom"_thermo_style.html command. Or
you can use the "thermo_modify"_thermo_modify.html command to
re-define what temperature or pressure compute is used for default
thermodynamic output.
:line
6.17 Walls :link(howto_17),h4
Walls in an MD simulation are typically used to bound particle motion,
i.e. to serve as a boundary condition.
Walls in LAMMPS can be of rough (made of particles) or idealized
surfaces. Ideal walls can be smooth, generating forces only in the
normal direction, or frictional, generating forces also in the
tangential direction.
Rough walls, built of particles, can be created in various ways. The
particles themselves can be generated like any other particle, via the
"lattice"_lattice.html and "create_atoms"_create_atoms.html commands,
or read in via the "read_data"_read_data.html command.
Their motion can be constrained by many different commands, so that
they do not move at all, move together as a group at constant velocity
or in response to a net force acting on them, move in a prescribed
fashion (e.g. rotate around a point), etc. Note that if a time
integration fix like "fix nve"_fix_nve.html or "fix nvt"_fix_nh.html
is not used with the group that contains wall particles, their
positions and velocities will not be updated.
"fix aveforce"_fix_aveforce.html - set force on particles to average value, so they move together
"fix setforce"_fix_setforce.html - set force on particles to a value, e.g. 0.0
"fix freeze"_fix_freeze.html - freeze particles for use as granular walls
"fix nve/noforce"_fix_nve_noforce.html - advect particles by their velocity, but without force
"fix move"_fix_move.html - prescribe motion of particles by a linear velocity, oscillation, rotation, variable :ul
The "fix move"_fix_move.html command offers the most generality, since
the motion of individual particles can be specified with
"variable"_variable.html formula which depends on time and/or the
particle position.
For rough walls, it may be useful to turn off pairwise interactions
between wall particles via the "neigh_modify
exclude"_neigh_modify.html command.
Rough walls can also be created by specifying frozen particles that do
not move and do not interact with mobile particles, and then tethering
other particles to the fixed particles, via a "bond"_bond_style.html.
The bonded particles do interact with other mobile particles.
Idealized walls can be specified via several fix commands. "Fix
wall/gran"_fix_wall_gran.html creates frictional walls for use with
granular particles; all the other commands create smooth walls.
"fix wall/reflect"_fix_wall_reflect.html - reflective flat walls
"fix wall/lj93"_fix_wall.html - flat walls, with Lennard-Jones 9/3 potential
"fix wall/lj126"_fix_wall.html - flat walls, with Lennard-Jones 12/6 potential
"fix wall/colloid"_fix_wall.html - flat walls, with "pair_style colloid"_pair_colloid.html potential
"fix wall/harmonic"_fix_wall.html - flat walls, with repulsive harmonic spring potential
"fix wall/region"_fix_wall_region.html - use region surface as wall
"fix wall/gran"_fix_wall_gran.html - flat or curved walls with "pair_style granular"_pair_gran.html potential :ul
The {lj93}, {lj126}, {colloid}, and {harmonic} styles all allow the
flat walls to move with a constant velocity, or oscillate in time.
The "fix wall/region"_fix_wall_region.html command offers the most
generality, since the region surface is treated as a wall, and the
geometry of the region can be a simple primitive volume (e.g. a
sphere, or cube, or plane), or a complex volume made from the union
and intersection of primitive volumes. "Regions"_region.html can also
specify a volume "interior" or "exterior" to the specified primitive
shape or {union} or {intersection}. "Regions"_region.html can also be
"dynamic" meaning they move with constant velocity, oscillate, or
rotate.
The only frictional idealized walls currently in LAMMPS are flat or
curved surfaces specified by the "fix wall/gran"_fix_wall_gran.html
command. At some point we plan to allow regoin surfaces to be used as
frictional walls, as well as triangulated surfaces.
:line
6.18 Elastic constants :link(howto_18),h4
Elastic constants characterize the stiffness of a material. The formal
definition is provided by the linear relation that holds between the
stress and strain tensors in the limit of infinitesimal deformation.
In tensor notation, this is expressed as s_ij = C_ijkl * e_kl, where
the repeated indices imply summation. s_ij are the elements of the
symmetric stress tensor. e_kl are the elements of the symmetric strain
tensor. C_ijkl are the elements of the fourth rank tensor of elastic
constants. In three dimensions, this tensor has 3^4=81 elements. Using
Voigt notation, the tensor can be written as a 6x6 matrix, where C_ij
is now the derivative of s_i w.r.t. e_j. Because s_i is itself a
derivative w.r.t. e_i, it follows that C_ij is also symmetric, with at
most 7*6/2 = 21 distinct elements.
At zero temperature, it is easy to estimate these derivatives by
deforming the cell in one of the six directions using the command
"displace_box"_displace_box.html and measuring the change in the
stress tensor. A general-purpose script that does this is given in the
examples/elastic directory described in "this
section"_Section_example.html.
Calculating elastic constants at finite temperature is more
challenging, because it is necessary to run a simulation that perfoms
time averages of differential properties. One way to do this is to
measure the change in average stress tensor in an NVT simulations when
the cell volume undergoes a finite deformation. In order to balance
the systematic and statistical errors in this method, the magnitude of
the deformation must be chosen judiciously, and care must be taken to
fully equilibrate the deformed cell before sampling the stress
tensor. Another approach is to sample the triclinic cell fluctuations
that occur in an NPT simulation. This method can also be slow to
converge and requires careful post-processing "(Shinoda)"_#Shinoda
:line
6.19 Library interface to LAMMPS :link(howto_19),h4
-As described in "this section"_Section_start.html#start_4, LAMMPS can
-be built as a library, so that it can be called by another code, used
-in a "coupled manner"_Section_howto.html#howto_10 with other codes, or
-driven through a "Python interface"_Section_python.html.
+As described in "Section_start 4"_Section_start.html#start_4, LAMMPS
+can be built as a library, so that it can be called by another code,
+used in a "coupled manner"_Section_howto.html#howto_10 with other
+codes, or driven through a "Python interface"_Section_python.html.
All of these methodologies use a C-style interface to LAMMPS that is
provided in the files src/library.cpp and src/library.h. The
functions therein have a C-style argument list, but contain C++ code
you could write yourself in a C++ application that was invoking LAMMPS
directly. The C++ code in the functions illustrates how to invoke
internal LAMMPS operations. Note that LAMMPS classes are defined
within a LAMMPS namespace (LAMMPS_NS) if you use them from another C++
application.
Library.cpp contains these 4 functions:
void lammps_open(int, char **, MPI_Comm, void **);
void lammps_close(void *);
void lammps_file(void *, char *);
char *lammps_command(void *, char *); :pre
The lammps_open() function is used to initialize LAMMPS, passing in a
list of strings as if they were "command-line
arguments"_Section_start.html#start_6 when LAMMPS is run in
stand-alone mode from the command line, and a MPI communicator for
LAMMPS to run under. It returns a ptr to the LAMMPS object that is
created, and which is used in subsequent library calls. The
lammps_open() function can be called multiple times, to create
multiple instances of LAMMPS.
LAMMPS will run on the set of processors in the communicator. This
means the calling code can run LAMMPS on all or a subset of
processors. For example, a wrapper script might decide to alternate
between LAMMPS and another code, allowing them both to run on all the
processors. Or it might allocate half the processors to LAMMPS and
half to the other code and run both codes simultaneously before
syncing them up periodically. Or it might instantiate multiple
instances of LAMMPS to perform different calculations.
The lammps_close() function is used to shut down an instance of LAMMPS
and free all its memory.
The lammps_file() and lammps_command() functions are used to pass a
file or string to LAMMPS as if it were an input script or single
command in an input script. Thus the calling code can read or
generate a series of LAMMPS commands one line at a time and pass it
thru the library interface to setup a problem and then run it,
interleaving the lammps_command() calls with other calls to extract
information from LAMMPS, perform its own operations, or call another
code's library.
Other useful functions are also included in library.cpp. For example:
void *lammps_extract_global(void *, char *)
void *lammps_extract_atom(void *, char *)
void *lammps_extract_compute(void *, char *, int, int)
void *lammps_extract_fix(void *, char *, int, int, int, int)
void *lammps_extract_variable(void *, char *, char *)
int lammps_get_natoms(void *)
void lammps_get_coords(void *, double *)
void lammps_put_coords(void *, double *) :pre
These can extract various global or per-atom quantities from LAMMPS as
well as values calculated by a compute, fix, or variable. The "get"
and "put" operations can retrieve and reset atom coordinates.
See the library.cpp file and its associated header file library.h for
details.
The key idea of the library interface is that you can write any
functions you wish to define how your code talks to LAMMPS and add
them to src/library.cpp and src/library.h, as well as to the "Python
interface"_Section_python.html. The routines you add can access
or change any LAMMPS data you wish. The couple and python directories
have example C++ and C and Python codes which show how a driver code
can link to LAMMPS as a library, run LAMMPS on a subset of processors,
grab data from LAMMPS, change it, and put it back into LAMMPS.
:line
6.20 Calculating thermal conductivity :link(howto_20),h4
The thermal conductivity kappa of a material can be measured in at
least 3 ways using various options in LAMMPS. (See "this
section"_Section_howto.html#howto_21 of the manual for an analogous
discussion for viscosity). The thermal conducitivity tensor kappa is
a measure of the propensity of a material to transmit heat energy in a
diffusive manner as given by Fourier's law
J = -kappa grad(T)
where J is the heat flux in units of energy per area per time and
grad(T) is the spatial gradient of temperature. The thermal
conductivity thus has units of energy per distance per time per degree
K and is often approximated as an isotropic quantity, i.e. as a
scalar.
The first method is to setup two thermostatted regions at opposite
ends of a simulation box, or one in the middle and one at the end of a
periodic box. By holding the two regions at different temperatures
with a "thermostatting fix"_Section_howto.html#howto_13, the energy added
to the hot region should equal the energy subtracted from the cold
region and be proportional to the heat flux moving between the
regions. See the paper by "Ikeshoji and Hafskjold"_#Ikeshoji for
details of this idea. Note that thermostatting fixes such as "fix
nvt"_fix_nh.html, "fix langevin"_fix_langevin.html, and "fix
temp/rescale"_fix_temp_rescale.html store the cumulative energy they
add/subtract. Alternatively, the "fix heat"_fix_heat.html command can
used in place of thermostats on each of two regions, and the resulting
temperatures of the two regions monitored with the "compute
temp/region" command or the temperature profile of the intermediate
region monitored with the "fix ave/spatial"_fix_ave_spatial.html and
"compute ke/atom"_compute_ke_atom.html commands.
The second method is to perform a reverse non-equilibrium MD
simulation using the "fix
thermal/conductivity"_fix_thermal_conductivity.html command which
implements the rNEMD algorithm of Muller-Plathe. Kinetic energy is
swapped between atoms in two different layers of the simulation box.
This induces a temperature gradient between the two layers which can
be monitored with the "fix ave/spatial"_fix_ave_spatial.html and
"compute ke/atom"_compute_ke_atom.html commands. The fix tallies the
cumulative energy transfer that it performs. See the "fix
thermal/conductivity"_fix_thermal_conductivity.html command for
details.
The third method is based on the Green-Kubo (GK) formula which relates
the ensemble average of the auto-correlation of the heat flux to
kappa. The heat flux can be calculated from the fluctuations of
per-atom potential and kinetic energies and per-atom stress tensor in
a steady-state equilibrated simulation. This is in contrast to the
two preceding non-equilibrium methods, where energy flows continuously
between hot and cold regions of the simulation box.
The "compute heat/flux"_compute_heat_flux.html command can calculate
the needed heat flux and describes how to implement the Green_Kubo
formalism using additional LAMMPS commands, such as the "fix
ave/correlate"_fix_ave_correlate.html command to calculate the needed
auto-correlation. See the doc page for the "compute
heat/flux"_compute_heat_flux.html command for an example input script
that calculates the thermal conductivity of solid Ar via the GK
formalism.
:line
6.21 Calculating viscosity :link(howto_21),h4
The shear viscosity eta of a fluid can be measured in at least 3 ways
using various options in LAMMPS. (See "this
section"_Section_howto.html#howto_20 of the manual for an analogous
discussion for thermal conductivity). Eta is a measure of the
propensity of a fluid to transmit momentum in a direction
perpendicular to the direction of velocity or momentum flow.
Alternatively it is the resistance the fluid has to being sheared. It
is given by
J = -eta grad(Vstream)
where J is the momentum flux in units of momentum per area per time.
and grad(Vstream) is the spatial gradient of the velocity of the fluid
moving in another direction, normal to the area through which the
momentum flows. Viscosity thus has units of pressure-time.
The first method is to perform a non-equlibrium MD (NEMD) simulation
by shearing the simulation box via the "fix deform"_fix_deform.html
command, and using the "fix nvt/sllod"_fix_nvt_sllod.html command to
thermostat the fluid via the SLLOD equations of motion. The velocity
profile setup in the fluid by this procedure can be monitored by the
"fix ave/spatial"_fix_ave_spatial.html command, which determines
grad(Vstream) in the equation above. E.g. the derivative in the
y-direction of the Vx component of fluid motion or grad(Vstream) =
dVx/dy. In this case, the Pxy off-diagonal component of the pressure
or stress tensor, as calculated by the "compute
pressure"_compute_pressure.html command, can also be monitored, which
is the J term in the equation above. See "this
section"_Section_howto.html#howto_13 of the manual for details on NEMD
simulations.
The second method is to perform a reverse non-equilibrium MD
simulation using the "fix viscosity"_fix_viscosity.html command which
implements the rNEMD algorithm of Muller-Plathe. Momentum in one
dimension is swapped between atoms in two different layers of the
simulation box in a different dimension. This induces a velocity
gradient which can be monitored with the "fix
ave/spatial"_fix_ave_spatial.html command. The fix tallies the
cummulative momentum transfer that it performs. See the "fix
viscosity"_fix_viscosity.html command for details.
The third method is based on the Green-Kubo (GK) formula which relates
the ensemble average of the auto-correlation of the stress/pressure
tensor to eta. This can be done in a steady-state equilibrated
simulation which is in contrast to the two preceding non-equilibrium
methods, where momentum flows continuously through the simulation box.
Here is an example input script that calculates the viscosity of
liquid Ar via the GK formalism:
# Sample LAMMPS input script for viscosity of liquid Ar :pre
units real
variable T equal 86.4956
variable V equal vol
variable dt equal 4.0
variable p equal 400 # correlation length
variable s equal 5 # sample interval
variable d equal $p*$s # dump interval :pre
# convert from LAMMPS real units to SI :pre
variable kB equal 1.3806504e-23 # \[J/K/] Boltzmann
variable atm2Pa equal 101325.0
variable A2m equal 1.0e-10
variable fs2s equal 1.0e-15
variable convert equal $\{atm2Pa\}*$\{atm2Pa\}*$\{fs2s\}*$\{A2m\}*$\{A2m\}*$\{A2m\} :pre
# setup problem :pre
dimension 3
boundary p p p
lattice fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
region box block 0 4 0 4 0 4
create_box 1 box
create_atoms 1 box
mass 1 39.948
pair_style lj/cut 13.0
pair_coeff * * 0.2381 3.405
timestep $\{dt\}
thermo $d :pre
# equilibration and thermalization :pre
velocity all create $T 102486 mom yes rot yes dist gaussian
fix NVT all nvt temp $T $T 10 drag 0.2
run 8000 :pre
# viscosity calculation, switch to NVE if desired :pre
#unfix NVT
#fix NVE all nve :pre
reset_timestep 0
variable pxy equal pxy
variable pxz equal pxz
variable pyz equal pyz
fix SS all ave/correlate $s $p $d &
v_pxy v_pxz v_pyz type auto file S0St.dat ave running
variable scale equal $\{convert\}/($\{kB\}*$T)*$V*$s*$\{dt\}
variable v11 equal trap(f_SS\[3/])*$\{scale\}
variable v22 equal trap(f_SS\[4/])*$\{scale\}
variable v33 equal trap(f_SS\[5/])*$\{scale\}
thermo_style custom step temp press v_pxy v_pxz v_pyz v_v11 v_v22 v_v33
run 100000
variable v equal (v_v11+v_v22+v_v33)/3.0
variable ndens equal count(all)/vol
print "average viscosity: $v \[Pa.s/] @ $T K, $\{ndens\} /A^3" :pre
:line
:line
:link(Berendsen)
[(Berendsen)] Berendsen, Grigera, Straatsma, J Phys Chem, 91,
6269-6271 (1987).
:link(Cornell)
[(Cornell)] Cornell, Cieplak, Bayly, Gould, Merz, Ferguson,
Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995).
:link(Horn)
[(Horn)] Horn, Swope, Pitera, Madura, Dick, Hura, and Head-Gordon,
J Chem Phys, 120, 9665 (2004).
:link(Ikeshoji)
[(Ikeshoji)] Ikeshoji and Hafskjold, Molecular Physics, 81, 251-261
(1994).
:link(MacKerell)
[(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
:link(Mayo)
[(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
:link(Jorgensen)
[(Jorgensen)] Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem
Phys, 79, 926 (1983).
:link(Price)
[(Price)] Price and Brooks, J Chem Phys, 121, 10096 (2004).
:link(Shinoda)
[(Shinoda)] Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004).
diff --git a/doc/Section_intro.html b/doc/Section_intro.html
index 3b659cf8e..9b278bfc8 100644
--- a/doc/Section_intro.html
+++ b/doc/Section_intro.html
@@ -1,539 +1,542 @@
<HTML>
<CENTER><A HREF = "Manual.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_start.html">Next Section</A>
</CENTER>
<HR>
<H3>1. Introduction
</H3>
-<P>These sections provide an overview of what LAMMPS can and can't do,
-describe what it means for LAMMPS to be an open-source code, and
-acknowledge the funding and people who have contributed to LAMMPS over
-the years.
+<P>This section provides an overview of what LAMMPS can and can't do,
+describes what it means for LAMMPS to be an open-source code, and
+acknowledges the funding and people who have contributed to LAMMPS
+over the years.
</P>
1.1 <A HREF = "#intro_1">What is LAMMPS</A><BR>
1.2 <A HREF = "#intro_2">LAMMPS features</A><BR>
1.3 <A HREF = "#intro_3">LAMMPS non-features</A><BR>
1.4 <A HREF = "#intro_4">Open source distribution</A><BR>
1.5 <A HREF = "#intro_5">Acknowledgments and citations</A> <BR>
<HR>
+<HR>
+
<A NAME = "intro_1"></A><H4>1.1 What is LAMMPS
</H4>
<P>LAMMPS is a classical molecular dynamics code that models an ensemble
of particles in a liquid, solid, or gaseous state. It can model
atomic, polymeric, biological, metallic, granular, and coarse-grained
systems using a variety of force fields and boundary conditions.
</P>
<P>For examples of LAMMPS simulations, see the Publications page of the
<A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.
</P>
<P>LAMMPS runs efficiently on single-processor desktop or laptop
machines, but is designed for parallel computers. It will run on any
parallel machine that compiles C++ and supports the <A HREF = "http://www-unix.mcs.anl.gov/mpi">MPI</A>
message-passing library. This includes distributed- or shared-memory
parallel machines and Beowulf-style clusters.
</P>
<P>LAMMPS can model systems with only a few particles up to millions or
-billions. See <A HREF = "Section_perf.html">this section</A> for information on LAMMPS
-performance and scalability, or the Benchmarks section of the <A HREF = "http://lammps.sandia.gov">LAMMPS
-WWW Site</A>.
+billions. See <A HREF = "Section_perf.html">Section_perf</A> for information on
+LAMMPS performance and scalability, or the Benchmarks section of the
+<A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.
</P>
<P>LAMMPS is a freely-available open-source code, distributed under the
terms of the <A HREF = "http://www.gnu.org/copyleft/gpl.html">GNU Public License</A>, which means you can use or
-modify the code however you wish. See <A HREF = "#intro_4">this section</A> for a brief
-discussion of the open-source philosophy.
+modify the code however you wish. See <A HREF = "#intro_4">this section</A> for a
+brief discussion of the open-source philosophy.
</P>
<P>LAMMPS is designed to be easy to modify or extend with new
capabilities, such as new force fields, atom types, boundary
-conditions, or diagnostics. See <A HREF = "Section_modify.html">this section</A> for
-more details.
+conditions, or diagnostics. See <A HREF = "Section_modify.html">Section_modify</A>
+for more details.
</P>
<P>The current version of LAMMPS is written in C++. Earlier versions
-were written in F77 and F90. See <A HREF = "Section_history.html">this section</A>
-for more information on different versions. All versions can be
-downloaded from the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.
+were written in F77 and F90. See
+<A HREF = "Section_history.html">Section_history</A> for more information on
+different versions. All versions can be downloaded from the <A HREF = "http://lammps.sandia.gov">LAMMPS
+WWW Site</A>.
</P>
<P>LAMMPS was originally developed under a US Department of Energy CRADA
(Cooperative Research and Development Agreement) between two DOE labs
and 3 companies. It is distributed by <A HREF = "http://www.sandia.gov">Sandia National Labs</A>.
See <A HREF = "#intro_5">this section</A> for more information on LAMMPS funding and
individuals who have contributed to LAMMPS.
</P>
<P>In the most general sense, LAMMPS integrates Newton's equations of
motion for collections of atoms, molecules, or macroscopic particles
that interact via short- or long-range forces with a variety of
initial and/or boundary conditions. For computational efficiency
LAMMPS uses neighbor lists to keep track of nearby particles. The
lists are optimized for systems with particles that are repulsive at
short distances, so that the local density of particles never becomes
too large. On parallel machines, LAMMPS uses spatial-decomposition
techniques to partition the simulation domain into small 3d
sub-domains, one of which is assigned to each processor. Processors
communicate and store "ghost" atom information for atoms that border
their sub-domain. LAMMPS is most efficient (in a parallel sense) for
systems whose particles fill a 3d rectangular box with roughly uniform
density. Papers with technical details of the algorithms used in
LAMMPS are listed in <A HREF = "#intro_5">this section</A>.
</P>
<HR>
<A NAME = "intro_2"></A><H4>1.2 LAMMPS features
</H4>
<P>This section highlights LAMMPS features, with pointers to specific
commands which give more details. If LAMMPS doesn't have your
favorite interatomic potential, boundary condition, or atom type, see
-<A HREF = "Section_modify.html">this section</A>, which describes how you can add it to
-LAMMPS.
+<A HREF = "Section_modify.html">Section_modify</A>, which describes how you can add
+it to LAMMPS.
</P>
<H4>General features
</H4>
<UL><LI> runs on a single processor or in parallel
<LI> distributed-memory message-passing parallelism (MPI)
<LI> spatial-decomposition of simulation domain for parallelism
<LI> open-source distribution
<LI> highly portable C++
<LI> optional libraries used: MPI and single-processor FFT
<LI> easy to extend with new features and functionality
<LI> runs from an input script
<LI> syntax for defining and using variables and formulas
<LI> syntax for looping over runs and breaking out of loops
<LI> run one or multiple simulations simultaneously (in parallel) from one script
<LI> build as library, invoke LAMMPS thru library interface or provided Python wrapper
<LI> couple with other codes: LAMMPS calls other code, other code calls LAMMPS, umbrella code calls both
</UL>
<H4>Particle and model types
</H4>
<P>(<A HREF = "atom_style.html">atom style</A> command)
</P>
<UL><LI> atoms
<LI> coarse-grained particles (e.g. bead-spring polymers)
<LI> united-atom polymers or organic molecules
<LI> all-atom polymers, organic molecules, proteins, DNA
<LI> metals
<LI> granular materials
<LI> coarse-grained mesoscale models
<LI> finite-size spherical and ellipsoidal particles
<LI> finite-size line segment (2d) and triangle (3d) particles
<LI> point dipolar particles
<LI> rigid collections of particles
<LI> hybrid combinations of these
</UL>
<H4>Force fields
</H4>
<P>(<A HREF = "pair_style.html">pair style</A>, <A HREF = "bond_style.html">bond style</A>,
<A HREF = "angle_style.html">angle style</A>, <A HREF = "dihedral_style.html">dihedral style</A>,
<A HREF = "improper_style.html">improper style</A>, <A HREF = "kspace_style.html">kspace style</A>
commands)
</P>
<UL><LI> pairwise potentials: Lennard-Jones, Buckingham, Morse, Born-Mayer-Huggins, Yukawa, soft, class 2 (COMPASS), hydrogen bond, tabulated
<LI> charged pairwise potentials: Coulombic, point-dipole
<LI> manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), embedded ion method (EIM), EDIP, ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB
<LI> electron force field (eFF, AWPMD)
<LI> coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO
<LI> mesoscopic potentials: granular, Peridynamics, SPH
<LI> bond potentials: harmonic, FENE, Morse, nonlinear, class 2, quartic (breakable)
<LI> angle potentials: harmonic, CHARMM, cosine, cosine/squared, cosine/periodic, class 2 (COMPASS)
<LI> dihedral potentials: harmonic, CHARMM, multi-harmonic, helix, class 2 (COMPASS), OPLS
<LI> improper potentials: harmonic, cvff, umbrella, class 2 (COMPASS)
<LI> polymer potentials: all-atom, united-atom, bead-spring, breakable
<LI> water potentials: TIP3P, TIP4P, SPC
<LI> implicit solvent potentials: hydrodynamic lubrication, Debye
-<LI> long-range Coulombics and dispersion: Ewald, PPPM (similar to particle-mesh Ewald), Ewald/N for long-range Lennard-Jones
+<LI> long-range Coulombics and dispersion: Ewald, Wolf, PPPM (similar to particle-mesh Ewald), Ewald/N for long-range Lennard-Jones
<LI> force-field compatibility with common CHARMM, AMBER, DREIDING, OPLS, GROMACS, COMPASS options
<LI> handful of GPU-enabled pair styles
</UL>
<P> hybrid potentials: multiple pair, bond, angle, dihedral, improper potentials can be used in one simulation
overlaid potentials: superposition of multiple pair potentials
</P>
<H4>Atom creation
</H4>
<P>(<A HREF = "read_data.html">read_data</A>, <A HREF = "lattice.html">lattice</A>,
<A HREF = "create_atoms.html">create_atoms</A>, <A HREF = "delete_atoms.html">delete_atoms</A>,
<A HREF = "displace_atoms.html">displace_atoms</A>, <A HREF = "replicate.html">replicate</A> commands)
</P>
<UL><LI> read in atom coords from files
<LI> create atoms on one or more lattices (e.g. grain boundaries)
<LI> delete geometric or logical groups of atoms (e.g. voids)
<LI> replicate existing atoms multiple times
<LI> displace atoms
</UL>
<H4>Ensembles, constraints, and boundary conditions
</H4>
<P>(<A HREF = "fix.html">fix</A> command)
</P>
<UL><LI> 2d or 3d systems
<LI> orthogonal or non-orthogonal (triclinic symmetry) simulation domains
<LI> constant NVE, NVT, NPT, NPH, Parinello/Rahman integrators
<LI> thermostatting options for groups and geometric regions of atoms
<LI> pressure control via Nose/Hoover or Berendsen barostatting in 1 to 3 dimensions
<LI> simulation box deformation (tensile and shear)
<LI> harmonic (umbrella) constraint forces
<LI> rigid body constraints
<LI> SHAKE bond and angle constraints
<LI> bond breaking, formation, swapping
<LI> walls of various kinds
<LI> non-equilibrium molecular dynamics (NEMD)
<LI> variety of additional boundary conditions and constraints
</UL>
<H4>Integrators
</H4>
<P>(<A HREF = "run.html">run</A>, <A HREF = "run_style.html">run_style</A>, <A HREF = "minimize.html">minimize</A> commands)
</P>
<UL><LI> velocity-Verlet integrator
<LI> Brownian dynamics
<LI> rigid body integration
<LI> energy minimization via conjugate gradient or steepest descent relaxation
<LI> rRESPA hierarchical timestepping
</UL>
<H4>Diagnostics
</H4>
<UL><LI> see the various flavors of the <A HREF = "fix.html">fix</A> and <A HREF = "compute.html">compute</A> commands
</UL>
<H4>Output
</H4>
<P>(<A HREF = "dump.html">dump</A>, <A HREF = "restart.html">restart</A> commands)
</P>
<UL><LI> log file of thermodynamic info
<LI> text dump files of atom coords, velocities, other per-atom quantities
<LI> binary restart files
<LI> parallel I/O of dump and restart files
<LI> per-atom quantities (energy, stress, centro-symmetry parameter, CNA, etc)
<LI> user-defined system-wide (log file) or per-atom (dump file) calculations
<LI> spatial and time averaging of per-atom quantities
<LI> time averaging of system-wide quantities
<LI> atom snapshots in native, XYZ, XTC, DCD, CFG formats
</UL>
<H4>Multi-replica models
</H4>
<P><A HREF = "neb.html">nudged elastic band</A>
<A HREF = "prd.html">parallel replica dynamics</A>
<A HREF = "tad.html">temperature accelerated dynamics</A>
<A HREF = "temper.html">parallel tempering</A>
</P>
<H4>Pre- and post-processing
</H4>
<UL><LI>Various pre- and post-processing serial tools are packaged
with LAMMPS; see these <A HREF = "Section_tools.html">doc pages</A>.
<LI>Our group has also written and released a separate toolkit called
<A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A> which provides tools for doing setup, analysis,
plotting, and visualization for LAMMPS simulations. Pizza.py is
written in <A HREF = "http://www.python.org">Python</A> and is available for download from <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">the
Pizza.py WWW site</A>.
</UL>
<H4>Specialized features
</H4>
<P>These are LAMMPS capabilities which you may not think of as typical
molecular dynamics options:
</P>
<UL><LI><A HREF = "fix_srd.html">stochastic rotation dynamics (SRD)</A>
<LI><A HREF = "fix_imd.html">real-time visualization and interactive MD</A>
<LI><A HREF = "fix_atc.html">atom-to-continuum coupling</A> with finite elements
<LI>coupled rigid body integration via the <A HREF = "fix_poems.html">POEMS</A> library
<LI><A HREF = "doc/fix_gcmc.html">grand canonical Monte Carlo</A> insertions/deletions
<LI><A HREF = "pair_dsmc.html">Direct Simulation Monte Carlo</A> for low-density fluids
<LI><A HREF = "pair_peri.html">Peridynamics mesoscale modeling</A>
<LI><A HREF = "fix_tmd.html">targeted</A> and <A HREF = "fix_smd.html">steered</A> molecular dynamics
<LI><A HREF = "fix_ttm.html">two-temperature electron model</A>
</UL>
<HR>
<A NAME = "intro_3"></A><H4>1.3 LAMMPS non-features
</H4>
<P>LAMMPS is designed to efficiently compute Newton's equations of motion
for a system of interacting particles. Many of the tools needed to
pre- and post-process the data for such simulations are not included
in the LAMMPS kernel for several reasons:
</P>
<UL><LI>the desire to keep LAMMPS simple
<LI>they are not parallel operations
<LI>other codes already do them
<LI>limited development resources
</UL>
<P>Specifically, LAMMPS itself does not:
</P>
<UL><LI>run thru a GUI
<LI>build molecular systems
<LI>assign force-field coefficients automagically
<LI>perform sophisticated analyses of your MD simulation
<LI>visualize your MD simulation
<LI>plot your output data
</UL>
<P>A few tools for pre- and post-processing tasks are provided as part of
the LAMMPS package; they are described in <A HREF = "Section_tools.html">this
section</A>. However, many people use other codes or
write their own tools for these tasks.
</P>
<P>As noted above, our group has also written and released a separate
toolkit called <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A> which addresses some of the listed
bullets. It provides tools for doing setup, analysis, plotting, and
visualization for LAMMPS simulations. Pizza.py is written in
<A HREF = "http://www.python.org">Python</A> and is available for download from <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">the Pizza.py WWW
site</A>.
</P>
<P>LAMMPS requires as input a list of initial atom coordinates and types,
molecular topology information, and force-field coefficients assigned
to all atoms and bonds. LAMMPS will not build molecular systems and
assign force-field parameters for you.
</P>
<P>For atomic systems LAMMPS provides a <A HREF = "create_atoms.html">create_atoms</A>
command which places atoms on solid-state lattices (fcc, bcc,
user-defined, etc). Assigning small numbers of force field
coefficients can be done via the <A HREF = "pair_coeff.html">pair coeff</A>, <A HREF = "bond_coeff.html">bond
coeff</A>, <A HREF = "angle_coeff.html">angle coeff</A>, etc commands.
For molecular systems or more complicated simulation geometries, users
typically use another code as a builder and convert its output to
LAMMPS input format, or write their own code to generate atom
coordinate and molecular topology for LAMMPS to read in.
</P>
<P>For complicated molecular systems (e.g. a protein), a multitude of
topology information and hundreds of force-field coefficients must
typically be specified. We suggest you use a program like
<A HREF = "http://www.scripps.edu/brooks">CHARMM</A> or <A HREF = "http://amber.scripps.edu">AMBER</A> or other molecular builders to setup
such problems and dump its information to a file. You can then
reformat the file as LAMMPS input. Some of the tools in <A HREF = "Section_tools.html">this
section</A> can assist in this process.
</P>
<P>Similarly, LAMMPS creates output files in a simple format. Most users
post-process these files with their own analysis tools or re-format
them for input into other programs, including visualization packages.
If you are convinced you need to compute something on-the-fly as
-LAMMPS runs, see <A HREF = "Section_modify.html">this section</A> for a discussion
+LAMMPS runs, see <A HREF = "Section_modify.html">Section_modify</A> for a discussion
of how you can use the <A HREF = "dump.html">dump</A> and <A HREF = "compute.html">compute</A> and
<A HREF = "fix.html">fix</A> commands to print out data of your choosing. Keep in
mind that complicated computations can slow down the molecular
dynamics timestepping, particularly if the computations are not
parallel, so it is often better to leave such analysis to
post-processing codes.
</P>
<P>A very simple (yet fast) visualizer is provided with the LAMMPS
package - see the <A HREF = "Section_tools.html#xmovie">xmovie</A> tool in <A HREF = "Section_tools.html">this
section</A>. It creates xyz projection views of
atomic coordinates and animates them. We find it very useful for
debugging purposes. For high-quality visualization we recommend the
following packages:
</P>
<UL><LI><A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A>
<LI><A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A>
<LI><A HREF = "http://pymol.sourceforge.net">PyMol</A>
<LI><A HREF = "http://www.bmsc.washington.edu/raster3d/raster3d.html">Raster3d</A>
<LI><A HREF = "http://www.openrasmol.org">RasMol</A>
</UL>
<P>Other features that LAMMPS does not yet (and may never) support are
-discussed in <A HREF = "Section_history.html">this section</A>.
+discussed in <A HREF = "Section_history.html">Section_history</A>.
</P>
<P>Finally, these are freely-available molecular dynamics codes, most of
them parallel, which may be well-suited to the problems you want to
model. They can also be used in conjunction with LAMMPS to perform
complementary modeling tasks.
</P>
<UL><LI><A HREF = "http://www.scripps.edu/brooks">CHARMM</A>
<LI><A HREF = "http://amber.scripps.edu">AMBER</A>
<LI><A HREF = "http://www.ks.uiuc.edu/Research/namd/">NAMD</A>
<LI><A HREF = "http://www.emsl.pnl.gov/docs/nwchem/nwchem.html">NWCHEM</A>
<LI><A HREF = "http://www.cse.clrc.ac.uk/msi/software/DL_POLY">DL_POLY</A>
<LI><A HREF = "http://dasher.wustl.edu/tinker">Tinker</A>
</UL>
<P>CHARMM, AMBER, NAMD, NWCHEM, and Tinker are designed primarily for
modeling biological molecules. CHARMM and AMBER use
atom-decomposition (replicated-data) strategies for parallelism; NAMD
and NWCHEM use spatial-decomposition approaches, similar to LAMMPS.
Tinker is a serial code. DL_POLY includes potentials for a variety of
biological and non-biological materials; both a replicated-data and
spatial-decomposition version exist.
</P>
<HR>
<A NAME = "intro_4"></A><H4>1.4 Open source distribution
</H4>
<P>LAMMPS comes with no warranty of any kind. As each source file states
in its header, it is a copyrighted code that is distributed free-of-
charge, under the terms of the <A HREF = "http://www.gnu.org/copyleft/gpl.html">GNU Public License</A> (GPL). This
is often referred to as open-source distribution - see
<A HREF = "http://www.gnu.org">www.gnu.org</A> or <A HREF = "http://www.opensource.org">www.opensource.org</A> for more
details. The legal text of the GPL is in the LICENSE file that is
included in the LAMMPS distribution.
</P>
<P>Here is a summary of what the GPL means for LAMMPS users:
</P>
<P>(1) Anyone is free to use, modify, or extend LAMMPS in any way they
choose, including for commercial purposes.
</P>
<P>(2) If you distribute a modified version of LAMMPS, it must remain
open-source, meaning you distribute it under the terms of the GPL.
You should clearly annotate such a code as a derivative version of
LAMMPS.
</P>
<P>(3) If you release any code that includes LAMMPS source code, then it
must also be open-sourced, meaning you distribute it under the terms
of the GPL.
</P>
<P>(4) If you give LAMMPS files to someone else, the GPL LICENSE file and
source file headers (including the copyright and GPL notices) should
remain part of the code.
</P>
<P>In the spirit of an open-source code, these are various ways you can
contribute to making LAMMPS better. You can send email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A> on any of these
items.
</P>
<UL><LI>Point prospective users to the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>. Mention it in
talks or link to it from your WWW site.
<LI>If you find an error or omission in this manual or on the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
Site</A>, or have a suggestion for something to clarify or include,
send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
-<LI>If you find a bug, <A HREF = "Section_errors.html#err_2">this section</A> describes
-how to report it.
+<LI>If you find a bug, <A HREF = "Section_errors.html#err_2">Section_errors 2</A>
+describes how to report it.
<LI>If you publish a paper using LAMMPS results, send the citation (and
any cool pictures or movies if you like) to add to the Publications,
Pictures, and Movies pages of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>, with links
and attributions back to you.
<LI>Create a new Makefile.machine that can be added to the src/MAKE
directory.
<LI>The tools sub-directory of the LAMMPS distribution has various
stand-alone codes for pre- and post-processing of LAMMPS data. More
-details are given in <A HREF = "Section_tools.html">this section</A>. If you write
+details are given in <A HREF = "Section_tools.html">Section_tools</A>. If you write
a new tool that users will find useful, it can be added to the LAMMPS
distribution.
<LI>LAMMPS is designed to be easy to extend with new code for features
like potentials, boundary conditions, diagnostic computations, etc.
<A HREF = "Section_modify.html">This section</A> gives details. If you add a
feature of general interest, it can be added to the LAMMPS
distribution.
<LI>The Benchmark page of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> lists LAMMPS
performance on various platforms. The files needed to run the
benchmarks are part of the LAMMPS distribution. If your machine is
sufficiently different from those listed, your timing data can be
added to the page.
<LI>You can send feedback for the User Comments page of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
Site</A>. It might be added to the page. No promises.
<LI>Cash. Small denominations, unmarked bills preferred. Paper sack OK.
Leave on desk. VISA also accepted. Chocolate chip cookies
encouraged.
</UL>
<HR>
<H4><A NAME = "intro_5"></A>1.5 Acknowledgments and citations
</H4>
<P>LAMMPS development has been funded by the <A HREF = "http://www.doe.gov">US Department of
Energy</A> (DOE), through its CRADA, LDRD, ASCI, and Genomes-to-Life
programs and its <A HREF = "http://www.sc.doe.gov/ascr/home.html">OASCR</A> and <A HREF = "http://www.er.doe.gov/production/ober/ober_top.html">OBER</A> offices.
</P>
<P>Specifically, work on the latest version was funded in part by the US
Department of Energy's Genomics:GTL program
(<A HREF = "http://www.doegenomestolife.org">www.doegenomestolife.org</A>) under the <A HREF = "http://www.genomes2life.org">project</A>, "Carbon
Sequestration in Synechococcus Sp.: From Molecular Machines to
Hierarchical Modeling".
</P>
<P>The following paper describe the basic parallel algorithms used in
LAMMPS. If you use LAMMPS results in your published work, please cite
this paper and include a pointer to the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>
(http://lammps.sandia.gov):
</P>
<P>S. J. Plimpton, <B>Fast Parallel Algorithms for Short-Range Molecular
Dynamics</B>, J Comp Phys, 117, 1-19 (1995).
</P>
<P>Other papers describing specific algorithms used in LAMMPS are listed
under the <A HREF = "http://lammps.sandia.gov/cite.html">Citing LAMMPS link</A> of
the LAMMPS WWW page.
</P>
<P>The <A HREF = "http://lammps.sandia.gov/papers.html">Publications link</A> on the
LAMMPS WWW page lists papers that have cited LAMMPS. If your paper is
not listed there for some reason, feel free to send us the info. If
the simulations in your paper produced cool pictures or animations,
we'll be pleased to add them to the
<A HREF = "http://lammps.sandia.gov/pictures.html">Pictures</A> or
<A HREF = "http://lammps.sandia.gov/movies.html">Movies</A> pages of the LAMMPS WWW
site.
</P>
<P>The core group of LAMMPS developers is at Sandia National Labs:
</P>
<UL><LI>Steve Plimpton, sjplimp at sandia.gov
<LI>Aidan Thompson, athomps at sandia.gov
<LI>Paul Crozier, pscrozi at sandia.gov
</UL>
<P>The following folks are responsible for significant contributions to
the code, or other aspects of the LAMMPS development effort. Many of
the packages they have written are somewhat unique to LAMMPS and the
code would not be as general-purpose as it is without their expertise
and efforts.
</P>
<UL><LI>Axel Kohlmeyer (Temple U), akohlmey at gmail.com, SVN and Git repositories, indefatigable mail list responder, USER-CG-CMM and USER-OMP packages
<LI>Roy Pollock (LLNL), Ewald and PPPM solvers
<LI>Mike Brown (ORNL), brownw at ornl.gov, GPU package
<LI>Greg Wagner (Sandia), gjwagne at sandia.gov, MEAM package for MEAM potential
<LI>Mike Parks (Sandia), mlparks at sandia.gov, PERI package for Peridynamics
<LI>Rudra Mukherjee (JPL), Rudranarayan.M.Mukherjee at jpl.nasa.gov, POEMS package for articulated rigid body motion
<LI>Reese Jones (Sandia) and collaborators, rjones at sandia.gov, USER-ATC package for atom/continuum coupling
<LI>Ilya Valuev (JIHT), valuev at physik.hu-berlin.de, USER-AWPMD package for wave-packet MD
<LI>Christian Trott (U Tech Ilmenau), christian.trott at tu-ilmenau.de, USER-CUDA package
<LI>Andres Jaramillo-Botero (Caltech), ajaramil at wag.caltech.edu, USER-EFF package for electron force field
<LI>Pieter in' t Veld (BASF), pieter.intveld at basf.com, USER-EWALDN package for 1/r^N long-range solvers
<LI>Christoph Kloss (JKU), Christoph.Kloss at jku.at, USER-LIGGGHTS package for granular models and granular/fluid coupling
<LI>Metin Aktulga (LBL), hmaktulga at lbl.gov, USER-REAXC package for C version of ReaxFF
<LI>Georg Gunzenmuller (EMI), georg.ganzenmueller at emi.fhg.de, USER-SPH package
</UL>
-<P>As discussed in <A HREF = "Section_history.html">this section</A>, LAMMPS originated
-as a cooperative project between DOE labs and industrial
+<P>As discussed in <A HREF = "Section_history.html">Section_history</A>, LAMMPS
+originated as a cooperative project between DOE labs and industrial
partners. Folks involved in the design and testing of the original
version of LAMMPS were the following:
</P>
<UL><LI>John Carpenter (Mayo Clinic, formerly at Cray Research)
<LI>Terry Stouch (Lexicon Pharmaceuticals, formerly at Bristol Myers Squibb)
<LI>Steve Lustig (Dupont)
<LI>Jim Belak (LLNL)
</UL>
</HTML>
diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt
index 2ceb4f78d..bebab7a73 100644
--- a/doc/Section_intro.txt
+++ b/doc/Section_intro.txt
@@ -1,523 +1,525 @@
"Previous Section"_Manual.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_start.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
1. Introduction :h3
-These sections provide an overview of what LAMMPS can and can't do,
-describe what it means for LAMMPS to be an open-source code, and
-acknowledge the funding and people who have contributed to LAMMPS over
-the years.
+This section provides an overview of what LAMMPS can and can't do,
+describes what it means for LAMMPS to be an open-source code, and
+acknowledges the funding and people who have contributed to LAMMPS
+over the years.
1.1 "What is LAMMPS"_#intro_1
1.2 "LAMMPS features"_#intro_2
1.3 "LAMMPS non-features"_#intro_3
1.4 "Open source distribution"_#intro_4
1.5 "Acknowledgments and citations"_#intro_5 :all(b)
+:line
:line
1.1 What is LAMMPS :link(intro_1),h4
LAMMPS is a classical molecular dynamics code that models an ensemble
of particles in a liquid, solid, or gaseous state. It can model
atomic, polymeric, biological, metallic, granular, and coarse-grained
systems using a variety of force fields and boundary conditions.
For examples of LAMMPS simulations, see the Publications page of the
"LAMMPS WWW Site"_lws.
LAMMPS runs efficiently on single-processor desktop or laptop
machines, but is designed for parallel computers. It will run on any
parallel machine that compiles C++ and supports the "MPI"_mpi
message-passing library. This includes distributed- or shared-memory
parallel machines and Beowulf-style clusters.
:link(mpi,http://www-unix.mcs.anl.gov/mpi)
LAMMPS can model systems with only a few particles up to millions or
-billions. See "this section"_Section_perf.html for information on LAMMPS
-performance and scalability, or the Benchmarks section of the "LAMMPS
-WWW Site"_lws.
+billions. See "Section_perf"_Section_perf.html for information on
+LAMMPS performance and scalability, or the Benchmarks section of the
+"LAMMPS WWW Site"_lws.
LAMMPS is a freely-available open-source code, distributed under the
terms of the "GNU Public License"_gnu, which means you can use or
-modify the code however you wish. See "this section"_#intro_4 for a brief
-discussion of the open-source philosophy.
+modify the code however you wish. See "this section"_#intro_4 for a
+brief discussion of the open-source philosophy.
:link(gnu,http://www.gnu.org/copyleft/gpl.html)
LAMMPS is designed to be easy to modify or extend with new
capabilities, such as new force fields, atom types, boundary
-conditions, or diagnostics. See "this section"_Section_modify.html for
-more details.
+conditions, or diagnostics. See "Section_modify"_Section_modify.html
+for more details.
The current version of LAMMPS is written in C++. Earlier versions
-were written in F77 and F90. See "this section"_Section_history.html
-for more information on different versions. All versions can be
-downloaded from the "LAMMPS WWW Site"_lws.
+were written in F77 and F90. See
+"Section_history"_Section_history.html for more information on
+different versions. All versions can be downloaded from the "LAMMPS
+WWW Site"_lws.
LAMMPS was originally developed under a US Department of Energy CRADA
(Cooperative Research and Development Agreement) between two DOE labs
and 3 companies. It is distributed by "Sandia National Labs"_snl.
See "this section"_#intro_5 for more information on LAMMPS funding and
individuals who have contributed to LAMMPS.
:link(snl,http://www.sandia.gov)
In the most general sense, LAMMPS integrates Newton's equations of
motion for collections of atoms, molecules, or macroscopic particles
that interact via short- or long-range forces with a variety of
initial and/or boundary conditions. For computational efficiency
LAMMPS uses neighbor lists to keep track of nearby particles. The
lists are optimized for systems with particles that are repulsive at
short distances, so that the local density of particles never becomes
too large. On parallel machines, LAMMPS uses spatial-decomposition
techniques to partition the simulation domain into small 3d
sub-domains, one of which is assigned to each processor. Processors
communicate and store "ghost" atom information for atoms that border
their sub-domain. LAMMPS is most efficient (in a parallel sense) for
systems whose particles fill a 3d rectangular box with roughly uniform
density. Papers with technical details of the algorithms used in
LAMMPS are listed in "this section"_#intro_5.
:line
1.2 LAMMPS features :link(intro_2),h4
This section highlights LAMMPS features, with pointers to specific
commands which give more details. If LAMMPS doesn't have your
favorite interatomic potential, boundary condition, or atom type, see
-"this section"_Section_modify.html, which describes how you can add it to
-LAMMPS.
+"Section_modify"_Section_modify.html, which describes how you can add
+it to LAMMPS.
General features :h4
runs on a single processor or in parallel
distributed-memory message-passing parallelism (MPI)
spatial-decomposition of simulation domain for parallelism
open-source distribution
highly portable C++
optional libraries used: MPI and single-processor FFT
easy to extend with new features and functionality
runs from an input script
syntax for defining and using variables and formulas
syntax for looping over runs and breaking out of loops
run one or multiple simulations simultaneously (in parallel) from one script
build as library, invoke LAMMPS thru library interface or provided Python wrapper
couple with other codes: LAMMPS calls other code, other code calls LAMMPS, umbrella code calls both :ul
Particle and model types :h4
("atom style"_atom_style.html command)
atoms
coarse-grained particles (e.g. bead-spring polymers)
united-atom polymers or organic molecules
all-atom polymers, organic molecules, proteins, DNA
metals
granular materials
coarse-grained mesoscale models
finite-size spherical and ellipsoidal particles
finite-size line segment (2d) and triangle (3d) particles
point dipolar particles
rigid collections of particles
hybrid combinations of these :ul
Force fields :h4
("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, "kspace style"_kspace_style.html
commands)
pairwise potentials: Lennard-Jones, Buckingham, Morse, Born-Mayer-Huggins, \
Yukawa, soft, class 2 (COMPASS), hydrogen bond, tabulated
charged pairwise potentials: Coulombic, point-dipole
manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM), \
embedded ion method (EIM), EDIP, ADP, Stillinger-Weber, Tersoff, REBO, AIREBO, ReaxFF, COMB
electron force field (eFF, AWPMD)
coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO
mesoscopic potentials: granular, Peridynamics, SPH
bond potentials: harmonic, FENE, Morse, nonlinear, class 2, \
quartic (breakable)
angle potentials: harmonic, CHARMM, cosine, cosine/squared, cosine/periodic, \
class 2 (COMPASS)
dihedral potentials: harmonic, CHARMM, multi-harmonic, helix, \
class 2 (COMPASS), OPLS
improper potentials: harmonic, cvff, umbrella, class 2 (COMPASS)
polymer potentials: all-atom, united-atom, bead-spring, breakable
water potentials: TIP3P, TIP4P, SPC
implicit solvent potentials: hydrodynamic lubrication, Debye
- long-range Coulombics and dispersion: Ewald, \
+ long-range Coulombics and dispersion: Ewald, Wolf, \
PPPM (similar to particle-mesh Ewald), Ewald/N for long-range Lennard-Jones
force-field compatibility with common CHARMM, AMBER, DREIDING, OPLS, GROMACS, COMPASS options
handful of GPU-enabled pair styles :ul
hybrid potentials: multiple pair, bond, angle, dihedral, improper \
potentials can be used in one simulation
overlaid potentials: superposition of multiple pair potentials
Atom creation :h4
("read_data"_read_data.html, "lattice"_lattice.html,
"create_atoms"_create_atoms.html, "delete_atoms"_delete_atoms.html,
"displace_atoms"_displace_atoms.html, "replicate"_replicate.html commands)
read in atom coords from files
create atoms on one or more lattices (e.g. grain boundaries)
delete geometric or logical groups of atoms (e.g. voids)
replicate existing atoms multiple times
displace atoms :ul
Ensembles, constraints, and boundary conditions :h4
("fix"_fix.html command)
2d or 3d systems
orthogonal or non-orthogonal (triclinic symmetry) simulation domains
constant NVE, NVT, NPT, NPH, Parinello/Rahman integrators
thermostatting options for groups and geometric regions of atoms
pressure control via Nose/Hoover or Berendsen barostatting in 1 to 3 dimensions
simulation box deformation (tensile and shear)
harmonic (umbrella) constraint forces
rigid body constraints
SHAKE bond and angle constraints
bond breaking, formation, swapping
walls of various kinds
non-equilibrium molecular dynamics (NEMD)
variety of additional boundary conditions and constraints :ul
Integrators :h4
("run"_run.html, "run_style"_run_style.html, "minimize"_minimize.html commands)
velocity-Verlet integrator
Brownian dynamics
rigid body integration
energy minimization via conjugate gradient or steepest descent relaxation
rRESPA hierarchical timestepping :ul
Diagnostics :h4
see the various flavors of the "fix"_fix.html and "compute"_compute.html commands :ul
Output :h4
("dump"_dump.html, "restart"_restart.html commands)
log file of thermodynamic info
text dump files of atom coords, velocities, other per-atom quantities
binary restart files
parallel I/O of dump and restart files
per-atom quantities (energy, stress, centro-symmetry parameter, CNA, etc)
user-defined system-wide (log file) or per-atom (dump file) calculations
spatial and time averaging of per-atom quantities
time averaging of system-wide quantities
atom snapshots in native, XYZ, XTC, DCD, CFG formats :ul
Multi-replica models :h4
"nudged elastic band"_neb.html
"parallel replica dynamics"_prd.html
"temperature accelerated dynamics"_tad.html
"parallel tempering"_temper.html
Pre- and post-processing :h4
Various pre- and post-processing serial tools are packaged
with LAMMPS; see these "doc pages"_Section_tools.html. :ulb,l
Our group has also written and released a separate toolkit called
"Pizza.py"_pizza which provides tools for doing setup, analysis,
plotting, and visualization for LAMMPS simulations. Pizza.py is
written in "Python"_python and is available for download from "the
Pizza.py WWW site"_pizza. :l,ule
:link(pizza,http://www.sandia.gov/~sjplimp/pizza.html)
:link(python,http://www.python.org)
Specialized features :h4
These are LAMMPS capabilities which you may not think of as typical
molecular dynamics options:
"stochastic rotation dynamics (SRD)"_fix_srd.html
"real-time visualization and interactive MD"_fix_imd.html
"atom-to-continuum coupling"_fix_atc.html with finite elements
coupled rigid body integration via the "POEMS"_fix_poems.html library
"grand canonical Monte Carlo"_doc/fix_gcmc.html insertions/deletions
"Direct Simulation Monte Carlo"_pair_dsmc.html for low-density fluids
"Peridynamics mesoscale modeling"_pair_peri.html
"targeted"_fix_tmd.html and "steered"_fix_smd.html molecular dynamics
"two-temperature electron model"_fix_ttm.html :ul
:line
1.3 LAMMPS non-features :link(intro_3),h4
LAMMPS is designed to efficiently compute Newton's equations of motion
for a system of interacting particles. Many of the tools needed to
pre- and post-process the data for such simulations are not included
in the LAMMPS kernel for several reasons:
the desire to keep LAMMPS simple
they are not parallel operations
other codes already do them
limited development resources :ul
Specifically, LAMMPS itself does not:
run thru a GUI
build molecular systems
assign force-field coefficients automagically
perform sophisticated analyses of your MD simulation
visualize your MD simulation
plot your output data :ul
A few tools for pre- and post-processing tasks are provided as part of
the LAMMPS package; they are described in "this
section"_Section_tools.html. However, many people use other codes or
write their own tools for these tasks.
As noted above, our group has also written and released a separate
toolkit called "Pizza.py"_pizza which addresses some of the listed
bullets. It provides tools for doing setup, analysis, plotting, and
visualization for LAMMPS simulations. Pizza.py is written in
"Python"_python and is available for download from "the Pizza.py WWW
site"_pizza.
LAMMPS requires as input a list of initial atom coordinates and types,
molecular topology information, and force-field coefficients assigned
to all atoms and bonds. LAMMPS will not build molecular systems and
assign force-field parameters for you.
For atomic systems LAMMPS provides a "create_atoms"_create_atoms.html
command which places atoms on solid-state lattices (fcc, bcc,
user-defined, etc). Assigning small numbers of force field
coefficients can be done via the "pair coeff"_pair_coeff.html, "bond
coeff"_bond_coeff.html, "angle coeff"_angle_coeff.html, etc commands.
For molecular systems or more complicated simulation geometries, users
typically use another code as a builder and convert its output to
LAMMPS input format, or write their own code to generate atom
coordinate and molecular topology for LAMMPS to read in.
For complicated molecular systems (e.g. a protein), a multitude of
topology information and hundreds of force-field coefficients must
typically be specified. We suggest you use a program like
"CHARMM"_charmm or "AMBER"_amber or other molecular builders to setup
such problems and dump its information to a file. You can then
reformat the file as LAMMPS input. Some of the tools in "this
section"_Section_tools.html can assist in this process.
Similarly, LAMMPS creates output files in a simple format. Most users
post-process these files with their own analysis tools or re-format
them for input into other programs, including visualization packages.
If you are convinced you need to compute something on-the-fly as
-LAMMPS runs, see "this section"_Section_modify.html for a discussion
+LAMMPS runs, see "Section_modify"_Section_modify.html for a discussion
of how you can use the "dump"_dump.html and "compute"_compute.html and
"fix"_fix.html commands to print out data of your choosing. Keep in
mind that complicated computations can slow down the molecular
dynamics timestepping, particularly if the computations are not
parallel, so it is often better to leave such analysis to
post-processing codes.
A very simple (yet fast) visualizer is provided with the LAMMPS
package - see the "xmovie"_Section_tools.html#xmovie tool in "this
section"_Section_tools.html. It creates xyz projection views of
atomic coordinates and animates them. We find it very useful for
debugging purposes. For high-quality visualization we recommend the
following packages:
"VMD"_http://www.ks.uiuc.edu/Research/vmd
"AtomEye"_http://mt.seas.upenn.edu/Archive/Graphics/A
"PyMol"_http://pymol.sourceforge.net
"Raster3d"_http://www.bmsc.washington.edu/raster3d/raster3d.html
"RasMol"_http://www.openrasmol.org :ul
Other features that LAMMPS does not yet (and may never) support are
-discussed in "this section"_Section_history.html.
+discussed in "Section_history"_Section_history.html.
Finally, these are freely-available molecular dynamics codes, most of
them parallel, which may be well-suited to the problems you want to
model. They can also be used in conjunction with LAMMPS to perform
complementary modeling tasks.
"CHARMM"_charmm
"AMBER"_amber
"NAMD"_namd
"NWCHEM"_nwchem
"DL_POLY"_dlpoly
"Tinker"_tinker :ul
:link(charmm,http://www.scripps.edu/brooks)
:link(amber,http://amber.scripps.edu)
:link(namd,http://www.ks.uiuc.edu/Research/namd/)
:link(nwchem,http://www.emsl.pnl.gov/docs/nwchem/nwchem.html)
:link(dlpoly,http://www.cse.clrc.ac.uk/msi/software/DL_POLY)
:link(tinker,http://dasher.wustl.edu/tinker)
CHARMM, AMBER, NAMD, NWCHEM, and Tinker are designed primarily for
modeling biological molecules. CHARMM and AMBER use
atom-decomposition (replicated-data) strategies for parallelism; NAMD
and NWCHEM use spatial-decomposition approaches, similar to LAMMPS.
Tinker is a serial code. DL_POLY includes potentials for a variety of
biological and non-biological materials; both a replicated-data and
spatial-decomposition version exist.
:line
1.4 Open source distribution :link(intro_4),h4
LAMMPS comes with no warranty of any kind. As each source file states
in its header, it is a copyrighted code that is distributed free-of-
charge, under the terms of the "GNU Public License"_gnu (GPL). This
is often referred to as open-source distribution - see
"www.gnu.org"_gnuorg or "www.opensource.org"_opensource for more
details. The legal text of the GPL is in the LICENSE file that is
included in the LAMMPS distribution.
:link(gnuorg,http://www.gnu.org)
:link(opensource,http://www.opensource.org)
Here is a summary of what the GPL means for LAMMPS users:
(1) Anyone is free to use, modify, or extend LAMMPS in any way they
choose, including for commercial purposes.
(2) If you distribute a modified version of LAMMPS, it must remain
open-source, meaning you distribute it under the terms of the GPL.
You should clearly annotate such a code as a derivative version of
LAMMPS.
(3) If you release any code that includes LAMMPS source code, then it
must also be open-sourced, meaning you distribute it under the terms
of the GPL.
(4) If you give LAMMPS files to someone else, the GPL LICENSE file and
source file headers (including the copyright and GPL notices) should
remain part of the code.
In the spirit of an open-source code, these are various ways you can
contribute to making LAMMPS better. You can send email to the
"developers"_http://lammps.sandia.gov/authors.html on any of these
items.
Point prospective users to the "LAMMPS WWW Site"_lws. Mention it in
talks or link to it from your WWW site. :ulb,l
If you find an error or omission in this manual or on the "LAMMPS WWW
Site"_lws, or have a suggestion for something to clarify or include,
send an email to the
"developers"_http://lammps.sandia.gov/authors.html. :l
-If you find a bug, "this section"_Section_errors.html#err_2 describes
-how to report it. :l
+If you find a bug, "Section_errors 2"_Section_errors.html#err_2
+describes how to report it. :l
If you publish a paper using LAMMPS results, send the citation (and
any cool pictures or movies if you like) to add to the Publications,
Pictures, and Movies pages of the "LAMMPS WWW Site"_lws, with links
and attributions back to you. :l
Create a new Makefile.machine that can be added to the src/MAKE
directory. :l
The tools sub-directory of the LAMMPS distribution has various
stand-alone codes for pre- and post-processing of LAMMPS data. More
-details are given in "this section"_Section_tools.html. If you write
+details are given in "Section_tools"_Section_tools.html. If you write
a new tool that users will find useful, it can be added to the LAMMPS
distribution. :l
LAMMPS is designed to be easy to extend with new code for features
like potentials, boundary conditions, diagnostic computations, etc.
"This section"_Section_modify.html gives details. If you add a
feature of general interest, it can be added to the LAMMPS
distribution. :l
The Benchmark page of the "LAMMPS WWW Site"_lws lists LAMMPS
performance on various platforms. The files needed to run the
benchmarks are part of the LAMMPS distribution. If your machine is
sufficiently different from those listed, your timing data can be
added to the page. :l
You can send feedback for the User Comments page of the "LAMMPS WWW
Site"_lws. It might be added to the page. No promises. :l
Cash. Small denominations, unmarked bills preferred. Paper sack OK.
Leave on desk. VISA also accepted. Chocolate chip cookies
encouraged. :ule,l
:line
1.5 Acknowledgments and citations :h4,link(intro_5)
LAMMPS development has been funded by the "US Department of
Energy"_doe (DOE), through its CRADA, LDRD, ASCI, and Genomes-to-Life
programs and its "OASCR"_oascr and "OBER"_ober offices.
Specifically, work on the latest version was funded in part by the US
Department of Energy's Genomics:GTL program
("www.doegenomestolife.org"_gtl) under the "project"_ourgtl, "Carbon
Sequestration in Synechococcus Sp.: From Molecular Machines to
Hierarchical Modeling".
:link(doe,http://www.doe.gov)
:link(gtl,http://www.doegenomestolife.org)
:link(ourgtl,http://www.genomes2life.org)
:link(oascr,http://www.sc.doe.gov/ascr/home.html)
:link(ober,http://www.er.doe.gov/production/ober/ober_top.html)
The following paper describe the basic parallel algorithms used in
LAMMPS. If you use LAMMPS results in your published work, please cite
this paper and include a pointer to the "LAMMPS WWW Site"_lws
(http://lammps.sandia.gov):
S. J. Plimpton, [Fast Parallel Algorithms for Short-Range Molecular
Dynamics], J Comp Phys, 117, 1-19 (1995).
Other papers describing specific algorithms used in LAMMPS are listed
under the "Citing LAMMPS link"_http://lammps.sandia.gov/cite.html of
the LAMMPS WWW page.
The "Publications link"_http://lammps.sandia.gov/papers.html on the
LAMMPS WWW page lists papers that have cited LAMMPS. If your paper is
not listed there for some reason, feel free to send us the info. If
the simulations in your paper produced cool pictures or animations,
we'll be pleased to add them to the
"Pictures"_http://lammps.sandia.gov/pictures.html or
"Movies"_http://lammps.sandia.gov/movies.html pages of the LAMMPS WWW
site.
The core group of LAMMPS developers is at Sandia National Labs:
Steve Plimpton, sjplimp at sandia.gov
Aidan Thompson, athomps at sandia.gov
Paul Crozier, pscrozi at sandia.gov :ul
The following folks are responsible for significant contributions to
the code, or other aspects of the LAMMPS development effort. Many of
the packages they have written are somewhat unique to LAMMPS and the
code would not be as general-purpose as it is without their expertise
and efforts.
Axel Kohlmeyer (Temple U), akohlmey at gmail.com, SVN and Git repositories, indefatigable mail list responder, USER-CG-CMM and USER-OMP packages
Roy Pollock (LLNL), Ewald and PPPM solvers
Mike Brown (ORNL), brownw at ornl.gov, GPU package
Greg Wagner (Sandia), gjwagne at sandia.gov, MEAM package for MEAM potential
Mike Parks (Sandia), mlparks at sandia.gov, PERI package for Peridynamics
Rudra Mukherjee (JPL), Rudranarayan.M.Mukherjee at jpl.nasa.gov, POEMS package for articulated rigid body motion
Reese Jones (Sandia) and collaborators, rjones at sandia.gov, USER-ATC package for atom/continuum coupling
Ilya Valuev (JIHT), valuev at physik.hu-berlin.de, USER-AWPMD package for wave-packet MD
Christian Trott (U Tech Ilmenau), christian.trott at tu-ilmenau.de, USER-CUDA package
Andres Jaramillo-Botero (Caltech), ajaramil at wag.caltech.edu, USER-EFF package for electron force field
Pieter in' t Veld (BASF), pieter.intveld at basf.com, USER-EWALDN package for 1/r^N long-range solvers
Christoph Kloss (JKU), Christoph.Kloss at jku.at, USER-LIGGGHTS package for granular models and granular/fluid coupling
Metin Aktulga (LBL), hmaktulga at lbl.gov, USER-REAXC package for C version of ReaxFF
Georg Gunzenmuller (EMI), georg.ganzenmueller at emi.fhg.de, USER-SPH package :ul
-As discussed in "this section"_Section_history.html, LAMMPS originated
-as a cooperative project between DOE labs and industrial
+As discussed in "Section_history"_Section_history.html, LAMMPS
+originated as a cooperative project between DOE labs and industrial
partners. Folks involved in the design and testing of the original
version of LAMMPS were the following:
John Carpenter (Mayo Clinic, formerly at Cray Research)
Terry Stouch (Lexicon Pharmaceuticals, formerly at Bristol Myers Squibb)
Steve Lustig (Dupont)
Jim Belak (LLNL) :ul
diff --git a/doc/Section_modify.html b/doc/Section_modify.html
index 8e217b40f..8a5604d16 100644
--- a/doc/Section_modify.html
+++ b/doc/Section_modify.html
@@ -1,668 +1,664 @@
<HTML>
<CENTER><A HREF = "Section_tools.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> -
<A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_python.html">Next
Section</A>
</CENTER>
<HR>
<H3>10. Modifying & extending LAMMPS
</H3>
+<P>This section describes how to customize LAMMPS by modifying
+and extending its source code.
+</P>
+10.1 <A HREF = "#mod_1">Atom styles</A><BR>
+10.2 <A HREF = "#mod_2">Bond, angle, dihedral, improper potentials</A><BR>
+10.3 <A HREF = "#mod_3">Compute styles</A><BR>
+10.4 <A HREF = "#mod_4">Dump styles</A><BR>
+10.5 <A HREF = "#mod_5">Dump custom output options</A><BR>
+10.6 <A HREF = "#mod_6">Fix styles</A> which include integrators, temperature and pressure control, force constraints, boundary conditions, diagnostic output, etc<BR>
+10.7 <A HREF = "mod_7">Input script commands</A><BR>
+10.8 <A HREF = "#mod_8">Kspace computations</A><BR>
+10.9 <A HREF = "#mod_9">Minimization styles</A><BR>
+10.10 <A HREF = "#mod_10">Pairwise potentials</A><BR>
+10.11 <A HREF = "#mod_11">Region styles</A><BR>
+10.12 <A HREF = "#mod_12">Thermodynamic output options</A><BR>
+10.13 <A HREF = "#mod_13">Variable options</A><BR>
+10.14 <A HREF = "#mod_14">Submitting new features for inclusion in LAMMPS</A> <BR>
+
<P>LAMMPS is designed in a modular fashion so as to be easy to modify and
extend with new functionality. In fact, about 75% of its source code
is files added in this fashion.
</P>
<P>In this section, changes and additions users can make are listed along
with minimal instructions. If you add a new feature to LAMMPS and
think it will be of interest to general users, we encourage you to
submit it to the developers for inclusion in the released version of
LAMMPS. Information about how to do this is provided
<A HREF = "#mod_14">below</A>.
</P>
<P>The best way to add a new feature is to find a similar feature in
LAMMPS and look at the corresponding source and header files to figure
out what it does. You will need some knowledge of C++ to be able to
understand the hi-level structure of LAMMPS and its class
organization, but functions (class methods) that do actual
computations are written in vanilla C-style code and operate on simple
C-style data structures (vectors and arrays).
</P>
<P>Most of the new features described in this section require you to
write a new C++ derived class (except for exceptions described below,
where you can make small edits to existing files). Creating a new
class requires 2 files, a source code file (*.cpp) and a header file
(*.h). The derived class must provide certain methods to work as a
new option. Depending on how different your new feature is compared
to existing features, you can either derive from the base class
itself, or from a derived class that already exists. Enabling LAMMPS
to invoke the new class is as simple as putting the two source
files in the src dir and re-building LAMMPS.
</P>
<P>The advantage of C++ and its object-orientation is that all the code
and variables needed to define the new feature are in the 2 files you
write, and thus shouldn't make the rest of LAMMPS more complex or
cause side-effect bugs.
</P>
<P>Here is a concrete example. Suppose you write 2 files pair_foo.cpp
and pair_foo.h that define a new class PairFoo that computes pairwise
potentials described in the classic 1997 <A HREF = "#Foo">paper</A> by Foo, et al.
If you wish to invoke those potentials in a LAMMPS input script with a
command like
</P>
<PRE>pair_style foo 0.1 3.5
</PRE>
<P>then your pair_foo.h file should be structured as follows:
</P>
<PRE>#ifdef PAIR_CLASS
PairStyle(foo,PairFoo)
#else
...
(class definition for PairFoo)
...
#endif
</PRE>
<P>where "foo" is the style keyword in the pair_style command, and
PairFoo is the class name defined in your pair_foo.cpp and pair_foo.h
files.
</P>
<P>When you re-build LAMMPS, your new pairwise potential becomes part of
the executable and can be invoked with a pair_style command like the
example above. Arguments like 0.1 and 3.5 can be defined and
processed by your new class.
</P>
<P>As illustrated by this pairwise example, many kinds of options are
referred to in the LAMMPS documentation as the "style" of a particular
command.
</P>
<P>The instructions below give the header file for the base class that
these styles are derived from. Public variables in that file are ones
used and set by the derived classes which are also used by the base
class. Sometimes they are also used by the rest of LAMMPS. Virtual
functions in the base class header file which are set = 0 are ones you
must define in your new derived class to give it the functionality
LAMMPS expects. Virtual functions that are not set to 0 are functions
you can optionally define.
</P>
<P>Additionally, new output options can be added directly to the
thermo.cpp, dump_custom.cpp, and variable.cpp files as explained
below.
</P>
-<HR>
-
<P>Here are additional guidelines for modifying LAMMPS and adding new
functionality:
</P>
<UL><LI>Think about whether what you want to do would be better as a pre- or
post-processing step. Many computations are more easily and more
quickly done that way.
<LI>Don't do anything within the timestepping of a run that isn't
parallel. E.g. don't accumulate a bunch of data on a single processor
and analyze it. You run the risk of seriously degrading the parallel
efficiency.
<LI>If your new feature reads arguments or writes output, make sure you
follow the unit conventions discussed by the <A HREF = "units.html">units</A>
command.
<LI>If you add something you think is truly useful and doesn't impact
LAMMPS performance when it isn't used, send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>. We might be
interested in adding it to the LAMMPS distribution. See further
-details on this at the bottom of this page.
+details on this at the bottom of this page.
</UL>
<HR>
-<P>Here are the subsequent topics discussed below, most of which are new
-features that can be added in the manner just described:
-</P>
-10.1 <A HREF = "#mod_1">Atom styles</A><BR>
-10.2 <A HREF = "#mod_2">Bond, angle, dihedral, improper potentials</A><BR>
-10.3 <A HREF = "#mod_3">Compute styles</A><BR>
-10.4 <A HREF = "#mod_4">Dump styles</A><BR>
-10.5 <A HREF = "#mod_5">Dump custom output options</A><BR>
-10.6 <A HREF = "#mod_6">Fix styles</A> which include integrators, temperature and pressure control, force constraints, boundary conditions, diagnostic output, etc<BR>
-10.7 <A HREF = "mod_7">Input script commands</A><BR>
-10.8 <A HREF = "#mod_8">Kspace computations</A><BR>
-10.9 <A HREF = "#mod_9">Minimization styles</A><BR>
-10.10 <A HREF = "#mod_10">Pairwise potentials</A><BR>
-10.11 <A HREF = "#mod_11">Region styles</A><BR>
-10.12 <A HREF = "#mod_12">Thermodynamic output options</A><BR>
-10.13 <A HREF = "#mod_13">Variable options</A><BR>
-10.14 <A HREF = "#mod_14">Submitting new features for inclusion in LAMMPS</A> <BR>
-
-<HR>
-
<HR>
<A NAME = "mod_1"></A><H4>10.1 Atom styles
</H4>
<P>Classes that define an atom style are derived from the AtomVec class
and managed by the Atom class. The atom style determines what
quantities are associated with an atom. A new atom style can be
created if one of the existing atom styles does not define all
the arrays you need to store and communicate with atoms.
</P>
<P>Atom_vec_atomic.cpp is a simple example of an atom style.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See atom_vec.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >init</TD><TD > one time setup (optional)</TD></TR>
<TR><TD >grow</TD><TD > re-allocate atom arrays to longer lengths (required)</TD></TR>
<TR><TD >grow_reset</TD><TD > make array pointers in Atom and AtomVec classes consistent (required)</TD></TR>
<TR><TD >copy</TD><TD > copy info for one atom to another atom's array locations (required)</TD></TR>
<TR><TD >pack_comm</TD><TD > store an atom's info in a buffer communicated every timestep (required)</TD></TR>
<TR><TD >pack_comm_vel</TD><TD > add velocity info to communication buffer (required)</TD></TR>
<TR><TD >pack_comm_hybrid</TD><TD > store extra info unique to this atom style (optional)</TD></TR>
<TR><TD >unpack_comm</TD><TD > retrieve an atom's info from the buffer (required)</TD></TR>
<TR><TD >unpack_comm_vel</TD><TD > also retrieve velocity info (required)</TD></TR>
<TR><TD >unpack_comm_hybrid</TD><TD > retreive extra info unique to this atom style (optional)</TD></TR>
<TR><TD >pack_reverse</TD><TD > store an atom's info in a buffer communicating partial forces (required)</TD></TR>
<TR><TD >pack_reverse_hybrid</TD><TD > store extra info unique to this atom style (optional)</TD></TR>
<TR><TD >unpack_reverse</TD><TD > retrieve an atom's info from the buffer (required)</TD></TR>
<TR><TD >unpack_reverse_hybrid</TD><TD > retreive extra info unique to this atom style (optional)</TD></TR>
<TR><TD >pack_border</TD><TD > store an atom's info in a buffer communicated on neighbor re-builds (required)</TD></TR>
<TR><TD >pack_border_vel</TD><TD > add velocity info to buffer (required)</TD></TR>
<TR><TD >pack_border_hybrid</TD><TD > store extra info unique to this atom style (optional)</TD></TR>
<TR><TD >unpack_border</TD><TD > retrieve an atom's info from the buffer (required)</TD></TR>
<TR><TD >unpack_border_vel</TD><TD > also retrieve velocity info (required)</TD></TR>
<TR><TD >unpack_border_hybrid</TD><TD > retreive extra info unique to this atom style (optional)</TD></TR>
<TR><TD >pack_exchange</TD><TD > store all an atom's info to migrate to another processor (required)</TD></TR>
<TR><TD >unpack_exchange</TD><TD > retrieve an atom's info from the buffer (required)</TD></TR>
<TR><TD >size_restart</TD><TD > number of restart quantities associated with proc's atoms (required)</TD></TR>
<TR><TD >pack_restart</TD><TD > pack atom quantities into a buffer (required)</TD></TR>
<TR><TD >unpack_restart</TD><TD > unpack atom quantities from a buffer (required)</TD></TR>
<TR><TD >create_atom</TD><TD > create an individual atom of this style (required)</TD></TR>
<TR><TD >data_atom</TD><TD > parse an atom line from the data file (required)</TD></TR>
<TR><TD >data_atom_hybrid</TD><TD > parse additional atom info unique to this atom style (optional)</TD></TR>
<TR><TD >data_vel</TD><TD > parse one line of velocity information from data file (optional)</TD></TR>
<TR><TD >data_vel_hybrid</TD><TD > parse additional velocity data unique to this atom style (optional)</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory allocated by atom arrays (required)
</TD></TR></TABLE></DIV>
<P>The constructor of the derived class sets values for several variables
that you must set when defining a new atom style, which are documented
in atom_vec.h. New atom arrays are defined in atom.cpp. Search for
the word "customize" and you will find locations you will need to
modify.
</P>
<HR>
<A NAME = "mod_2"></A><H4>10.2 Bond, angle, dihedral, improper potentials
</H4>
<P>Classes that compute molecular interactions are derived from the Bond,
Angle, Dihedral, and Improper classes. New styles can be created to
add new potentials to LAMMPS.
</P>
<P>Bond_harmonic.cpp is the simplest example of a bond style. Ditto for
the harmonic forms of the angle, dihedral, and improper style
commands.
</P>
<P>Here is a brief description of common methods you define in your
new derived class. See bond.h, angle.h, dihedral.h, and improper.h
for details and specific additional methods.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >init</TD><TD > check if all coefficients are set, calls <I>init_style</I> (optional)</TD></TR>
<TR><TD >init_style</TD><TD > check if style specific conditions are met (optional)</TD></TR>
<TR><TD >compute</TD><TD > compute the molecular interactions (required)</TD></TR>
<TR><TD >settings</TD><TD > apply global settings for all types (optional)</TD></TR>
<TR><TD >coeff</TD><TD > set coefficients for one type (required)</TD></TR>
<TR><TD >equilibrium_distance</TD><TD > length of bond, used by SHAKE (required, bond only)</TD></TR>
<TR><TD >equilibrium_angle</TD><TD > opening of angle, used by SHAKE (required, angle only)</TD></TR>
<TR><TD >write & read_restart</TD><TD > writes/reads coeffs to restart files (required)</TD></TR>
<TR><TD >single</TD><TD > force and energy of a single bond or angle (required, bond or angle only)</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory allocated by the style (optional)
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "mod_3"></A><H4>10.3 Compute styles
</H4>
<P>Classes that compute scalar and vector quantities like temperature
and the pressure tensor, as well as classes that compute per-atom
quantities like kinetic energy and the centro-symmetry parameter
are derived from the Compute class. New styles can be created
to add new calculations to LAMMPS.
</P>
<P>Compute_temp.cpp is a simple example of computing a scalar
temperature. Compute_ke_atom.cpp is a simple example of computing
per-atom kinetic energy.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See compute.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >init</TD><TD > perform one time setup (required)</TD></TR>
<TR><TD >init_list</TD><TD > neighbor list setup, if needed (optional)</TD></TR>
<TR><TD >compute_scalar</TD><TD > compute a scalar quantity (optional)</TD></TR>
<TR><TD >compute_vector</TD><TD > compute a vector of quantities (optional)</TD></TR>
<TR><TD >compute_peratom</TD><TD > compute one or more quantities per atom (optional)</TD></TR>
<TR><TD >compute_local</TD><TD > compute one or more quantities per processor (optional)</TD></TR>
<TR><TD >pack_comm</TD><TD > pack a buffer with items to communicate (optional)</TD></TR>
<TR><TD >unpack_comm</TD><TD > unpack the buffer (optional)</TD></TR>
<TR><TD >pack_reverse</TD><TD > pack a buffer with items to reverse communicate (optional)</TD></TR>
<TR><TD >unpack_reverse</TD><TD > unpack the buffer (optional)</TD></TR>
<TR><TD >remove_bias</TD><TD > remove velocity bias from one atom (optional)</TD></TR>
<TR><TD >remove_bias_all</TD><TD > remove velocity bias from all atoms in group (optional)</TD></TR>
<TR><TD >restore_bias</TD><TD > restore velocity bias for one atom after remove_bias (optional)</TD></TR>
<TR><TD >restore_bias_all</TD><TD > same as before, but for all atoms in group (optional)</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory usage (optional)
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "mod_4"></A><H4>10.4 Dump styles
</H4>
<A NAME = "mod_5"></A><H4>10.5 Dump custom output options
</H4>
<P>Classes that dump per-atom info to files are derived from the Dump
class. To dump new quantities or in a new format, a new derived dump
class can be added, but it is typically simpler to modify the
DumpCustom class contained in the dump_custom.cpp file.
</P>
<P>Dump_atom.cpp is a simple example of a derived dump class.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See dump.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >write_header</TD><TD > write the header section of a snapshot of atoms</TD></TR>
<TR><TD >count</TD><TD > count the number of lines a processor will output</TD></TR>
<TR><TD >pack</TD><TD > pack a proc's output data into a buffer</TD></TR>
<TR><TD >write_data</TD><TD > write a proc's data to a file
</TD></TR></TABLE></DIV>
<P>See the <A HREF = "dump.html">dump</A> command and its <I>custom</I> style for a list of
keywords for atom information that can already be dumped by
DumpCustom. It includes options to dump per-atom info from Compute
classes, so adding a new derived Compute class is one way to calculate
new quantities to dump.
</P>
<P>Alternatively, you can add new keywords to the dump custom command.
Search for the word "customize" in dump_custom.cpp to see the
half-dozen or so locations where code will need to be added.
</P>
<HR>
<A NAME = "mod_6"></A><H4>10.6 Fix styles
</H4>
<P>In LAMMPS, a "fix" is any operation that is computed during
timestepping that alters some property of the system. Essentially
everything that happens during a simulation besides force computation,
neighbor list construction, and output, is a "fix". This includes
time integration (update of coordinates and velocities), force
constraints or boundary conditions (SHAKE or walls), and diagnostics
(compute a diffusion coefficient). New styles can be created to add
new options to LAMMPS.
</P>
<P>Fix_setforce.cpp is a simple example of setting forces on atoms to
prescribed values. There are dozens of fix options already in LAMMPS;
choose one as a template that is similar to what you want to
implement.
</P>
<P>Here is a brief description of methods you can define in your new
derived class. See fix.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >setmask</TD><TD > determines when the fix is called during the timestep (required)</TD></TR>
<TR><TD >init</TD><TD > initialization before a run (optional)</TD></TR>
<TR><TD >setup_pre_exchange</TD><TD > called before atom exchange in setup (optional)</TD></TR>
<TR><TD >setup_pre_force</TD><TD > called before force computation in setup (optional)</TD></TR>
<TR><TD >setup</TD><TD > called immediately before the 1st timestep and after forces are computed (optional)</TD></TR>
<TR><TD >min_setup_pre_force</TD><TD > like setup_pre_force, but for minimizations instead of MD runs (optional)</TD></TR>
<TR><TD >min_setup</TD><TD > like setup, but for minimizations instead of MD runs (optional)</TD></TR>
<TR><TD >initial_integrate</TD><TD > called at very beginning of each timestep (optional)</TD></TR>
<TR><TD >pre_exchange</TD><TD > called before atom exchange on re-neighboring steps (optional)</TD></TR>
<TR><TD >pre_neighbor</TD><TD > called before neighbor list build (optional)</TD></TR>
<TR><TD >pre_force</TD><TD > called after pair & molecular forces are computed (optional)</TD></TR>
<TR><TD >post_force</TD><TD > called after pair & molecular forces are computed and communicated (optional)</TD></TR>
<TR><TD >final_integrate</TD><TD > called at end of each timestep (optional)</TD></TR>
<TR><TD >end_of_step</TD><TD > called at very end of timestep (optional)</TD></TR>
<TR><TD >write_restart</TD><TD > dumps fix info to restart file (optional)</TD></TR>
<TR><TD >restart</TD><TD > uses info from restart file to re-initialize the fix (optional)</TD></TR>
<TR><TD >grow_arrays</TD><TD > allocate memory for atom-based arrays used by fix (optional)</TD></TR>
<TR><TD >copy_arrays</TD><TD > copy atom info when an atom migrates to a new processor (optional)</TD></TR>
<TR><TD >pack_exchange</TD><TD > store atom's data in a buffer (optional)</TD></TR>
<TR><TD >unpack_exchange</TD><TD > retrieve atom's data from a buffer (optional)</TD></TR>
<TR><TD >pack_restart</TD><TD > store atom's data for writing to restart file (optional)</TD></TR>
<TR><TD >unpack_restart</TD><TD > retrieve atom's data from a restart file buffer (optional)</TD></TR>
<TR><TD >size_restart</TD><TD > size of atom's data (optional)</TD></TR>
<TR><TD >maxsize_restart</TD><TD > max size of atom's data (optional)</TD></TR>
<TR><TD >setup_pre_force_respa</TD><TD > same as setup_pre_force, but for rRESPA (optional)</TD></TR>
<TR><TD >initial_integrate_respa</TD><TD > same as initial_integrate, but for rRESPA (optional)</TD></TR>
<TR><TD >post_integrate_respa</TD><TD > called after the first half integration step is done in rRESPA (optional)</TD></TR>
<TR><TD >pre_force_respa</TD><TD > same as pre_force, but for rRESPA (optional)</TD></TR>
<TR><TD >post_force_respa</TD><TD > same as post_force, but for rRESPA (optional)</TD></TR>
<TR><TD >final_integrate_respa</TD><TD > same as final_integrate, but for rRESPA (optional)</TD></TR>
<TR><TD >min_pre_force</TD><TD > called after pair & molecular forces are computed in minimizer (optional)</TD></TR>
<TR><TD >min_post_force</TD><TD > called after pair & molecular forces are computed and communicated in minmizer (optional)</TD></TR>
<TR><TD >min_store</TD><TD > store extra data for linesearch based minimization on a LIFO stack (optional)</TD></TR>
<TR><TD >min_pushstore</TD><TD > push the minimization LIFO stack one element down (optional)</TD></TR>
<TR><TD >min_popstore</TD><TD > pop the minimization LIFO stack one element up (optional)</TD></TR>
<TR><TD >min_clearstore</TD><TD > clear minimization LIFO stack (optional)</TD></TR>
<TR><TD >min_step</TD><TD > reset or move forward on line search minimization (optional)</TD></TR>
<TR><TD >min_dof</TD><TD > report number of degrees of freedom <I>added</I> by this fix in minimization (optional)</TD></TR>
<TR><TD >max_alpha</TD><TD > report maximum allowed step size during linesearch minimization (optional)</TD></TR>
<TR><TD >pack_comm</TD><TD > pack a buffer to communicate a per-atom quantity (optional)</TD></TR>
<TR><TD >unpack_comm</TD><TD > unpack a buffer to communicate a per-atom quantity (optional)</TD></TR>
<TR><TD >pack_reverse_comm</TD><TD > pack a buffer to reverse communicate a per-atom quantity (optional)</TD></TR>
<TR><TD >unpack_reverse_comm</TD><TD > unpack a buffer to reverse communicate a per-atom quantity (optional)</TD></TR>
<TR><TD >dof</TD><TD > report number of degrees of freedom <I>removed</I> by this fix during MD (optional)</TD></TR>
<TR><TD >compute_scalar</TD><TD > return a global scalar property that the fix computes (optional)</TD></TR>
<TR><TD >compute_vector</TD><TD > return a component of a vector property that the fix computes (optional)</TD></TR>
<TR><TD >compute_array</TD><TD > return a component of an array property that the fix computes (optional)</TD></TR>
<TR><TD >deform</TD><TD > called when the box size is changed (optional)</TD></TR>
<TR><TD >reset_target</TD><TD > called when a change of the target temperature is requested during a run (optional)</TD></TR>
<TR><TD >reset_dt</TD><TD > is called when a change of the time step is requested during a run (optional)</TD></TR>
<TR><TD >modify_param</TD><TD > called when a fix_modify request is executed (optional)</TD></TR>
<TR><TD >memory_usage</TD><TD > report memory used by fix (optional)</TD></TR>
<TR><TD >thermo</TD><TD > compute quantities for thermodynamic output (optional)
</TD></TR></TABLE></DIV>
<P>Typically, only a small fraction of these methods are defined for a
particular fix. Setmask is mandatory, as it determines when the fix
will be invoked during the timestep. Fixes that perform time
integration (<I>nve</I>, <I>nvt</I>, <I>npt</I>) implement initial_integrate() and
final_integrate() to perform velocity Verlet updates. Fixes that
constrain forces implement post_force().
</P>
<P>Fixes that perform diagnostics typically implement end_of_step(). For
an end_of_step fix, one of your fix arguments must be the variable
"nevery" which is used to determine when to call the fix and you must
set this variable in the constructor of your fix. By convention, this
is the first argument the fix defines (after the ID, group-ID, style).
</P>
<P>If the fix needs to store information for each atom that persists from
timestep to timestep, it can manage that memory and migrate the info
with the atoms as they move from processors to processor by
implementing the grow_arrays, copy_arrays, pack_exchange, and
unpack_exchange methods. Similarly, the pack_restart and
unpack_restart methods can be implemented to store information about
the fix in restart files. If you wish an integrator or force
constraint fix to work with rRESPA (see the <A HREF = "run_style.html">run_style</A>
command), the initial_integrate, post_force_integrate, and
final_integrate_respa methods can be implemented. The thermo method
enables a fix to contribute values to thermodynamic output, as printed
quantities and/or to be summed to the potential energy of the system.
</P>
<HR>
<A NAME = "mod_7"></A><H4>10.7 Input script commands
</H4>
<P>New commands can be added to LAMMPS input scripts by adding new
classes that have a "command" method. For example, the create_atoms,
read_data, velocity, and run commands are all implemented in this
fashion. When such a command is encountered in the LAMMPS input
script, LAMMPS simply creates a class with the corresponding name,
invokes the "command" method of the class, and passes it the arguments
from the input script. The command method can perform whatever
operations it wishes on LAMMPS data structures.
</P>
<P>The single method your new class must define is as follows:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >command</TD><TD > operations performed by the new command
</TD></TR></TABLE></DIV>
<P>Of course, the new class can define other methods and variables as
needed.
</P>
<HR>
<A NAME = "mod_8"></A><H4>10.8 Kspace computations
</H4>
<P>Classes that compute long-range Coulombic interactions via K-space
representations (Ewald, PPPM) are derived from the KSpace class. New
styles can be created to add new K-space options to LAMMPS.
</P>
<P>Ewald.cpp is an example of computing K-space interactions.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See kspace.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >init</TD><TD > initialize the calculation before a run</TD></TR>
<TR><TD >setup</TD><TD > computation before the 1st timestep of a run</TD></TR>
<TR><TD >compute</TD><TD > every-timestep computation</TD></TR>
<TR><TD >memory_usage</TD><TD > tally of memory usage
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "mod_9"></A><H4>10.9 Minimization styles
</H4>
<P>Classes that perform energy minimization derived from the Min class.
New styles can be created to add new minimization algorithms to
LAMMPS.
</P>
<P>Min_cg.cpp is an example of conjugate gradient minimization.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See min.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >init</TD><TD > initialize the minimization before a run</TD></TR>
<TR><TD >run</TD><TD > perform the minimization</TD></TR>
<TR><TD >memory_usage</TD><TD > tally of memory usage
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "mod_10"></A><H4>10.10 Pairwise potentials
</H4>
<P>Classes that compute pairwise interactions are derived from the Pair
class. In LAMMPS, pairwise calculation include manybody potentials
such as EAM or Tersoff where particles interact without a static bond
topology. New styles can be created to add new pair potentials to
LAMMPS.
</P>
<P>Pair_lj_cut.cpp is a simple example of a Pair class, though it
includes some optional methods to enable its use with rRESPA.
</P>
<P>Here is a brief description of the class methods in pair.h:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >compute</TD><TD > workhorse routine that computes pairwise interactions</TD></TR>
<TR><TD >settings</TD><TD > reads the input script line with arguments you define</TD></TR>
<TR><TD >coeff</TD><TD > set coefficients for one i,j type pair</TD></TR>
<TR><TD >init_one</TD><TD > perform initialization for one i,j type pair</TD></TR>
<TR><TD >init_style</TD><TD > initialization specific to this pair style</TD></TR>
<TR><TD >write & read_restart</TD><TD > write/read i,j pair coeffs to restart files</TD></TR>
<TR><TD >write & read_restart_settings</TD><TD > write/read global settings to restart files</TD></TR>
<TR><TD >single</TD><TD > force and energy of a single pairwise interaction between 2 atoms</TD></TR>
<TR><TD >compute_inner/middle/outer</TD><TD > versions of compute used by rRESPA
</TD></TR></TABLE></DIV>
<P>The inner/middle/outer routines are optional.
</P>
<HR>
<A NAME = "mod_11"></A><H4>10.11 Region styles
</H4>
<P>Classes that define geometric regions are derived from the Region
class. Regions are used elsewhere in LAMMPS to group atoms, delete
atoms to create a void, insert atoms in a specified region, etc. New
styles can be created to add new region shapes to LAMMPS.
</P>
<P>Region_sphere.cpp is an example of a spherical region.
</P>
<P>Here is a brief description of methods you define in your new derived
class. See region.h for details.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >match</TD><TD > determine whether a point is in the region
</TD></TR></TABLE></DIV>
<HR>
<A NAME = "mod_12"></A><H4>10.12 Thermodynamic output options
</H4>
<P>There is one class that computes and prints thermodynamic information
to the screen and log file; see the file thermo.cpp.
</P>
<P>There are two styles defined in thermo.cpp: "one" and "multi". There
is also a flexible "custom" style which allows the user to explicitly
list keywords for quantities to print when thermodynamic info is
output. See the <A HREF = "thermo_style.html">thermo_style</A> command for a list
of defined quantities.
</P>
<P>The thermo styles (one, multi, etc) are simply lists of keywords.
Adding a new style thus only requires defining a new list of keywords.
Search for the word "customize" with references to "thermo style" in
thermo.cpp to see the two locations where code will need to be added.
</P>
<P>New keywords can also be added to thermo.cpp to compute new quantities
for output. Search for the word "customize" with references to
"keyword" in thermo.cpp to see the several locations where code will
need to be added.
</P>
<P>Note that the <A HREF = "thermo.html">thermo_style custom</A> command already allows
for thermo output of quantities calculated by <A HREF = "fix.html">fixes</A>,
<A HREF = "compute.html">computes</A>, and <A HREF = "variable.html">variables</A>. Thus, it may
be simpler to compute what you wish via one of those constructs, than
by adding a new keyword to the thermo command.
</P>
<HR>
<A NAME = "mod_13"></A><H4>10.13 Variable options
</H4>
<P>There is one class that computes and stores <A HREF = "variable.html">variable</A>
information in LAMMPS; see the file variable.cpp. The value
associated with a variable can be periodically printed to the screen
via the <A HREF = "print.html">print</A>, <A HREF = "fix_print.html">fix print</A>, or
<A HREF = "thermo_style.html">thermo_style custom</A> commands. Variables of style
"equal" can compute complex equations that involve the following types
of arguments:
</P>
<P>thermo keywords = ke, vol, atoms, ...
other variables = v_a, v_myvar, ...
math functions = div(x,y), mult(x,y), add(x,y), ...
group functions = mass(group), xcm(group,x), ...
atom values = x<B>123</B>, y<B>3</B>, vx<B>34</B>, ...
compute values = c_mytemp<B>0</B>, c_thermo_press<B>3</B>, ...
</P>
<P>Adding keywords for the <A HREF = "thermo_style.html">thermo_style custom</A> command
(which can then be accessed by variables) was discussed
<A HREF = "Section_modify.html#thermo">here</A> on this page.
</P>
<P>Adding a new math function of one or two arguments can be done by
editing one section of the Variable::evaulate() method. Search for
the word "customize" to find the appropriate location.
</P>
<P>Adding a new group function can be done by editing one section of the
Variable::evaulate() method. Search for the word "customize" to find
the appropriate location. You may need to add a new method to the
Group class as well (see the group.cpp file).
</P>
<P>Accessing a new atom-based vector can be done by editing one section
of the Variable::evaulate() method. Search for the word "customize"
to find the appropriate location.
</P>
<P>Adding new <A HREF = "compute.html">compute styles</A> (whose calculated values can
then be accessed by variables) was discussed
<A HREF = "Section_modify.html#compute">here</A> on this page.
</P>
<HR>
<HR>
<A NAME = "mod_14"></A><H4>10.14 Submitting new features for inclusion in LAMMPS
</H4>
<P>We encourage users to submit new features that they add to LAMMPS to
<A HREF = "http://lammps.sandia.gov/authors.html">the developers</A>, especially if
you think the features will be of interest to other users. If they
are broadly useful we may add them as core files to LAMMPS or as part
of a <A HREF = "Section_start.html#start_3">standard package</A>. Else we will add
them as a user-contributed package or file. Examples of user packages
are in src sub-directories that start with USER. The USER-MISC
package is simply a collection of (mostly) unrelated single files,
which is the simplest way to have your contribution quickly added to
the LAMMPS distribution. You can see a list of the both standard and
user packages by typing "make package" in the LAMMPS src directory.
</P>
<P>With user packages and files, all we are really providing (aside from
the fame and fortune that accompanies having your name in the source
code and on the <A HREF = "http://lammps.sandia.gov/authors.html">Authors page</A>
of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW site</A>), is a means for you to distribute your
work to the LAMMPS user community and a mechanism for others to easily
try out your new feature. This may help you find bugs or make contact
with new collaborators. Note that you're also implicitly agreeing to
support your code which means answer questions, fix bugs, and maintain
it if LAMMPS changes.
</P>
<P>The previous sections of this doc page describe how to add new
features of various kinds to LAMMPS. Packages are simply collections
of one or more new class files which are invoked as a new "style"
within a LAMMPS input script. If designed correctly, these additions
do not require changes to the main core of LAMMPS; they are simply
add-on files. If you think your new feature requires non-trivial
changes in core LAMMPS files, you'll need to <A HREF = "http://lammps.sandia.gov/authors.html">communicate with the
developers</A>, since we may or may
not want to make those changes. An example of a trivial change is
making a parent-class method "virtual" when you derive a new child
class from it.
</P>
<P>Here is what you need to do to submit a user package or single file
for our consideration. Following these steps will save time for both
you and us. See existing package files for examples.
</P>
<UL><LI>All source files you provide must compile with the most current
version of LAMMPS.
<LI>If your contribution is a single file (actually a *.cpp and *.h file)
it can most rapidly be added to the USER-MISC directory. Send us the
one-line entry to add to the USER-MISC/README file in that dir, along
with the 2 source files. You can do this multiple times if you wish
to contribute several individual features.
<LI>If your contribution is several related featues, it is probably best
to make it a user package directory with a name like USER-FOO. In
addition to your new files, the directory should contain a README, and
Install.csh file. The README text file should contain your name and
contact information and a brief description of what your new package
does. The Install.csh file enables LAMMPS to include and exclude your
package. See other README and Install.sh files in other USER
directories as examples. Send us a tarball of this USER-FOO
directory.
<LI>Your new source files need to have the LAMMPS copyright, GPL notice,
and your name at the top, like other LAMMPS source files. They need
to create a class that is inside the LAMMPS namespace. Other than
that, your files can do whatever is necessary to implement the new
features. They don't have to be written in the same stylistic format
and syntax as other LAMMPS files, though that would be nice.
<LI>Finally, you must also send a documentation file for each new command
or style you are adding to LAMMPS. This will be one file for a
single-file feature. For a package, it might be several files. These
are simple text files which we will convert to HTML. They must be in
the same format as other *.txt files in the lammps/doc directory for
similar commands and styles. The "Restrictions" section of the doc
page should indicate that your command is only available if LAMMPS is
built with the appropriate USER-MISC or USER-FOO package. See other
user package doc files for an example of how to do this. The txt2html
tool we use to do the conversion can be downloaded from <A HREF = "http://www.sandia.gov/~sjplimp/download.html">this
site</A>, so you can perform
the HTML conversion yourself to proofread your doc page.
</UL>
<P>Note that the more clear and self-explanatory you make your doc and
README files, the more likely it is that users will try out your new
feature.
</P>
<HR>
<HR>
<A NAME = "Foo"></A>
<P><B>(Foo)</B> Foo, Morefoo, and Maxfoo, J of Classic Potentials, 75, 345 (1997).
</P>
</HTML>
diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt
index 789761cbb..a38bd219a 100644
--- a/doc/Section_modify.txt
+++ b/doc/Section_modify.txt
@@ -1,640 +1,636 @@
"Previous Section"_Section_tools.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_python.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
10. Modifying & extending LAMMPS :h3
+This section describes how to customize LAMMPS by modifying
+and extending its source code.
+
+10.1 "Atom styles"_#mod_1
+10.2 "Bond, angle, dihedral, improper potentials"_#mod_2
+10.3 "Compute styles"_#mod_3
+10.4 "Dump styles"_#mod_4
+10.5 "Dump custom output options"_#mod_5
+10.6 "Fix styles"_#mod_6 which include integrators, \
+ temperature and pressure control, force constraints, \
+ boundary conditions, diagnostic output, etc
+10.7 "Input script commands"_mod_7
+10.8 "Kspace computations"_#mod_8
+10.9 "Minimization styles"_#mod_9
+10.10 "Pairwise potentials"_#mod_10
+10.11 "Region styles"_#mod_11
+10.12 "Thermodynamic output options"_#mod_12
+10.13 "Variable options"_#mod_13
+10.14 "Submitting new features for inclusion in LAMMPS"_#mod_14 :all(b)
+
LAMMPS is designed in a modular fashion so as to be easy to modify and
extend with new functionality. In fact, about 75% of its source code
is files added in this fashion.
In this section, changes and additions users can make are listed along
with minimal instructions. If you add a new feature to LAMMPS and
think it will be of interest to general users, we encourage you to
submit it to the developers for inclusion in the released version of
LAMMPS. Information about how to do this is provided
"below"_#mod_14.
The best way to add a new feature is to find a similar feature in
LAMMPS and look at the corresponding source and header files to figure
out what it does. You will need some knowledge of C++ to be able to
understand the hi-level structure of LAMMPS and its class
organization, but functions (class methods) that do actual
computations are written in vanilla C-style code and operate on simple
C-style data structures (vectors and arrays).
Most of the new features described in this section require you to
write a new C++ derived class (except for exceptions described below,
where you can make small edits to existing files). Creating a new
class requires 2 files, a source code file (*.cpp) and a header file
(*.h). The derived class must provide certain methods to work as a
new option. Depending on how different your new feature is compared
to existing features, you can either derive from the base class
itself, or from a derived class that already exists. Enabling LAMMPS
to invoke the new class is as simple as putting the two source
files in the src dir and re-building LAMMPS.
The advantage of C++ and its object-orientation is that all the code
and variables needed to define the new feature are in the 2 files you
write, and thus shouldn't make the rest of LAMMPS more complex or
cause side-effect bugs.
Here is a concrete example. Suppose you write 2 files pair_foo.cpp
and pair_foo.h that define a new class PairFoo that computes pairwise
potentials described in the classic 1997 "paper"_#Foo by Foo, et al.
If you wish to invoke those potentials in a LAMMPS input script with a
command like
pair_style foo 0.1 3.5 :pre
then your pair_foo.h file should be structured as follows:
#ifdef PAIR_CLASS
PairStyle(foo,PairFoo)
#else
...
(class definition for PairFoo)
...
#endif :pre
where "foo" is the style keyword in the pair_style command, and
PairFoo is the class name defined in your pair_foo.cpp and pair_foo.h
files.
When you re-build LAMMPS, your new pairwise potential becomes part of
the executable and can be invoked with a pair_style command like the
example above. Arguments like 0.1 and 3.5 can be defined and
processed by your new class.
As illustrated by this pairwise example, many kinds of options are
referred to in the LAMMPS documentation as the "style" of a particular
command.
The instructions below give the header file for the base class that
these styles are derived from. Public variables in that file are ones
used and set by the derived classes which are also used by the base
class. Sometimes they are also used by the rest of LAMMPS. Virtual
functions in the base class header file which are set = 0 are ones you
must define in your new derived class to give it the functionality
LAMMPS expects. Virtual functions that are not set to 0 are functions
you can optionally define.
Additionally, new output options can be added directly to the
thermo.cpp, dump_custom.cpp, and variable.cpp files as explained
below.
-:line
-
Here are additional guidelines for modifying LAMMPS and adding new
functionality:
Think about whether what you want to do would be better as a pre- or
post-processing step. Many computations are more easily and more
quickly done that way. :ulb,l
Don't do anything within the timestepping of a run that isn't
parallel. E.g. don't accumulate a bunch of data on a single processor
and analyze it. You run the risk of seriously degrading the parallel
efficiency. :l
If your new feature reads arguments or writes output, make sure you
follow the unit conventions discussed by the "units"_units.html
command. :l
If you add something you think is truly useful and doesn't impact
LAMMPS performance when it isn't used, send an email to the
"developers"_http://lammps.sandia.gov/authors.html. We might be
interested in adding it to the LAMMPS distribution. See further
-details on this at the bottom of this page. :l,ule
-
-:line
-
-Here are the subsequent topics discussed below, most of which are new
-features that can be added in the manner just described:
-
-10.1 "Atom styles"_#mod_1
-10.2 "Bond, angle, dihedral, improper potentials"_#mod_2
-10.3 "Compute styles"_#mod_3
-10.4 "Dump styles"_#mod_4
-10.5 "Dump custom output options"_#mod_5
-10.6 "Fix styles"_#mod_6 which include integrators, \
- temperature and pressure control, force constraints, \
- boundary conditions, diagnostic output, etc
-10.7 "Input script commands"_mod_7
-10.8 "Kspace computations"_#mod_8
-10.9 "Minimization styles"_#mod_9
-10.10 "Pairwise potentials"_#mod_10
-10.11 "Region styles"_#mod_11
-10.12 "Thermodynamic output options"_#mod_12
-10.13 "Variable options"_#mod_13
-10.14 "Submitting new features for inclusion in LAMMPS"_#mod_14 :all(b)
+details on this at the bottom of this page. :l,ule
:line
:line
10.1 Atom styles :link(mod_1),h4
Classes that define an atom style are derived from the AtomVec class
and managed by the Atom class. The atom style determines what
quantities are associated with an atom. A new atom style can be
created if one of the existing atom styles does not define all
the arrays you need to store and communicate with atoms.
Atom_vec_atomic.cpp is a simple example of an atom style.
Here is a brief description of methods you define in your new derived
class. See atom_vec.h for details.
init: one time setup (optional)
grow: re-allocate atom arrays to longer lengths (required)
grow_reset: make array pointers in Atom and AtomVec classes consistent (required)
copy: copy info for one atom to another atom's array locations (required)
pack_comm: store an atom's info in a buffer communicated every timestep (required)
pack_comm_vel: add velocity info to communication buffer (required)
pack_comm_hybrid: store extra info unique to this atom style (optional)
unpack_comm: retrieve an atom's info from the buffer (required)
unpack_comm_vel: also retrieve velocity info (required)
unpack_comm_hybrid: retreive extra info unique to this atom style (optional)
pack_reverse: store an atom's info in a buffer communicating partial forces (required)
pack_reverse_hybrid: store extra info unique to this atom style (optional)
unpack_reverse: retrieve an atom's info from the buffer (required)
unpack_reverse_hybrid: retreive extra info unique to this atom style (optional)
pack_border: store an atom's info in a buffer communicated on neighbor re-builds (required)
pack_border_vel: add velocity info to buffer (required)
pack_border_hybrid: store extra info unique to this atom style (optional)
unpack_border: retrieve an atom's info from the buffer (required)
unpack_border_vel: also retrieve velocity info (required)
unpack_border_hybrid: retreive extra info unique to this atom style (optional)
pack_exchange: store all an atom's info to migrate to another processor (required)
unpack_exchange: retrieve an atom's info from the buffer (required)
size_restart: number of restart quantities associated with proc's atoms (required)
pack_restart: pack atom quantities into a buffer (required)
unpack_restart: unpack atom quantities from a buffer (required)
create_atom: create an individual atom of this style (required)
data_atom: parse an atom line from the data file (required)
data_atom_hybrid: parse additional atom info unique to this atom style (optional)
data_vel: parse one line of velocity information from data file (optional)
data_vel_hybrid: parse additional velocity data unique to this atom style (optional)
memory_usage: tally memory allocated by atom arrays (required) :tb(s=:)
The constructor of the derived class sets values for several variables
that you must set when defining a new atom style, which are documented
in atom_vec.h. New atom arrays are defined in atom.cpp. Search for
the word "customize" and you will find locations you will need to
modify.
:line
10.2 Bond, angle, dihedral, improper potentials :link(mod_2),h4
Classes that compute molecular interactions are derived from the Bond,
Angle, Dihedral, and Improper classes. New styles can be created to
add new potentials to LAMMPS.
Bond_harmonic.cpp is the simplest example of a bond style. Ditto for
the harmonic forms of the angle, dihedral, and improper style
commands.
Here is a brief description of common methods you define in your
new derived class. See bond.h, angle.h, dihedral.h, and improper.h
for details and specific additional methods.
init: check if all coefficients are set, calls {init_style} (optional)
init_style: check if style specific conditions are met (optional)
compute: compute the molecular interactions (required)
settings: apply global settings for all types (optional)
coeff: set coefficients for one type (required)
equilibrium_distance: length of bond, used by SHAKE (required, bond only)
equilibrium_angle: opening of angle, used by SHAKE (required, angle only)
write & read_restart: writes/reads coeffs to restart files (required)
single: force and energy of a single bond or angle (required, bond or angle only)
memory_usage: tally memory allocated by the style (optional) :tb(s=:)
:line
10.3 Compute styles :link(mod_3),h4
Classes that compute scalar and vector quantities like temperature
and the pressure tensor, as well as classes that compute per-atom
quantities like kinetic energy and the centro-symmetry parameter
are derived from the Compute class. New styles can be created
to add new calculations to LAMMPS.
Compute_temp.cpp is a simple example of computing a scalar
temperature. Compute_ke_atom.cpp is a simple example of computing
per-atom kinetic energy.
Here is a brief description of methods you define in your new derived
class. See compute.h for details.
init: perform one time setup (required)
init_list: neighbor list setup, if needed (optional)
compute_scalar: compute a scalar quantity (optional)
compute_vector: compute a vector of quantities (optional)
compute_peratom: compute one or more quantities per atom (optional)
compute_local: compute one or more quantities per processor (optional)
pack_comm: pack a buffer with items to communicate (optional)
unpack_comm: unpack the buffer (optional)
pack_reverse: pack a buffer with items to reverse communicate (optional)
unpack_reverse: unpack the buffer (optional)
remove_bias: remove velocity bias from one atom (optional)
remove_bias_all: remove velocity bias from all atoms in group (optional)
restore_bias: restore velocity bias for one atom after remove_bias (optional)
restore_bias_all: same as before, but for all atoms in group (optional)
memory_usage: tally memory usage (optional) :tb(s=:)
:line
10.4 Dump styles :link(mod_4),h4
10.5 Dump custom output options :link(mod_5),h4
Classes that dump per-atom info to files are derived from the Dump
class. To dump new quantities or in a new format, a new derived dump
class can be added, but it is typically simpler to modify the
DumpCustom class contained in the dump_custom.cpp file.
Dump_atom.cpp is a simple example of a derived dump class.
Here is a brief description of methods you define in your new derived
class. See dump.h for details.
write_header: write the header section of a snapshot of atoms
count: count the number of lines a processor will output
pack: pack a proc's output data into a buffer
write_data: write a proc's data to a file :tb(s=:)
See the "dump"_dump.html command and its {custom} style for a list of
keywords for atom information that can already be dumped by
DumpCustom. It includes options to dump per-atom info from Compute
classes, so adding a new derived Compute class is one way to calculate
new quantities to dump.
Alternatively, you can add new keywords to the dump custom command.
Search for the word "customize" in dump_custom.cpp to see the
half-dozen or so locations where code will need to be added.
:line
10.6 Fix styles :link(mod_6),h4
In LAMMPS, a "fix" is any operation that is computed during
timestepping that alters some property of the system. Essentially
everything that happens during a simulation besides force computation,
neighbor list construction, and output, is a "fix". This includes
time integration (update of coordinates and velocities), force
constraints or boundary conditions (SHAKE or walls), and diagnostics
(compute a diffusion coefficient). New styles can be created to add
new options to LAMMPS.
Fix_setforce.cpp is a simple example of setting forces on atoms to
prescribed values. There are dozens of fix options already in LAMMPS;
choose one as a template that is similar to what you want to
implement.
Here is a brief description of methods you can define in your new
derived class. See fix.h for details.
setmask: determines when the fix is called during the timestep (required)
init: initialization before a run (optional)
setup_pre_exchange: called before atom exchange in setup (optional)
setup_pre_force: called before force computation in setup (optional)
setup: called immediately before the 1st timestep and after forces are computed (optional)
min_setup_pre_force: like setup_pre_force, but for minimizations instead of MD runs (optional)
min_setup: like setup, but for minimizations instead of MD runs (optional)
initial_integrate: called at very beginning of each timestep (optional)
pre_exchange: called before atom exchange on re-neighboring steps (optional)
pre_neighbor: called before neighbor list build (optional)
pre_force: called after pair & molecular forces are computed (optional)
post_force: called after pair & molecular forces are computed and communicated (optional)
final_integrate: called at end of each timestep (optional)
end_of_step: called at very end of timestep (optional)
write_restart: dumps fix info to restart file (optional)
restart: uses info from restart file to re-initialize the fix (optional)
grow_arrays: allocate memory for atom-based arrays used by fix (optional)
copy_arrays: copy atom info when an atom migrates to a new processor (optional)
pack_exchange: store atom's data in a buffer (optional)
unpack_exchange: retrieve atom's data from a buffer (optional)
pack_restart: store atom's data for writing to restart file (optional)
unpack_restart: retrieve atom's data from a restart file buffer (optional)
size_restart: size of atom's data (optional)
maxsize_restart: max size of atom's data (optional)
setup_pre_force_respa: same as setup_pre_force, but for rRESPA (optional)
initial_integrate_respa: same as initial_integrate, but for rRESPA (optional)
post_integrate_respa: called after the first half integration step is done in rRESPA (optional)
pre_force_respa: same as pre_force, but for rRESPA (optional)
post_force_respa: same as post_force, but for rRESPA (optional)
final_integrate_respa: same as final_integrate, but for rRESPA (optional)
min_pre_force: called after pair & molecular forces are computed in minimizer (optional)
min_post_force: called after pair & molecular forces are computed and communicated in minmizer (optional)
min_store: store extra data for linesearch based minimization on a LIFO stack (optional)
min_pushstore: push the minimization LIFO stack one element down (optional)
min_popstore: pop the minimization LIFO stack one element up (optional)
min_clearstore: clear minimization LIFO stack (optional)
min_step: reset or move forward on line search minimization (optional)
min_dof: report number of degrees of freedom {added} by this fix in minimization (optional)
max_alpha: report maximum allowed step size during linesearch minimization (optional)
pack_comm: pack a buffer to communicate a per-atom quantity (optional)
unpack_comm: unpack a buffer to communicate a per-atom quantity (optional)
pack_reverse_comm: pack a buffer to reverse communicate a per-atom quantity (optional)
unpack_reverse_comm: unpack a buffer to reverse communicate a per-atom quantity (optional)
dof: report number of degrees of freedom {removed} by this fix during MD (optional)
compute_scalar: return a global scalar property that the fix computes (optional)
compute_vector: return a component of a vector property that the fix computes (optional)
compute_array: return a component of an array property that the fix computes (optional)
deform: called when the box size is changed (optional)
reset_target: called when a change of the target temperature is requested during a run (optional)
reset_dt: is called when a change of the time step is requested during a run (optional)
modify_param: called when a fix_modify request is executed (optional)
memory_usage: report memory used by fix (optional)
thermo: compute quantities for thermodynamic output (optional) :tb(s=:)
Typically, only a small fraction of these methods are defined for a
particular fix. Setmask is mandatory, as it determines when the fix
will be invoked during the timestep. Fixes that perform time
integration ({nve}, {nvt}, {npt}) implement initial_integrate() and
final_integrate() to perform velocity Verlet updates. Fixes that
constrain forces implement post_force().
Fixes that perform diagnostics typically implement end_of_step(). For
an end_of_step fix, one of your fix arguments must be the variable
"nevery" which is used to determine when to call the fix and you must
set this variable in the constructor of your fix. By convention, this
is the first argument the fix defines (after the ID, group-ID, style).
If the fix needs to store information for each atom that persists from
timestep to timestep, it can manage that memory and migrate the info
with the atoms as they move from processors to processor by
implementing the grow_arrays, copy_arrays, pack_exchange, and
unpack_exchange methods. Similarly, the pack_restart and
unpack_restart methods can be implemented to store information about
the fix in restart files. If you wish an integrator or force
constraint fix to work with rRESPA (see the "run_style"_run_style.html
command), the initial_integrate, post_force_integrate, and
final_integrate_respa methods can be implemented. The thermo method
enables a fix to contribute values to thermodynamic output, as printed
quantities and/or to be summed to the potential energy of the system.
:line
10.7 Input script commands :link(mod_7),h4
New commands can be added to LAMMPS input scripts by adding new
classes that have a "command" method. For example, the create_atoms,
read_data, velocity, and run commands are all implemented in this
fashion. When such a command is encountered in the LAMMPS input
script, LAMMPS simply creates a class with the corresponding name,
invokes the "command" method of the class, and passes it the arguments
from the input script. The command method can perform whatever
operations it wishes on LAMMPS data structures.
The single method your new class must define is as follows:
command: operations performed by the new command :tb(s=:)
Of course, the new class can define other methods and variables as
needed.
:line
10.8 Kspace computations :link(mod_8),h4
Classes that compute long-range Coulombic interactions via K-space
representations (Ewald, PPPM) are derived from the KSpace class. New
styles can be created to add new K-space options to LAMMPS.
Ewald.cpp is an example of computing K-space interactions.
Here is a brief description of methods you define in your new derived
class. See kspace.h for details.
init: initialize the calculation before a run
setup: computation before the 1st timestep of a run
compute: every-timestep computation
memory_usage: tally of memory usage :tb(s=:)
:line
10.9 Minimization styles :link(mod_9),h4
Classes that perform energy minimization derived from the Min class.
New styles can be created to add new minimization algorithms to
LAMMPS.
Min_cg.cpp is an example of conjugate gradient minimization.
Here is a brief description of methods you define in your new derived
class. See min.h for details.
init: initialize the minimization before a run
run: perform the minimization
memory_usage: tally of memory usage :tb(s=:)
:line
10.10 Pairwise potentials :link(mod_10),h4
Classes that compute pairwise interactions are derived from the Pair
class. In LAMMPS, pairwise calculation include manybody potentials
such as EAM or Tersoff where particles interact without a static bond
topology. New styles can be created to add new pair potentials to
LAMMPS.
Pair_lj_cut.cpp is a simple example of a Pair class, though it
includes some optional methods to enable its use with rRESPA.
Here is a brief description of the class methods in pair.h:
compute: workhorse routine that computes pairwise interactions
settings: reads the input script line with arguments you define
coeff: set coefficients for one i,j type pair
init_one: perform initialization for one i,j type pair
init_style: initialization specific to this pair style
write & read_restart: write/read i,j pair coeffs to restart files
write & read_restart_settings: write/read global settings to restart files
single: force and energy of a single pairwise interaction between 2 atoms
compute_inner/middle/outer: versions of compute used by rRESPA :tb(s=:)
The inner/middle/outer routines are optional.
:line
10.11 Region styles :link(mod_11),h4
Classes that define geometric regions are derived from the Region
class. Regions are used elsewhere in LAMMPS to group atoms, delete
atoms to create a void, insert atoms in a specified region, etc. New
styles can be created to add new region shapes to LAMMPS.
Region_sphere.cpp is an example of a spherical region.
Here is a brief description of methods you define in your new derived
class. See region.h for details.
match: determine whether a point is in the region :tb(s=:)
:line
10.12 Thermodynamic output options :link(mod_12),h4
There is one class that computes and prints thermodynamic information
to the screen and log file; see the file thermo.cpp.
There are two styles defined in thermo.cpp: "one" and "multi". There
is also a flexible "custom" style which allows the user to explicitly
list keywords for quantities to print when thermodynamic info is
output. See the "thermo_style"_thermo_style.html command for a list
of defined quantities.
The thermo styles (one, multi, etc) are simply lists of keywords.
Adding a new style thus only requires defining a new list of keywords.
Search for the word "customize" with references to "thermo style" in
thermo.cpp to see the two locations where code will need to be added.
New keywords can also be added to thermo.cpp to compute new quantities
for output. Search for the word "customize" with references to
"keyword" in thermo.cpp to see the several locations where code will
need to be added.
Note that the "thermo_style custom"_thermo.html command already allows
for thermo output of quantities calculated by "fixes"_fix.html,
"computes"_compute.html, and "variables"_variable.html. Thus, it may
be simpler to compute what you wish via one of those constructs, than
by adding a new keyword to the thermo command.
:line
10.13 Variable options :link(mod_13),h4
There is one class that computes and stores "variable"_variable.html
information in LAMMPS; see the file variable.cpp. The value
associated with a variable can be periodically printed to the screen
via the "print"_print.html, "fix print"_fix_print.html, or
"thermo_style custom"_thermo_style.html commands. Variables of style
"equal" can compute complex equations that involve the following types
of arguments:
thermo keywords = ke, vol, atoms, ...
other variables = v_a, v_myvar, ...
math functions = div(x,y), mult(x,y), add(x,y), ...
group functions = mass(group), xcm(group,x), ...
atom values = x[123], y[3], vx[34], ...
compute values = c_mytemp[0], c_thermo_press[3], ...
Adding keywords for the "thermo_style custom"_thermo_style.html command
(which can then be accessed by variables) was discussed
"here"_Section_modify.html#thermo on this page.
Adding a new math function of one or two arguments can be done by
editing one section of the Variable::evaulate() method. Search for
the word "customize" to find the appropriate location.
Adding a new group function can be done by editing one section of the
Variable::evaulate() method. Search for the word "customize" to find
the appropriate location. You may need to add a new method to the
Group class as well (see the group.cpp file).
Accessing a new atom-based vector can be done by editing one section
of the Variable::evaulate() method. Search for the word "customize"
to find the appropriate location.
Adding new "compute styles"_compute.html (whose calculated values can
then be accessed by variables) was discussed
"here"_Section_modify.html#compute on this page.
:line
:line
10.14 Submitting new features for inclusion in LAMMPS :link(mod_14),h4
We encourage users to submit new features that they add to LAMMPS to
"the developers"_http://lammps.sandia.gov/authors.html, especially if
you think the features will be of interest to other users. If they
are broadly useful we may add them as core files to LAMMPS or as part
of a "standard package"_Section_start.html#start_3. Else we will add
them as a user-contributed package or file. Examples of user packages
are in src sub-directories that start with USER. The USER-MISC
package is simply a collection of (mostly) unrelated single files,
which is the simplest way to have your contribution quickly added to
the LAMMPS distribution. You can see a list of the both standard and
user packages by typing "make package" in the LAMMPS src directory.
With user packages and files, all we are really providing (aside from
the fame and fortune that accompanies having your name in the source
code and on the "Authors page"_http://lammps.sandia.gov/authors.html
of the "LAMMPS WWW site"_lws), is a means for you to distribute your
work to the LAMMPS user community and a mechanism for others to easily
try out your new feature. This may help you find bugs or make contact
with new collaborators. Note that you're also implicitly agreeing to
support your code which means answer questions, fix bugs, and maintain
it if LAMMPS changes.
The previous sections of this doc page describe how to add new
features of various kinds to LAMMPS. Packages are simply collections
of one or more new class files which are invoked as a new "style"
within a LAMMPS input script. If designed correctly, these additions
do not require changes to the main core of LAMMPS; they are simply
add-on files. If you think your new feature requires non-trivial
changes in core LAMMPS files, you'll need to "communicate with the
developers"_http://lammps.sandia.gov/authors.html, since we may or may
not want to make those changes. An example of a trivial change is
making a parent-class method "virtual" when you derive a new child
class from it.
Here is what you need to do to submit a user package or single file
for our consideration. Following these steps will save time for both
you and us. See existing package files for examples.
All source files you provide must compile with the most current
version of LAMMPS. :ulb,l
If your contribution is a single file (actually a *.cpp and *.h file)
it can most rapidly be added to the USER-MISC directory. Send us the
one-line entry to add to the USER-MISC/README file in that dir, along
with the 2 source files. You can do this multiple times if you wish
to contribute several individual features. :l
If your contribution is several related featues, it is probably best
to make it a user package directory with a name like USER-FOO. In
addition to your new files, the directory should contain a README, and
Install.csh file. The README text file should contain your name and
contact information and a brief description of what your new package
does. The Install.csh file enables LAMMPS to include and exclude your
package. See other README and Install.sh files in other USER
directories as examples. Send us a tarball of this USER-FOO
directory. :l
Your new source files need to have the LAMMPS copyright, GPL notice,
and your name at the top, like other LAMMPS source files. They need
to create a class that is inside the LAMMPS namespace. Other than
that, your files can do whatever is necessary to implement the new
features. They don't have to be written in the same stylistic format
and syntax as other LAMMPS files, though that would be nice. :l
Finally, you must also send a documentation file for each new command
or style you are adding to LAMMPS. This will be one file for a
single-file feature. For a package, it might be several files. These
are simple text files which we will convert to HTML. They must be in
the same format as other *.txt files in the lammps/doc directory for
similar commands and styles. The "Restrictions" section of the doc
page should indicate that your command is only available if LAMMPS is
built with the appropriate USER-MISC or USER-FOO package. See other
user package doc files for an example of how to do this. The txt2html
tool we use to do the conversion can be downloaded from "this
site"_http://www.sandia.gov/~sjplimp/download.html, so you can perform
the HTML conversion yourself to proofread your doc page. :l,ule
Note that the more clear and self-explanatory you make your doc and
README files, the more likely it is that users will try out your new
feature.
:line
:line
:link(Foo)
[(Foo)] Foo, Morefoo, and Maxfoo, J of Classic Potentials, 75, 345 (1997).
diff --git a/doc/Section_packages.html b/doc/Section_packages.html
index 613043b2e..af512bd2e 100644
--- a/doc/Section_packages.html
+++ b/doc/Section_packages.html
@@ -1,408 +1,422 @@
<HTML>
<CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> -
<A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_accelerate.html">Next
Section</A>
</CENTER>
<HR>
<H3>4. Packages
</H3>
+<P>This section gives a quick overview of the add-on packages that extend
+LAMMPS functionality.
+</P>
+4.1 <A HREF = "#pkg_1">Standard packages</A><BR>
+4.2 <A HREF = "#pkg_2">User packages</A> <BR>
+
<P>LAMMPS includes many optional packages, which are groups of files that
enable a specific set of features. For example, force fields for
molecular systems or granular systems are in packages. You can see
the list of all packages by typing "make package" from within the src
directory of the LAMMPS distribution.
</P>
-<P>See <A HREF = "Section_start.html#start_3">this section</A> of the manual for
+<P>See <A HREF = "Section_start.html#start_3">Section_start 3</A> of the manual for
details on how to include/exclude specific packages as part of the
LAMMPS build process, and for more details about the differences
between standard packages and user packages in LAMMPS.
</P>
<P>Below, the packages currently availabe in LAMMPS are listed. For
standard packages, just a one-line description is given. For user
packages, more details are provided.
</P>
-4.1 <A HREF = "#pkg_1">Standard packages</A><BR>
-4.2 <A HREF = "#pkg_2">User packages</A> <BR>
-
<HR>
<HR>
<H4><A NAME = "pkg_1"></A>4.1 Standard packages
</H4>
<P>The current list of standard packages is as follows:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD >Package</TD><TD > Description</TD><TD > Author(s)</TD><TD > Doc page</TD><TD > Example</TD><TD > Library</TD></TR>
<TR ALIGN="center"><TD >ASPHERE</TD><TD > aspherical particles</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_14">howto</A></TD><TD > ellipse</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >CLASS2</TD><TD > class 2 force fields</TD><TD > -</TD><TD > <A HREF = "pair_class2.html">pair_style lj/class2</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >COLLOID</TD><TD > colloidal particles</TD><TD > -</TD><TD > <A HREF = "atom_style.html">atom_style colloid</A></TD><TD > colloid</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >DIPOLE</TD><TD > point dipole particles</TD><TD > -</TD><TD > <A HREF = "pair_dipole.html">pair_style dipole/cut</A></TD><TD > dipole</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >FLD</TD><TD > Fast Lubrication Dynamics</TD><TD > Kumar & Bybee & Higdon (1)</TD><TD > <A HREF = "pair_lubricateU.html">pair_style lubricateU</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >GPU</TD><TD > GPU-enabled potentials</TD><TD > Mike Brown (ORNL)</TD><TD > <A HREF = "Section_accelerate.html#acc_3">accelerate</A></TD><TD > gpu</TD><TD > lib/gpu</TD></TR>
<TR ALIGN="center"><TD >GRANULAR</TD><TD > granular systems</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_6">howto</A></TD><TD > pour</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >KSPACE</TD><TD > long-range Coulombic solvers</TD><TD > -</TD><TD > <A HREF = "kspace_style.html">kspace_style</A></TD><TD > peptide</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >MANYBODY</TD><TD > many-body potentials</TD><TD > -</TD><TD > <A HREF = "pair_tersoff.html">pair_style tersoff</A></TD><TD > shear</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >MEAM</TD><TD > modified EAM potential</TD><TD > Greg Wagner (Sandia)</TD><TD > <A HREF = "pair_meam.html">pair_style meam</A></TD><TD > meam</TD><TD > lib/meam</TD></TR>
<TR ALIGN="center"><TD >MC</TD><TD > Monte Carlo options</TD><TD > -</TD><TD > <A HREF = "fix_gcmc.html">fix gcmc</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >MOLECULE</TD><TD > molecular system force fields</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_3">howto</A></TD><TD > peptide</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >OPT</TD><TD > optimized pair potentials</TD><TD > Fischer & Richie & Natoli (2)</TD><TD > <A HREF = "Section_accelerate.html#acc_1">howto</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >PERI</TD><TD > Peridynamics models</TD><TD > Mike Parks (Sandia)</TD><TD > <A HREF = "pair_peri.html">pair_style peri</A></TD><TD > peri</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >POEMS</TD><TD > coupled rigid body motion</TD><TD > Rudra Mukherjee (JPL)</TD><TD > <A HREF = "fix_poems.html">fix poems</A></TD><TD > rigid</TD><TD > lib/poems</TD></TR>
<TR ALIGN="center"><TD >REAX</TD><TD > ReaxFF potential</TD><TD > Aidan Thompson (Sandia)</TD><TD > <A HREF = "pair_reax.html">pair_style reax</A></TD><TD > reax</TD><TD > lib/reax</TD></TR>
<TR ALIGN="center"><TD >REPLICA</TD><TD > multi-replica methods</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_5">howto</A></TD><TD > tad</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >SHOCK</TD><TD > shock loading methods</TD><TD > -</TD><TD > <A HREF = "fix_msst.html">fix msst</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >SRD</TD><TD > stochastic rotation dynamics</TD><TD > -</TD><TD > <A HREF = "fix_srd.html">fix srd</A></TD><TD > srd</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >XTC</TD><TD > dumps in XTC format</TD><TD > -</TD><TD > <A HREF = "dump.html">dump</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >
</TD></TR></TABLE></DIV>
<P>The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
</P>
<P>(1) The FLD package was created by Amit Kumar and Michael Bybee from
Jonathan Higdon's group at UIUC.
</P>
<P>(2) The OPT package was created by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technolgy).
</P>
<P>The "Doc page" column links to either a portion of the
<A HREF = "Section_howto.html">Section_howto</A> of the manual, or an input script
command implemented as part of the package.
</P>
<P>The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory.
</P>
<P>The "Library" column lists an external library which must be built first and which LAMMPS links to when it is built. These are in the lib directory of the distribution. <A HREF = "Section_start.html#start_3_3">This section</A> of the manual gives details on the 2-step build process with external libraries.
</P>
<HR>
<HR>
<H4><A NAME = "pkg_2"></A>4.2 User packages
</H4>
<P>The current list of user-contributed packages is as follows:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD >Package</TD><TD > Description</TD><TD > Author(s)</TD><TD > Doc page</TD><TD > Example</TD><TD > Pic/movie</TD><TD > Library</TD></TR>
<TR ALIGN="center"><TD >USER-MISC</TD><TD > single-file contributions</TD><TD > USER-MISC/README</TD><TD > -</TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-ATC</TD><TD > atom-to-continuum coupling</TD><TD > Jones & Templeton & Zimmerman (2)</TD><TD > <A HREF = "fix_atc.html">fix atc</A></TD><TD > USER/atc</TD><TD > <A HREF = "http://lammps.sandia.gov/pictures.html#atc">atc</A></TD><TD > lib/atc</TD></TR>
<TR ALIGN="center"><TD >USER-AWPMD</TD><TD > wave-packet MD</TD><TD > Ilya Valuev (JIHT)</TD><TD > <A HREF = "pair_awpmd.html">pair_style awpmd/cut</A></TD><TD > USER/awpmd</TD><TD > -</TD><TD > lib/awpmd</TD></TR>
-<TR ALIGN="center"><TD >USER-CG-CMM</TD><TD > coarse-graining model</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "pair_cmm.html">pair_style cg/cmm</A></TD><TD > USER/cg-cmm</TD><TD > <A HREF = "http://lammps.sandia.gov/pictures.html#cg">cg</A></TD><TD > -</TD></TR>
+<TR ALIGN="center"><TD >USER-CG-CMM</TD><TD > coarse-graining model</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "pair_sdk.html">pair_style lj/sdk</A></TD><TD > USER/cg-cmm</TD><TD > <A HREF = "http://lammps.sandia.gov/pictures.html#cg">cg</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-CUDA</TD><TD > NVIDIA GPU styles</TD><TD > Christian Trott (U Tech Ilmenau)</TD><TD > <A HREF = "Section_accelerate.html#acc_4">accelerate</A></TD><TD > USER/cuda</TD><TD > -</TD><TD > lib/cuda</TD></TR>
<TR ALIGN="center"><TD >USER-EFF</TD><TD > electron force field</TD><TD > Andres Jaramillo-Botero (Caltech)</TD><TD > <A HREF = "pair_eff.html">pair_style eff/cut</A></TD><TD > USER/eff</TD><TD > <A HREF = "http://lammps.sandia.gov/movies.html#eff">eff</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-EWALDN</TD><TD > Ewald for 1/R^n</TD><TD > Pieter in' t Veld (BASF)</TD><TD > <A HREF = "kspace_style.html">kspace_style</A></TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-OMP</TD><TD > OpenMP threaded styles</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "Section_accelerate.html#acc_2">accelerate</A></TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-REAXC</TD><TD > C version of ReaxFF</TD><TD > Metin Aktulga (LBNL)</TD><TD > <A HREF = "pair_reax_c.html">pair_style reaxc</A></TD><TD > reax</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-SPH</TD><TD > smoothed particle hydrodynamics</TD><TD > Georg Ganzenmuller (EMI)</TD><TD > <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">SPH_LAMMPS_userguide.pdf</A></TD><TD > USER/sph</TD><TD > <A HREF = "http://lammps.sandia.gov/movies.html#sph">sph</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >
</TD></TR></TABLE></DIV>
<P>The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
</P>
<P>(2) The ATC package was created by Reese Jones, Jeremy Templeton, and Jon Zimmerman (Sandia).
</P>
<P>The "Doc page" column links to either a portion of the
<A HREF = "Section_howto.html">Section_howto</A> of the manual, or an input script
command implemented as part of the package, or to additional
documentation provided witht he package.
</P>
<P>The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory. USER/cuda
refers to the examples/USER/cuda directory.
</P>
<P>The "Library" column lists an external library which must be built
first and which LAMMPS links to when it is built. These are in the
lib directory of the distribution. <A HREF = "Section_start.html#start_3_3">This
section</A> of the manual gives details on
the 2-step build process with external libraries.
</P>
<P>More details on each package, from the USER-blah/README file
is given below.
</P>
<HR>
<H4>USER-MISC package
</H4>
<P>The files in this package are a potpourri of (mostly) unrelated
features contributed to LAMMPS by users. Each feature is a single
pair of files (*.cpp and *.h).
</P>
<P>More information about each feature can be found by reading its doc
page in the LAMMPS doc directory. The doc page which lists all LAMMPS
input script commands is as follows:
</P>
<P><A HREF = "Section_commands.html#cmd_5">Section_commands</A>
</P>
<P>User-contributed features are listed at the bottom of the fix,
compute, pair, etc sections.
</P>
<P>The list of features and author of each is given in the
src/USER-MISC/README file.
</P>
<P>You should contact the author directly if you have specific questions
about the feature or its coding.
</P>
<HR>
<H4>USER-ATC package
</H4>
<P>This package implements a "fix atc" command which can be used in a
LAMMPS input script. This fix can be employed to either do concurrent
coupling of MD with FE-based physics surrogates or on-the-fly
post-processing of atomic information to continuum fields.
</P>
<P>See the doc page for the fix atc command to get started. At the
bottom of the doc page are many links to additional documentation
contained in the doc/USER/atc directory.
</P>
<P>There are example scripts for using this package in examples/USER/atc.
</P>
<P>This package uses an external library in lib/atc which must be
compiled before making LAMMPS. See the lib/atc/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The primary people who created this package are Reese Jones (rjones at
sandia.gov), Jeremy Templeton (jatempl at sandia.gov) and Jon
Zimmerman (jzimmer at sandia.gov) at Sandia. Contact them directly if
you have questions.
</P>
<HR>
<H4>USER-AWPMD package
</H4>
<P>This package contains a LAMMPS implementation of the Antisymmetrized
Wave Packet Molecular Dynamics (AWPMD) method.
</P>
<P>See the doc page for the pair_style awpmd/cut command to get started.
</P>
<P>There are example scripts for using this package in examples/USER/awpmd.
</P>
<P>This package uses an external library in lib/awpmd which must be
compiled before making LAMMPS. See the lib/awpmd/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The person who created this package is Ilya Valuev at the JIHT in
Russia (valuev at physik.hu-berlin.de). Contact him directly if you
have questions.
</P>
<HR>
<H4>USER-CG-CMM package
</H4>
-<P>This package implements 4 commands which can be used in a LAMMPS input
+<P>This package implements 3 commands which can be used in a LAMMPS input
script:
</P>
-<UL><LI>pair_style cg/cmm
-<LI>pair_style cg/cmm/coul/cut
-<LI>pair_style cg/cmm/coul/long
-<LI>angle_style cg/cmm
+<UL><LI>pair_style lj/sdk
+<LI>pair_style lj/sdk/coul/long
+<LI>angle_style sdk
</UL>
<P>These styles allow coarse grained MD simulations with the
parametrization of Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007)
-(cg/cmm), with extensions to simulate ionic liquids, electrolytes,
-lipids and charged amino acids (to be published soon).
+(SDK), with extensions to simulate ionic liquids, electrolytes, lipids
+and charged amino acids.
</P>
<P>See the doc pages for these commands for details.
</P>
<P>There are example scripts for using this package in
examples/USER/cg-cmm.
</P>
+<P>This is the second generation implementation reducing the the clutter
+of the previous version. For many systems with electrostatics, it will
+be faster to use pair_style hybrid/overlay with lj/sdk and coul/long
+instead of the combined lj/sdk/coul/long style. since the number of
+charged atom types is usually small. For any other coulomb
+interactions this is now required. To exploit this property, the use
+of the kspace_style pppm/cg is recommended over regular pppm. For all
+new styles, input file backward compatibility is provided. The old
+implementation is still available through appending the /old
+suffix. These will be discontinued and removed after the new
+implementation has been fully validated.
+</P>
<P>The current version of this package should be considered beta
-quality. The CG potentials work correctly and well, but there will be
-optimizations, cleanups and additional tools to aid in setting up and
-analyzing simulations with this package added in the next months.
+quality. The CG potentials work correctly for "normal" situations, but
+have not been testing with all kinds of potential parameters and
+simulation systems.
</P>
<P>The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-CUDA package
</H4>
<P>This package provides acceleration of various LAMMPS pair styles, fix
styles, compute styles, and long-range Coulombics via PPPM for NVIDIA
GPUs.
</P>
<P>See this section of the manual to get started:
</P>
<P><A HREF = "Section_accelerate.html#acc_4">Section_accelerate</A>
</P>
<P>There are example scripts for using this package in
examples/USER/cuda.
</P>
<P>This package uses an external library in lib/cuda which must be
compiled before making LAMMPS. See the lib/cuda/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The person who created this package is Christian Trott at the
University of Technology Ilmenau, Germany (christian.trott at
tu-ilmenau.de). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-EFF package
</H4>
<P>This package contains a LAMMPS implementation of the electron Force
Field (eFF) currently under development at Caltech, as described in
A. Jaramillo-Botero, J. Su, Q. An, and W.A. Goddard III, JCC,
2010. The eFF potential was first introduced by Su and Goddard, in
2007.
</P>
<P>eFF can be viewed as an approximation to QM wave packet dynamics and
Fermionic molecular dynamics, combining the ability of electronic
structure methods to describe atomic structure, bonding, and chemistry
in materials, and of plasma methods to describe nonequilibrium
dynamics of large systems with a large number of highly excited
electrons. We classify it as a mixed QM-classical approach rather than
a conventional force field method, which introduces QM-based terms (a
spin-dependent repulsion term to account for the Pauli exclusion
principle and the electron wavefunction kinetic energy associated with
the Heisenberg principle) that reduce, along with classical
electrostatic terms between nuclei and electrons, to the sum of a set
of effective pairwise potentials. This makes eFF uniquely suited to
simulate materials over a wide range of temperatures and pressures
where electronically excited and ionized states of matter can occur
and coexist.
</P>
<P>The necessary customizations to the LAMMPS core are in place to
enable the correct handling of explicit electron properties during
minimization and dynamics.
</P>
<P>See the doc page for the pair_style eff/cut command to get started.
</P>
<P>There are example scripts for using this package in
examples/USER/eff.
</P>
<P>There are auxiliary tools for using this package in tools/eff.
</P>
<P>The person who created this package is Andres Jaramillo-Botero at
CalTech (ajaramil at wag.caltech.edu). Contact him directly if you
have questions.
</P>
<HR>
<H4>USER-EWALDN package
</H4>
<P>This package implements 3 commands which can be used in a LAMMPS input
script: pair_style lj/coul, pair_style buck/coul, and kspace_style
ewald/n.
</P>
<P>The "kspace_style ewald/n" command is similar to standard Ewald for
charges, but also enables the Lennard-Jones interaction, or any 1/r^N
interaction to be of infinite extent, instead of being cutoff. LAMMPS
pair potentials for long-range Coulombic interactions, such as
lj/cut/coul/long can be used with ewald/n. The two new pair_style
commands provide the modifications for the short-range LJ and
Buckingham interactions that can also be used with ewald/n.
</P>
<P>Another advantage of kspace_style ewald/n is that it can be used with
non-orthogonal (triclinic symmetry) simulation boxes, either for just
long-range Coulombic interactions, or for both Coulombic and 1/r^N LJ
or Buckingham, which is not currently possible for other kspace styles
such as PPPM and ewald.
</P>
<P>See the doc pages for these commands for details.
</P>
<P>The person who created these files is Pieter in' t Veld while at
Sandia. He is now at BASF (pieter.intveld at basf.com). Contact him
directly if you have questions.
</P>
<HR>
<H4>USER-OMP package
</H4>
<P>This package provides OpenMP multi-threading support and
other optimizations of various LAMMPS pair styles, dihedral
styles, and fix styles.
</P>
<P>See this section of the manual to get started:
</P>
<P><A HREF = "Section_accelerate.html#acc_2">Section_accelerate</A>
</P>
<P>The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-REAXC package
</H4>
<P>This package contains a implementation for LAMMPS of the ReaxFF force
field. ReaxFF uses distance-dependent bond-order functions to
represent the contributions of chemical bonding to the potential
energy. It was originally developed by Adri van Duin and the Goddard
group at CalTech.
</P>
<P>The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in
C, should give identical or very similar results to pair_style reax,
which is a ReaxFF implementation on top of a Fortran library, a
version of which library was originally authored by Adri van Duin.
</P>
<P>The reax/c version should be somewhat faster and more scalable,
particularly with respect to the charge equilibration calculation. It
should also be easier to build and use since there are no complicating
issues with Fortran memory allocation or linking to a Fortran library.
</P>
<P>For technical details about this implemention of ReaxFF, see
this paper:
</P>
<P>Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods
and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty,
S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011).
</P>
<P>See the doc page for the pair_style reax/c command for details
of how to use it in LAMMPS.
</P>
<P>The person who created this package is Hasan Metin Aktulga (hmaktulga
at lbl.gov), while at Purdue University. Contact him directly, or
Aidan Thompson at Sandia (athomps at sandia.gov), if you have
questions.
</P>
<HR>
<H4>USER-SPH package
</H4>
<P>This package implements smoothed particle hydrodynamics (SPH) in
LAMMPS. Currently, the package has the following features:
</P>
<P>* Tait, ideal gas, Lennard-Jones equation of states, full support for
complete (i.e. internal-energy dependent) equations of state
* plain or Monaghans XSPH integration of the equations of motion
* density continuity or density summation to propagate the density field
* commands to set internal energy and density of particles from the
input script
* output commands to access internal energy and density for dumping and
thermo output
</P>
<P>See the file doc/USER/sph/SPH_LAMMPS_userguide.pdf to get started.
</P>
<P>There are example scripts for using this package in examples/USER/sph.
</P>
<P>The person who created this package is Georg Ganzenmuller at the
Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute in
Germany (georg.ganzenmueller at emi.fhg.de). Contact him directly if
you have questions.
</P>
</HTML>
diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt
index aa7e7fb42..425373d7a 100644
--- a/doc/Section_packages.txt
+++ b/doc/Section_packages.txt
@@ -1,394 +1,408 @@
"Previous Section"_Section_commands.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_accelerate.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
4. Packages :h3
+This section gives a quick overview of the add-on packages that extend
+LAMMPS functionality.
+
+4.1 "Standard packages"_#pkg_1
+4.2 "User packages"_#pkg_2 :all(b)
+
LAMMPS includes many optional packages, which are groups of files that
enable a specific set of features. For example, force fields for
molecular systems or granular systems are in packages. You can see
the list of all packages by typing "make package" from within the src
directory of the LAMMPS distribution.
-See "this section"_Section_start.html#start_3 of the manual for
+See "Section_start 3"_Section_start.html#start_3 of the manual for
details on how to include/exclude specific packages as part of the
LAMMPS build process, and for more details about the differences
between standard packages and user packages in LAMMPS.
Below, the packages currently availabe in LAMMPS are listed. For
standard packages, just a one-line description is given. For user
packages, more details are provided.
-4.1 "Standard packages"_#pkg_1
-4.2 "User packages"_#pkg_2 :all(b)
-
:line
:line
4.1 Standard packages :h4,link(pkg_1)
The current list of standard packages is as follows:
Package, Description, Author(s), Doc page, Example, Library
ASPHERE, aspherical particles, -, "howto"_Section_howto.html#howto_14, ellipse, -
CLASS2, class 2 force fields, -, "pair_style lj/class2"_pair_class2.html, -, -
COLLOID, colloidal particles, -, "atom_style colloid"_atom_style.html, colloid, -
DIPOLE, point dipole particles, -, "pair_style dipole/cut"_pair_dipole.html, dipole, -
FLD, Fast Lubrication Dynamics, Kumar & Bybee & Higdon (1), "pair_style lubricateU"_pair_lubricateU.html, -, -
GPU, GPU-enabled potentials, Mike Brown (ORNL), "accelerate"_Section_accelerate.html#acc_3, gpu, lib/gpu
GRANULAR, granular systems, -, "howto"_Section_howto.html#howto_6, pour, -
KSPACE, long-range Coulombic solvers, -, "kspace_style"_kspace_style.html, peptide, -
MANYBODY, many-body potentials, -, "pair_style tersoff"_pair_tersoff.html, shear, -
MEAM, modified EAM potential, Greg Wagner (Sandia), "pair_style meam"_pair_meam.html, meam, lib/meam
MC, Monte Carlo options, -, "fix gcmc"_fix_gcmc.html, -, -
MOLECULE, molecular system force fields, -, "howto"_Section_howto.html#howto_3, peptide, -
OPT, optimized pair potentials, Fischer & Richie & Natoli (2), "howto"_Section_accelerate.html#acc_1, -, -
PERI, Peridynamics models, Mike Parks (Sandia), "pair_style peri"_pair_peri.html, peri, -
POEMS, coupled rigid body motion, Rudra Mukherjee (JPL), "fix poems"_fix_poems.html, rigid, lib/poems
REAX, ReaxFF potential, Aidan Thompson (Sandia), "pair_style reax"_pair_reax.html, reax, lib/reax
REPLICA, multi-replica methods, -, "howto"_Section_howto.html#howto_5, tad, -
SHOCK, shock loading methods, -, "fix msst"_fix_msst.html, -, -
SRD, stochastic rotation dynamics, -, "fix srd"_fix_srd.html, srd, -
XTC, dumps in XTC format, -, "dump"_dump.html, -, -
:tb(ea=c)
The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
(1) The FLD package was created by Amit Kumar and Michael Bybee from
Jonathan Higdon's group at UIUC.
(2) The OPT package was created by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technolgy).
The "Doc page" column links to either a portion of the
"Section_howto"_Section_howto.html of the manual, or an input script
command implemented as part of the package.
The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory.
The "Library" column lists an external library which must be built first and which LAMMPS links to when it is built. These are in the lib directory of the distribution. "This section"_Section_start.html#start_3_3 of the manual gives details on the 2-step build process with external libraries.
:line
:line
4.2 User packages :h4,link(pkg_2)
The current list of user-contributed packages is as follows:
Package, Description, Author(s), Doc page, Example, Pic/movie, Library
USER-MISC, single-file contributions, USER-MISC/README, -, -, -, -
USER-ATC, atom-to-continuum coupling, Jones & Templeton & Zimmerman (2), "fix atc"_fix_atc.html, USER/atc, "atc"_atc, lib/atc
USER-AWPMD, wave-packet MD, Ilya Valuev (JIHT), "pair_style awpmd/cut"_pair_awpmd.html, USER/awpmd, -, lib/awpmd
-USER-CG-CMM, coarse-graining model, Axel Kohlmeyer (Temple U), "pair_style cg/cmm"_pair_cmm.html, USER/cg-cmm, "cg"_cg, -
+USER-CG-CMM, coarse-graining model, Axel Kohlmeyer (Temple U), "pair_style lj/sdk"_pair_sdk.html, USER/cg-cmm, "cg"_cg, -
USER-CUDA, NVIDIA GPU styles, Christian Trott (U Tech Ilmenau), "accelerate"_Section_accelerate.html#acc_4, USER/cuda, -, lib/cuda
USER-EFF, electron force field, Andres Jaramillo-Botero (Caltech), "pair_style eff/cut"_pair_eff.html, USER/eff, "eff"_eff, -
USER-EWALDN, Ewald for 1/R^n, Pieter in' t Veld (BASF), "kspace_style"_kspace_style.html, -, -, -
USER-OMP, OpenMP threaded styles, Axel Kohlmeyer (Temple U), "accelerate"_Section_accelerate.html#acc_2, -, -, -
USER-REAXC, C version of ReaxFF, Metin Aktulga (LBNL), "pair_style reaxc"_pair_reax_c.html, reax, -, -
USER-SPH, smoothed particle hydrodynamics, Georg Ganzenmuller (EMI), "SPH_LAMMPS_userguide.pdf"_USER/sph/SPH_LAMMPS_userguide.pdf, USER/sph, "sph"_sph, -
:tb(ea=c)
:link(atc,http://lammps.sandia.gov/pictures.html#atc)
:link(cg,http://lammps.sandia.gov/pictures.html#cg)
:link(eff,http://lammps.sandia.gov/movies.html#eff)
:link(sph,http://lammps.sandia.gov/movies.html#sph)
The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
(2) The ATC package was created by Reese Jones, Jeremy Templeton, and Jon Zimmerman (Sandia).
The "Doc page" column links to either a portion of the
"Section_howto"_Section_howto.html of the manual, or an input script
command implemented as part of the package, or to additional
documentation provided witht he package.
The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory. USER/cuda
refers to the examples/USER/cuda directory.
The "Library" column lists an external library which must be built
first and which LAMMPS links to when it is built. These are in the
lib directory of the distribution. "This
section"_Section_start.html#start_3_3 of the manual gives details on
the 2-step build process with external libraries.
More details on each package, from the USER-blah/README file
is given below.
:line
USER-MISC package :h4
The files in this package are a potpourri of (mostly) unrelated
features contributed to LAMMPS by users. Each feature is a single
pair of files (*.cpp and *.h).
More information about each feature can be found by reading its doc
page in the LAMMPS doc directory. The doc page which lists all LAMMPS
input script commands is as follows:
"Section_commands"_Section_commands.html#cmd_5
User-contributed features are listed at the bottom of the fix,
compute, pair, etc sections.
The list of features and author of each is given in the
src/USER-MISC/README file.
You should contact the author directly if you have specific questions
about the feature or its coding.
:line
USER-ATC package :h4
This package implements a "fix atc" command which can be used in a
LAMMPS input script. This fix can be employed to either do concurrent
coupling of MD with FE-based physics surrogates or on-the-fly
post-processing of atomic information to continuum fields.
See the doc page for the fix atc command to get started. At the
bottom of the doc page are many links to additional documentation
contained in the doc/USER/atc directory.
There are example scripts for using this package in examples/USER/atc.
This package uses an external library in lib/atc which must be
compiled before making LAMMPS. See the lib/atc/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The primary people who created this package are Reese Jones (rjones at
sandia.gov), Jeremy Templeton (jatempl at sandia.gov) and Jon
Zimmerman (jzimmer at sandia.gov) at Sandia. Contact them directly if
you have questions.
:line
USER-AWPMD package :h4
This package contains a LAMMPS implementation of the Antisymmetrized
Wave Packet Molecular Dynamics (AWPMD) method.
See the doc page for the pair_style awpmd/cut command to get started.
There are example scripts for using this package in examples/USER/awpmd.
This package uses an external library in lib/awpmd which must be
compiled before making LAMMPS. See the lib/awpmd/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The person who created this package is Ilya Valuev at the JIHT in
Russia (valuev at physik.hu-berlin.de). Contact him directly if you
have questions.
:line
USER-CG-CMM package :h4
-This package implements 4 commands which can be used in a LAMMPS input
+This package implements 3 commands which can be used in a LAMMPS input
script:
-pair_style cg/cmm
-pair_style cg/cmm/coul/cut
-pair_style cg/cmm/coul/long
-angle_style cg/cmm :ul
+pair_style lj/sdk
+pair_style lj/sdk/coul/long
+angle_style sdk :ul
These styles allow coarse grained MD simulations with the
parametrization of Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007)
-(cg/cmm), with extensions to simulate ionic liquids, electrolytes,
-lipids and charged amino acids (to be published soon).
+(SDK), with extensions to simulate ionic liquids, electrolytes, lipids
+and charged amino acids.
See the doc pages for these commands for details.
There are example scripts for using this package in
examples/USER/cg-cmm.
+This is the second generation implementation reducing the the clutter
+of the previous version. For many systems with electrostatics, it will
+be faster to use pair_style hybrid/overlay with lj/sdk and coul/long
+instead of the combined lj/sdk/coul/long style. since the number of
+charged atom types is usually small. For any other coulomb
+interactions this is now required. To exploit this property, the use
+of the kspace_style pppm/cg is recommended over regular pppm. For all
+new styles, input file backward compatibility is provided. The old
+implementation is still available through appending the /old
+suffix. These will be discontinued and removed after the new
+implementation has been fully validated.
+
The current version of this package should be considered beta
-quality. The CG potentials work correctly and well, but there will be
-optimizations, cleanups and additional tools to aid in setting up and
-analyzing simulations with this package added in the next months.
+quality. The CG potentials work correctly for "normal" situations, but
+have not been testing with all kinds of potential parameters and
+simulation systems.
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
:line
USER-CUDA package :h4
This package provides acceleration of various LAMMPS pair styles, fix
styles, compute styles, and long-range Coulombics via PPPM for NVIDIA
GPUs.
See this section of the manual to get started:
"Section_accelerate"_Section_accelerate.html#acc_4
There are example scripts for using this package in
examples/USER/cuda.
This package uses an external library in lib/cuda which must be
compiled before making LAMMPS. See the lib/cuda/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The person who created this package is Christian Trott at the
University of Technology Ilmenau, Germany (christian.trott at
tu-ilmenau.de). Contact him directly if you have questions.
:line
USER-EFF package :h4
This package contains a LAMMPS implementation of the electron Force
Field (eFF) currently under development at Caltech, as described in
A. Jaramillo-Botero, J. Su, Q. An, and W.A. Goddard III, JCC,
2010. The eFF potential was first introduced by Su and Goddard, in
2007.
eFF can be viewed as an approximation to QM wave packet dynamics and
Fermionic molecular dynamics, combining the ability of electronic
structure methods to describe atomic structure, bonding, and chemistry
in materials, and of plasma methods to describe nonequilibrium
dynamics of large systems with a large number of highly excited
electrons. We classify it as a mixed QM-classical approach rather than
a conventional force field method, which introduces QM-based terms (a
spin-dependent repulsion term to account for the Pauli exclusion
principle and the electron wavefunction kinetic energy associated with
the Heisenberg principle) that reduce, along with classical
electrostatic terms between nuclei and electrons, to the sum of a set
of effective pairwise potentials. This makes eFF uniquely suited to
simulate materials over a wide range of temperatures and pressures
where electronically excited and ionized states of matter can occur
and coexist.
The necessary customizations to the LAMMPS core are in place to
enable the correct handling of explicit electron properties during
minimization and dynamics.
See the doc page for the pair_style eff/cut command to get started.
There are example scripts for using this package in
examples/USER/eff.
There are auxiliary tools for using this package in tools/eff.
The person who created this package is Andres Jaramillo-Botero at
CalTech (ajaramil at wag.caltech.edu). Contact him directly if you
have questions.
:line
USER-EWALDN package :h4
This package implements 3 commands which can be used in a LAMMPS input
script: pair_style lj/coul, pair_style buck/coul, and kspace_style
ewald/n.
The "kspace_style ewald/n" command is similar to standard Ewald for
charges, but also enables the Lennard-Jones interaction, or any 1/r^N
interaction to be of infinite extent, instead of being cutoff. LAMMPS
pair potentials for long-range Coulombic interactions, such as
lj/cut/coul/long can be used with ewald/n. The two new pair_style
commands provide the modifications for the short-range LJ and
Buckingham interactions that can also be used with ewald/n.
Another advantage of kspace_style ewald/n is that it can be used with
non-orthogonal (triclinic symmetry) simulation boxes, either for just
long-range Coulombic interactions, or for both Coulombic and 1/r^N LJ
or Buckingham, which is not currently possible for other kspace styles
such as PPPM and ewald.
See the doc pages for these commands for details.
The person who created these files is Pieter in' t Veld while at
Sandia. He is now at BASF (pieter.intveld at basf.com). Contact him
directly if you have questions.
:line
USER-OMP package :h4
This package provides OpenMP multi-threading support and
other optimizations of various LAMMPS pair styles, dihedral
styles, and fix styles.
See this section of the manual to get started:
"Section_accelerate"_Section_accelerate.html#acc_2
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
:line
USER-REAXC package :h4
This package contains a implementation for LAMMPS of the ReaxFF force
field. ReaxFF uses distance-dependent bond-order functions to
represent the contributions of chemical bonding to the potential
energy. It was originally developed by Adri van Duin and the Goddard
group at CalTech.
The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in
C, should give identical or very similar results to pair_style reax,
which is a ReaxFF implementation on top of a Fortran library, a
version of which library was originally authored by Adri van Duin.
The reax/c version should be somewhat faster and more scalable,
particularly with respect to the charge equilibration calculation. It
should also be easier to build and use since there are no complicating
issues with Fortran memory allocation or linking to a Fortran library.
For technical details about this implemention of ReaxFF, see
this paper:
Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods
and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty,
S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011).
See the doc page for the pair_style reax/c command for details
of how to use it in LAMMPS.
The person who created this package is Hasan Metin Aktulga (hmaktulga
at lbl.gov), while at Purdue University. Contact him directly, or
Aidan Thompson at Sandia (athomps at sandia.gov), if you have
questions.
:line
USER-SPH package :h4
This package implements smoothed particle hydrodynamics (SPH) in
LAMMPS. Currently, the package has the following features:
* Tait, ideal gas, Lennard-Jones equation of states, full support for
complete (i.e. internal-energy dependent) equations of state
* plain or Monaghans XSPH integration of the equations of motion
* density continuity or density summation to propagate the density field
* commands to set internal energy and density of particles from the
input script
* output commands to access internal energy and density for dumping and
thermo output
See the file doc/USER/sph/SPH_LAMMPS_userguide.pdf to get started.
There are example scripts for using this package in examples/USER/sph.
The person who created this package is Georg Ganzenmuller at the
Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute in
Germany (georg.ganzenmueller at emi.fhg.de). Contact him directly if
you have questions.
diff --git a/doc/Section_python.html b/doc/Section_python.html
index 92de682b0..5f0952120 100644
--- a/doc/Section_python.html
+++ b/doc/Section_python.html
@@ -1,676 +1,679 @@
<HTML>
<CENTER><A HREF = "Section_modify.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_errors.html">Next Section</A>
</CENTER>
<HR>
<H3>11. Python interface to LAMMPS
</H3>
+<P>This section describes how to build and use LAMMPS via a Python
+interface.
+</P>
+<UL><LI>11.1 <A HREF = "#py_1">Extending Python with a serial version of LAMMPS</A>
+<LI>11.2 <A HREF = "#py_2">Creating a shared MPI library</A>
+<LI>11.3 <A HREF = "#py_3">Extending Python with a parallel version of LAMMPS</A>
+<LI>11.4 <A HREF = "#py_4">Extending Python with MPI</A>
+<LI>11.5 <A HREF = "#py_5">Testing the Python-LAMMPS interface</A>
+<LI>11.6 <A HREF = "#py_6">Using LAMMPS from Python</A>
+<LI>11.7 <A HREF = "#py_7">Example Python scripts that use LAMMPS</A>
+</UL>
<P>The LAMMPS distribution includes some Python code in its python
directory which wraps the library interface to LAMMPS. This makes it
is possible to run LAMMPS, invoke LAMMPS commands or give it an input
script, extract LAMMPS results, an modify internal LAMMPS variables,
either from a Python script or interactively from a Python prompt.
</P>
<P><A HREF = "http://www.python.org">Python</A> is a powerful scripting and programming
language which can be used to wrap software like LAMMPS and other
packages. It can be used to glue multiple pieces of software
together, e.g. to run a coupled or multiscale model. See <A HREF = "Section_howto.html#howto_10">this
section</A> of the manual and the couple
directory of the distribution for more ideas about coupling LAMMPS to
-other codes. See <A HREF = "Section_start.html#start_4">this section</A> about how
-to build LAMMPS as a library, and <A HREF = "Section_howto.html#howto_19">this
+other codes. See <A HREF = "Section_start.html#start_4">Section_start 4</A> about
+how to build LAMMPS as a library, and <A HREF = "Section_howto.html#howto_19">this
section</A> for a description of the library
interface provided in src/library.cpp and src/library.h and how to
extend it for your needs. As described below, that interface is what
is exposed to Python. It is designed to be easy to add functions to.
This has the effect of extending the Python inteface as well. See
details below.
</P>
<P>By using the Python interface LAMMPS can also be coupled with a GUI or
visualization tools that display graphs or animations in real time as
LAMMPS runs. Examples of such scripts are inlcluded in the python
directory.
</P>
<P>Two advantages of using Python are how concise the language is and
that it can be run interactively, enabling rapid development and
debugging of programs. If you use it to mostly invoke costly
operations within LAMMPS, such as running a simulation for a
reasonable number of timesteps, then the overhead cost of invoking
LAMMPS thru Python will be negligible.
</P>
<P>Before using LAMMPS from a Python script, the Python on your machine
must be "extended" to include an interface to the LAMMPS library. If
your Python script will invoke MPI operations, you will also need to
extend your Python with an interface to MPI itself.
</P>
<P>Thus you should first decide how you intend to use LAMMPS from Python.
There are 3 options:
</P>
<P>(1) Use LAMMPS on a single processor running Python.
</P>
<P>(2) Use LAMMPS in parallel, where each processor runs Python, but your
Python program does not use MPI.
</P>
<P>(3) Use LAMMPS in parallel, where each processor runs Python, and your
Python script also makes MPI calls through a Python/MPI interface.
</P>
<P>Note that for (2) and (3) you will not be able to use Python
interactively by typing commands and getting a response. This is
because you will have multiple instances of Python running (e.g. on a
parallel machine) and they cannot all read what you type.
</P>
<P>Working in mode (1) does not require your machine to have MPI
installed. You should extend your Python with a serial version of
LAMMPS and the dummy MPI library provided with LAMMPS. See
instructions below on how to do this.
</P>
<P>Working in mode (2) requires your machine to have an MPI library
installed, but your Python does not need to be extended with MPI
itself. The MPI library must be a shared library (e.g. a *.so file on
Linux) which is not typically created when MPI is built/installed.
See instruction below on how to do this. You should extend your
Python with the a parallel versionn of LAMMPS which will use the
shared MPI system library. See instructions below on how to do this.
</P>
<P>Working in mode (3) requires your machine to have MPI installed (as a
shared library as in (2)). You must also extend your Python with a
parallel version of LAMMPS (same as in (2)) and with MPI itself, via
one of several available Python/MPI packages. See instructions below
on how to do the latter task.
</P>
<P>Several of the following sub-sections cover the rest of the Python
setup discussion. The next to last sub-section describes the Python
syntax used to invoke LAMMPS. The last sub-section describes example
Python scripts included in the python directory.
</P>
-<UL><LI>11.1 <A HREF = "#py_1">Extending Python with a serial version of LAMMPS</A>
-<LI>11.2 <A HREF = "#py_2">Creating a shared MPI library</A>
-<LI>11.3 <A HREF = "#py_3">Extending Python with a parallel version of LAMMPS</A>
-<LI>11.4 <A HREF = "#py_4">Extending Python with MPI</A>
-<LI>11.5 <A HREF = "#py_5">Testing the Python-LAMMPS interface</A>
-<LI>11.6 <A HREF = "#py_6">Using LAMMPS from Python</A>
-<LI>11.7 <A HREF = "#py_7">Example Python scripts that use LAMMPS</A>
-</UL>
<P>Before proceeding, there are 2 items to note.
</P>
<P>(1) The provided Python wrapper for LAMMPS uses the amazing and
magical (to me) "ctypes" package in Python, which auto-generates the
interface code needed between Python and a set of C interface routines
for a library. Ctypes is part of standard Python for versions 2.5 and
later. You can check which version of Python you have installed, by
simply typing "python" at a shell prompt.
</P>
<P>(2) Any library wrapped by Python, including LAMMPS, must be built as
a shared library (e.g. a *.so file on Linux and not a *.a file). The
python/setup_serial.py and setup.py scripts do this build for LAMMPS
itself (described below). But if you have LAMMPS configured to use
additional packages that have their own libraries, then those
libraries must also be shared libraries. E.g. MPI, FFTW, or any of
the libraries in lammps/lib. When you build LAMMPS as a stand-alone
code, you are not building shared versions of these libraries.
</P>
<P>The discussion below describes how to create a shared MPI library. I
suggest you start by configuing LAMMPS without packages installed that
require any libraries besides MPI. See <A HREF = "Section_start.html#start_3">this
section</A> of the manual for a discussion of
LAMMPS pacakges. E.g. do not use the KSPACE, GPU, MEAM, POEMS, or
REAX packages.
</P>
<P>If you are successfully follow the steps belwo to build the Python
wrappers and use this version of LAMMPS through Python, you can then
take the next step of adding LAMMPS packages that use additional
libraries. This will require you to build a shared library for that
package's library, similar to what is described below for MPI. It
will also require you to edit the python/setup_serial.py or setup.py
scripts to enable Python to access those libraries when it builds the
LAMMPS wrapper.
</P>
<HR>
<HR>
<A NAME = "py_1"></A><H4>11.1 Extending Python with a serial version of LAMMPS
</H4>
<P>From the python directory in the LAMMPS distribution, type
</P>
<PRE>python setup_serial.py build
</PRE>
<P>and then one of these commands:
</P>
<PRE>sudo python setup_serial.py install
python setup_serial.py install --home=~/foo
</PRE>
<P>The "build" command should compile all the needed LAMMPS files,
including its dummy MPI library. The first "install" command will put
the needed files in your Python's site-packages sub-directory, so that
Python can load them. For example, if you installed Python yourself
on a Linux machine, it would typically be somewhere like
/usr/local/lib/python2.5/site-packages. Installing Python packages
this way often requires you to be able to write to the Python
directories, which may require root priveleges, hence the "sudo"
prefix. If this is not the case, you can drop the "sudo".
</P>
<P>Alternatively, you can install the LAMMPS files (or any other Python
packages) in your own user space. The second "install" command does
this, where you should replace "foo" with your directory of choice.
</P>
<P>If these commands are successful, a <I>lammps.py</I> and
<I>_lammps_serial.so</I> file will be put in the appropriate directory.
</P>
<HR>
<A NAME = "py_2"></A><H4>11.2 Creating a shared MPI library
</H4>
<P>A shared library is one that is dynamically loadable, which is what
Python requires. On Linux this is a library file that ends in ".so",
not ".a". Such a shared library is normally not built if you
installed MPI yourself, but it is easy to do. Here is how to do it
for <A HREF = "http://www-unix.mcs.anl.gov/mpi">MPICH</A>, a popular open-source version of MPI, distributed
by Argonne National Labs. From within the mpich directory, type
</P>
-<PRE>./configure --enable-sharedlib=gcc
+<PRE>./configure --enable-shared
make
make install
</PRE>
<P>You may need to use "sudo make install" in place of the last line.
The end result should be the file libmpich.so in /usr/local/lib.
</P>
<P>IMPORTANT NOTE: If the file libmpich.a already exists in your
installation directory (e.g. /usr/local/lib), you will now have both a
static and shared MPI library. This will be fine for running LAMMPS
from Python since it only uses the shared library. But if you now try
to build LAMMPS by itself as a stand-alone program (cd lammps/src;
make foo) or build other codes that expect to link against libmpich.a,
-then those builds will typically fail if the linker uses libmpich.so
-instead. This means you will need to remove the file
+then those builds may fail if the linker uses libmpich.so instead. If
+this happens, it means you will need to remove the file
/usr/local/lib/libmich.so before building LAMMPS again as a
stand-alone code.
</P>
<HR>
<A NAME = "py_3"></A><H4>11.3 Extending Python with a parallel version of LAMMPS
</H4>
<P>From the python directory, type
</P>
<PRE>python setup.py build
</PRE>
<P>and then one of these commands:
</P>
<PRE>sudo python setup.py install
python setup.py install --home=~/foo
</PRE>
<P>The "build" command should compile all the needed LAMMPS C++ files,
which will require MPI to be installed on your system. This means it
must find both the header file mpi.h and a shared library file,
e.g. libmpich.so if the MPICH version of MPI is installed. See the
preceding section for how to create a shared library version of MPI if
it does not exist. You may need to adjust the "include_dirs" and
"library_dirs" and "libraries" fields in python/setup.py to
insure the Python build finds all the files it needs.
</P>
<P>The first "install" command will put the needed files in your Python's
site-packages sub-directory, so that Python can load them. For
example, if you installed Python yourself on a Linux machine, it would
typically be somewhere like /usr/local/lib/python2.5/site-packages.
Installing Python packages this way often requires you to be able to
write to the Python directories, which may require root priveleges,
hence the "sudo" prefix. If this is not the case, you can drop the
"sudo".
</P>
<P>Alternatively, you can install the LAMMPS files (or any other Python
packages) in your own user space. The second "install" command does
this, where you should replace "foo" with your directory of choice.
</P>
<P>If these commands are successful, a <I>lammps.py</I> and <I>_lammps.so</I> file
will be put in the appropriate directory.
</P>
<HR>
<A NAME = "py_4"></A><H4>11.4 Extending Python with MPI
</H4>
<P>There are several Python packages available that purport to wrap MPI
as a library and allow MPI functions to be called from Python.
</P>
<P>These include
</P>
<UL><LI><A HREF = "http://pympi.sourceforge.net/">pyMPI</A>
<LI><A HREF = "http://code.google.com/p/maroonmpi/">maroonmpi</A>
<LI><A HREF = "http://code.google.com/p/mpi4py/">mpi4py</A>
<LI><A HREF = "http://nbcr.sdsc.edu/forum/viewtopic.php?t=89&sid=c997fefc3933bd66204875b436940f16">myMPI</A>
<LI><A HREF = "http://datamining.anu.edu.au/~ole/pypar">Pypar</A>
</UL>
<P>All of these except pyMPI work by wrapping the MPI library (which must
be available on your system as a shared library, as discussed above),
and exposing (some portion of) its interface to your Python script.
This means they cannot be used interactively in parallel, since they
do not address the issue of interactive input to multiple instances of
Python running on different processors. The one exception is pyMPI,
which alters the Python interpreter to address this issue, and (I
believe) creates a new alternate executable (in place of python
itself) as a result.
</P>
<P>In principle any of these Python/MPI packages should work to invoke
both calls to LAMMPS and MPI itself from a Python script running in
parallel. However, when I downloaded and looked at a few of them,
their docuemtation was incomplete and I had trouble with their
installation. It's not clear if some of the packages are still being
actively developed and supported.
</P>
<P>The one I recommend, since I have successfully used it with LAMMPS, is
Pypar. Pypar requires the ubiquitous <A HREF = "http://numpy.scipy.org">Numpy
package</A> be installed in your Python. After
launching python, type
</P>
<PRE>>>> import numpy
</PRE>
<P>to see if it is installed. If not, here is how to install it (version
1.3.0b1 as of April 2009). Unpack the numpy tarball and from its
top-level directory, type
</P>
<PRE>python setup.py build
sudo python setup.py install
</PRE>
<P>The "sudo" is only needed if required to copy Numpy files into your
Python distribution's site-packages directory.
</P>
<P>To install Pypar (version pypar-2.1.0_66 as of April 2009), unpack it
and from its "source" directory, type
</P>
<PRE>python setup.py build
sudo python setup.py install
</PRE>
<P>Again, the "sudo" is only needed if required to copy PyPar files into
your Python distribution's site-packages directory.
</P>
<P>If you have successully installed Pypar, you should be able to run
python serially and type
</P>
<PRE>>>> import pypar
</PRE>
<P>without error. You should also be able to run python in parallel
on a simple test script
</P>
<PRE>% mpirun -np 4 python test.script
</PRE>
<P>where test.script contains the lines
</P>
<PRE>import pypar
print "Proc %d out of %d procs" % (pypar.rank(),pypar.size())
</PRE>
<P>and see one line of output for each processor you ran on.
</P>
<HR>
<A NAME = "py_5"></A><H4>11.5 Testing the Python-LAMMPS interface
</H4>
<P>Before using LAMMPS in a Python program, one more step is needed. The
interface to LAMMPS is via the Python ctypes package, which loads the
shared LAMMPS library via a CDLL() call, which in turn is a wrapper on
the C-library dlopen(). This command is different than a normal
Python "import" and needs to be able to find the LAMMPS shared
library, which is either in the Python site-packages directory or in a
local directory you specified in the "python setup.py install"
command, as described above.
</P>
<P>The simplest way to do this is add a line like this to your
.cshrc or other shell start-up file.
</P>
<PRE>setenv LD_LIBRARY_PATH
${LD_LIBRARY_PATH}:/usr/local/lib/python2.5/site-packages
</PRE>
<P>and then execute the shell file to insure the path has been updated.
This will extend the path that dlopen() uses to look for shared
libraries.
</P>
<P>To test if the serial LAMMPS library has been successfully installed
(mode 1 above), launch Python and type
</P>
<PRE>>>> from lammps import lammps
>>> lmp = lammps()
</PRE>
<P>If you get no errors, you're ready to use serial LAMMPS from Python.
</P>
<P>If you built LAMMPS for parallel use (mode 2 or 3 above), launch
Python in parallel:
</P>
<PRE>% mpirun -np 4 python test.script
</PRE>
<P>where test.script contains the lines
</P>
<PRE>import pypar
from lammps import lammps
lmp = lammps()
print "Proc %d out of %d procs has" % (pypar.rank(),pypar.size()), lmp
pypar.finalize()
</PRE>
<P>Again, if you get no errors, you're good to go.
</P>
<P>Note that if you left out the "import pypar" line from this script,
you would instantiate and run LAMMPS independently on each of the P
processors specified in the mpirun command. You can test if Pypar is
enabling true parallel Python and LAMMPS by adding a line to the above
sequence of commands like lmp.file("in.lj") to run an input script and
see if the LAMMPS run says it ran on P processors or if you get output
from P duplicated 1-processor runs written to the screen. In the
latter case, Pypar is not working correctly.
</P>
<P>Note that this line:
</P>
<PRE>from lammps import lammps
</PRE>
<P>will import either the serial or parallel version of the LAMMPS
library, as wrapped by lammps.py. But if you installed both via
setup_serial.py and setup.py, it will always import the parallel
version, since it attempts that first.
</P>
<P>Note that if your Python script imports the Pypar package (as above),
so that it can use MPI calls directly, then Pypar initializes MPI for
you. Thus the last line of your Python script should be
pypar.finalize(), to insure MPI is shut down correctly.
</P>
<P>Also note that a Python script can be invoked in one of several ways:
</P>
<P>% python foo.script
% python -i foo.script
% foo.script
</P>
<P>The last command requires that the first line of the script be
something like this:
</P>
<P>#!/usr/local/bin/python
#!/usr/local/bin/python -i
</P>
<P>where the path points to where you have Python installed, and that you
have made the script file executable:
</P>
<P>% chmod +x foo.script
</P>
<P>Without the "-i" flag, Python will exit when the script finishes.
With the "-i" flag, you will be left in the Python interpreter when
the script finishes, so you can type subsequent commands. As
mentioned above, you can only run Python interactively when running
Python on a single processor, not in parallel.
</P>
<HR>
<HR>
<A NAME = "py_6"></A><H4>11.6 Using LAMMPS from Python
</H4>
<P>The Python interface to LAMMPS consists of a Python "lammps" module,
the source code for which is in python/lammps.py, which creates a
"lammps" object, with a set of methods that can be invoked on that
object. The sample Python code below assumes you have first imported
the "lammps" module in your Python script and its settings as
follows:
</P>
<PRE>from lammps import lammps
from lammps import LMPINT as INT
from lammps import LMPDOUBLE as DOUBLE
from lammps import LMPIPTR as IPTR
from lammps import LMPDPTR as DPTR
from lammps import LMPDPTRPTR as DPTRPTR
</PRE>
<P>These are the methods defined by the lammps module. If you look
at the file src/library.cpp you will see that they correspond
one-to-one with calls you can make to the LAMMPS library from a C++ or
C or Fortran program.
</P>
<PRE>lmp = lammps() # create a LAMMPS object
lmp = lammps(list) # ditto, with command-line args, list = ["-echo","screen"]
</PRE>
<PRE>lmp.close() # destroy a LAMMPS object
</PRE>
<PRE>lmp.file(file) # run an entire input script, file = "in.lj"
lmp.command(cmd) # invoke a single LAMMPS command, cmd = "run 100"
</PRE>
<PRE>xlo = lmp.extract_global(name,type) # extract a global quantity
# name = "boxxlo", "nlocal", etc
# type = INT or DOUBLE
</PRE>
<PRE>coords = lmp.extract_atom(name,type) # extract a per-atom quantity
# name = "x", "type", etc
# type = IPTR or DPTR or DPTRPTR
</PRE>
<PRE>eng = lmp.extract_compute(id,style,type) # extract value(s) from a compute
v3 = lmp.extract_fix(id,style,type,i,j) # extract value(s) from a fix
# id = ID of compute or fix
# style = 0 = global data
# 1 = per-atom data
# 2 = local data
# type = 0 = scalar
# 1 = vector
# 2 = array
# i,j = indices of value in global vector or array
</PRE>
<PRE>var = lmp.extract_variable(name,group,flag) # extract value(s) from a variable
# name = name of variable
# group = group ID (ignored for equal-style variables)
# flag = 0 = equal-style variable
# 1 = atom-style variable
</PRE>
<PRE>natoms = lmp.get_natoms() # total # of atoms as int
x = lmp.get_coords() # return coords of all atoms in x
lmp.put_coords(x) # set all atom coords via x
</PRE>
<HR>
<P>The creation of a LAMMPS object does not take an MPI communicator as
an argument. There should be a way to do this, so that the LAMMPS
instance runs on a subset of processors, if desired, but I don't yet
know how from Pypar. So for now, it runs on MPI_COMM_WORLD, which is
all the processors.
</P>
<P>The file() and command() methods allow an input script or single
commands to be invoked.
</P>
<P>The extract_global(), extract_atom(), extract_compute(),
extract_fix(), and extract_variable() methods return values or
pointers to data structures internal to LAMMPS.
</P>
<P>For extract_global() see the src/library.cpp file for the list of
valid names. New names could easily be added. A double or integer is
returned. You need to specify the appropriate data type via the type
argument.
</P>
<P>For extract_atom(), a pointer to internal LAMMPS atom-based data is
returned, which you can use via normal Python subscripting. See the
extract() method in the src/atom.cpp file for a list of valid names.
Again, new names could easily be added. A pointer to a vector of
doubles or integers, or a pointer to an array of doubles (double **)
is returned. You need to specify the appropriate data type via the
type argument.
</P>
<P>For extract_compute() and extract_fix(), the global, per-atom, or
local data calulated by the compute or fix can be accessed. What is
returned depends on whether the compute or fix calculates a scalar or
vector or array. For a scalar, a single double value is returned. If
the compute or fix calculates a vector or array, a pointer to the
internal LAMMPS data is returned, which you can use via normal Python
subscripting. The one exception is that for a fix that calculates a
global vector or array, a single double value from the vector or array
is returned, indexed by I (vector) or I and J (array). I,J are
zero-based indices. The I,J arguments can be left out if not needed.
-See <A HREF = "Section_howto.html#howto_15">this section</A> of the manual for a
+See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> of the manual for a
discussion of global, per-atom, and local data, and of scalar, vector,
and array data types. See the doc pages for individual
<A HREF = "compute.html">computes</A> and <A HREF = "fix.html">fixes</A> for a description of what
they calculate and store.
</P>
<P>For extract_variable(), an <A HREF = "variable.html">equal-style or atom-style
variable</A> is evaluated and its result returned.
</P>
<P>For equal-style variables a single double value is returned and the
group argument is ignored. For atom-style variables, a vector of
doubles is returned, one value per atom, which you can use via normal
Python subscripting. The values will be zero for atoms not in the
specified group.
</P>
<P>The get_natoms() method returns the total number of atoms in the
simulation, as an int. Note that extract_global("natoms") returns the
same value, but as a double, which is the way LAMMPS stores it to
allow for systems with more atoms than can be stored in an int (> 2
billion).
</P>
<P>The get_coords() method returns an ctypes vector of doubles of length
3*natoms, for the coordinates of all the atoms in the simulation,
ordered by x,y,z and then by atom ID (see code for put_coords()
below). The array can be used via normal Python subscripting. If
atom IDs are not consecutively ordered within LAMMPS, a None is
returned as indication of an error.
</P>
<P>Note that the data structure get_coords() returns is different from
the data structure returned by extract_atom("x") in four ways. (1)
Get_coords() returns a vector which you index as x[i];
extract_atom() returns an array which you index as x[i][j]. (2)
Get_coords() orders the atoms by atom ID while extract_atom() does
not. (3) Get_coords() returns a list of all atoms in the simulation;
extract_atoms() returns just the atoms local to each processor. (4)
Finally, the get_coords() data structure is a copy of the atom coords
stored internally in LAMMPS, whereas extract_atom returns an array
that points directly to the internal data. This means you can change
values inside LAMMPS from Python by assigning a new values to the
extract_atom() array. To do this with the get_atoms() vector, you
need to change values in the vector, then invoke the put_coords()
method.
</P>
<P>The put_coords() method takes a vector of coordinates for all atoms in
the simulation, assumed to be ordered by x,y,z and then by atom ID,
and uses the values to overwrite the corresponding coordinates for
each atom inside LAMMPS. This requires LAMMPS to have its "map"
option enabled; see the <A HREF = "atom_modify.html">atom_modify</A> command for
details. If it is not or if atom IDs are not consecutively ordered,
no coordinates are reset,
</P>
<P>The array of coordinates passed to put_coords() must be a ctypes
vector of doubles, allocated and initialized something like this:
</P>
<PRE>from ctypes import *
natoms = lmp.get_atoms()
n3 = 3*natoms
x = (c_double*n3)()
x<B>0</B> = x coord of atom with ID 1
x<B>1</B> = y coord of atom with ID 1
x<B>2</B> = z coord of atom with ID 1
x<B>3</B> = x coord of atom with ID 2
...
x<B>n3-1</B> = z coord of atom with ID natoms
lmp.put_coords(x)
</PRE>
<P>Alternatively, you can just change values in the vector returned by
get_coords(), since it is a ctypes vector of doubles.
</P>
<HR>
<P>As noted above, these Python class methods correspond one-to-one with
the functions in the LAMMPS library interface in src/library.cpp and
library.h. This means you can extend the Python wrapper via the
following steps:
</P>
<UL><LI>Add a new interface function to src/library.cpp and
src/library.h.
<LI>Verify the new function is syntactically correct by building LAMMPS as
-a library - see <A HREF = "Section_start.html#start_4">this section</A> of the
+a library - see <A HREF = "Section_start.html#start_4">Section_start 4</A> of the
manual.
<LI>Add a wrapper method in the Python LAMMPS module to python/lammps.py
for this interface function.
<LI>Rebuild the Python wrapper via python/setup_serial.py or
python/setup.py.
<LI>You should now be able to invoke the new interface function from a
Python script. Isn't ctypes amazing?
</UL>
<HR>
<HR>
<A NAME = "py_7"></A><H4>11.7 Example Python scripts that use LAMMPS
</H4>
<P>These are the Python scripts included as demos in the python/examples
directory of the LAMMPS distribution, to illustrate the kinds of
things that are possible when Python wraps LAMMPS. If you create your
own scripts, send them to us and we can include them in the LAMMPS
distribution.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >trivial.py</TD><TD > read/run a LAMMPS input script thru Python</TD></TR>
<TR><TD >demo.py</TD><TD > invoke various LAMMPS library interface routines</TD></TR>
<TR><TD >simple.py</TD><TD > mimic operation of couple/simple/simple.cpp in Python</TD></TR>
<TR><TD >gui.py</TD><TD > GUI go/stop/temperature-slider to control LAMMPS</TD></TR>
<TR><TD >plot.py</TD><TD > real-time temeperature plot with GnuPlot via Pizza.py</TD></TR>
<TR><TD >viz_tool.py</TD><TD > real-time viz via some viz package</TD></TR>
<TR><TD >vizplotgui_tool.py</TD><TD > combination of viz_tool.py and plot.py and gui.py
</TD></TR></TABLE></DIV>
<HR>
<P>For the viz_tool.py and vizplotgui_tool.py commands, replace "tool"
with "gl" or "atomeye" or "pymol" or "vmd", depending on what
visualization package you have installed.
</P>
<P>Note that for GL, you need to be able to run the Pizza.py GL tool,
which is included in the pizza sub-directory. See the <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py doc
pages</A> for more info:
</P>
<P>Note that for AtomEye, you need version 3, and there is a line in the
scripts that specifies the path and name of the executable. See the
AtomEye WWW pages <A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">here</A> or <A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html">here</A> for more details:
</P>
<PRE>http://mt.seas.upenn.edu/Archive/Graphics/A
http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html
</PRE>
<P>The latter link is to AtomEye 3 which has the scriping
capability needed by these Python scripts.
</P>
<P>Note that for PyMol, you need to have built and installed the
open-source version of PyMol in your Python, so that you can import it
from a Python script. See the PyMol WWW pages <A HREF = "http://www.pymol.org">here</A> or
<A HREF = "http://sourceforge.net/scm/?type=svn&group_id=4546">here</A> for more details:
</P>
<PRE>http://www.pymol.org
http://sourceforge.net/scm/?type=svn&group_id=4546
</PRE>
<P>The latter link is to the open-source version.
</P>
<P>Note that for VMD, you need a fairly current version (1.8.7 works for
me) and there are some lines in the pizza/vmd.py script for 4 PIZZA
variables that have to match the VMD installation on your system.
</P>
<HR>
<P>See the python/README file for instructions on how to run them and the
source code for individual scripts for comments about what they do.
</P>
<P>Here are screenshots of the vizplotgui_tool.py script in action for
different visualization package options. Click to see larger images:
</P>
<A HREF = "JPG/screenshot_gl.jpg"><IMG SRC = "JPG/screenshot_gl_small.jpg"></A>
<A HREF = "JPG/screenshot_atomeye.jpg"><IMG SRC = "JPG/screenshot_atomeye_small.jpg"></A>
<A HREF = "JPG/screenshot_pymol.jpg"><IMG SRC = "JPG/screenshot_pymol_small.jpg"></A>
<A HREF = "JPG/screenshot_vmd.jpg"><IMG SRC = "JPG/screenshot_vmd_small.jpg"></A>
</HTML>
diff --git a/doc/Section_python.txt b/doc/Section_python.txt
index dbf470081..44b2a0f01 100644
--- a/doc/Section_python.txt
+++ b/doc/Section_python.txt
@@ -1,661 +1,664 @@
"Previous Section"_Section_modify.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_errors.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
11. Python interface to LAMMPS :h3
+This section describes how to build and use LAMMPS via a Python
+interface.
+
+11.1 "Extending Python with a serial version of LAMMPS"_#py_1
+11.2 "Creating a shared MPI library"_#py_2
+11.3 "Extending Python with a parallel version of LAMMPS"_#py_3
+11.4 "Extending Python with MPI"_#py_4
+11.5 "Testing the Python-LAMMPS interface"_#py_5
+11.6 "Using LAMMPS from Python"_#py_6
+11.7 "Example Python scripts that use LAMMPS"_#py_7 :ul
+
The LAMMPS distribution includes some Python code in its python
directory which wraps the library interface to LAMMPS. This makes it
is possible to run LAMMPS, invoke LAMMPS commands or give it an input
script, extract LAMMPS results, an modify internal LAMMPS variables,
either from a Python script or interactively from a Python prompt.
"Python"_http://www.python.org is a powerful scripting and programming
language which can be used to wrap software like LAMMPS and other
packages. It can be used to glue multiple pieces of software
together, e.g. to run a coupled or multiscale model. See "this
section"_Section_howto.html#howto_10 of the manual and the couple
directory of the distribution for more ideas about coupling LAMMPS to
-other codes. See "this section"_Section_start.html#start_4 about how
-to build LAMMPS as a library, and "this
+other codes. See "Section_start 4"_Section_start.html#start_4 about
+how to build LAMMPS as a library, and "this
section"_Section_howto.html#howto_19 for a description of the library
interface provided in src/library.cpp and src/library.h and how to
extend it for your needs. As described below, that interface is what
is exposed to Python. It is designed to be easy to add functions to.
This has the effect of extending the Python inteface as well. See
details below.
By using the Python interface LAMMPS can also be coupled with a GUI or
visualization tools that display graphs or animations in real time as
LAMMPS runs. Examples of such scripts are inlcluded in the python
directory.
Two advantages of using Python are how concise the language is and
that it can be run interactively, enabling rapid development and
debugging of programs. If you use it to mostly invoke costly
operations within LAMMPS, such as running a simulation for a
reasonable number of timesteps, then the overhead cost of invoking
LAMMPS thru Python will be negligible.
Before using LAMMPS from a Python script, the Python on your machine
must be "extended" to include an interface to the LAMMPS library. If
your Python script will invoke MPI operations, you will also need to
extend your Python with an interface to MPI itself.
Thus you should first decide how you intend to use LAMMPS from Python.
There are 3 options:
(1) Use LAMMPS on a single processor running Python.
(2) Use LAMMPS in parallel, where each processor runs Python, but your
Python program does not use MPI.
(3) Use LAMMPS in parallel, where each processor runs Python, and your
Python script also makes MPI calls through a Python/MPI interface.
Note that for (2) and (3) you will not be able to use Python
interactively by typing commands and getting a response. This is
because you will have multiple instances of Python running (e.g. on a
parallel machine) and they cannot all read what you type.
Working in mode (1) does not require your machine to have MPI
installed. You should extend your Python with a serial version of
LAMMPS and the dummy MPI library provided with LAMMPS. See
instructions below on how to do this.
Working in mode (2) requires your machine to have an MPI library
installed, but your Python does not need to be extended with MPI
itself. The MPI library must be a shared library (e.g. a *.so file on
Linux) which is not typically created when MPI is built/installed.
See instruction below on how to do this. You should extend your
Python with the a parallel versionn of LAMMPS which will use the
shared MPI system library. See instructions below on how to do this.
Working in mode (3) requires your machine to have MPI installed (as a
shared library as in (2)). You must also extend your Python with a
parallel version of LAMMPS (same as in (2)) and with MPI itself, via
one of several available Python/MPI packages. See instructions below
on how to do the latter task.
Several of the following sub-sections cover the rest of the Python
setup discussion. The next to last sub-section describes the Python
syntax used to invoke LAMMPS. The last sub-section describes example
Python scripts included in the python directory.
-11.1 "Extending Python with a serial version of LAMMPS"_#py_1
-11.2 "Creating a shared MPI library"_#py_2
-11.3 "Extending Python with a parallel version of LAMMPS"_#py_3
-11.4 "Extending Python with MPI"_#py_4
-11.5 "Testing the Python-LAMMPS interface"_#py_5
-11.6 "Using LAMMPS from Python"_#py_6
-11.7 "Example Python scripts that use LAMMPS"_#py_7 :ul
-
Before proceeding, there are 2 items to note.
(1) The provided Python wrapper for LAMMPS uses the amazing and
magical (to me) "ctypes" package in Python, which auto-generates the
interface code needed between Python and a set of C interface routines
for a library. Ctypes is part of standard Python for versions 2.5 and
later. You can check which version of Python you have installed, by
simply typing "python" at a shell prompt.
(2) Any library wrapped by Python, including LAMMPS, must be built as
a shared library (e.g. a *.so file on Linux and not a *.a file). The
python/setup_serial.py and setup.py scripts do this build for LAMMPS
itself (described below). But if you have LAMMPS configured to use
additional packages that have their own libraries, then those
libraries must also be shared libraries. E.g. MPI, FFTW, or any of
the libraries in lammps/lib. When you build LAMMPS as a stand-alone
code, you are not building shared versions of these libraries.
The discussion below describes how to create a shared MPI library. I
suggest you start by configuing LAMMPS without packages installed that
require any libraries besides MPI. See "this
section"_Section_start.html#start_3 of the manual for a discussion of
LAMMPS pacakges. E.g. do not use the KSPACE, GPU, MEAM, POEMS, or
REAX packages.
If you are successfully follow the steps belwo to build the Python
wrappers and use this version of LAMMPS through Python, you can then
take the next step of adding LAMMPS packages that use additional
libraries. This will require you to build a shared library for that
package's library, similar to what is described below for MPI. It
will also require you to edit the python/setup_serial.py or setup.py
scripts to enable Python to access those libraries when it builds the
LAMMPS wrapper.
:line
:line
11.1 Extending Python with a serial version of LAMMPS :link(py_1),h4
From the python directory in the LAMMPS distribution, type
python setup_serial.py build :pre
and then one of these commands:
sudo python setup_serial.py install
python setup_serial.py install --home=~/foo :pre
The "build" command should compile all the needed LAMMPS files,
including its dummy MPI library. The first "install" command will put
the needed files in your Python's site-packages sub-directory, so that
Python can load them. For example, if you installed Python yourself
on a Linux machine, it would typically be somewhere like
/usr/local/lib/python2.5/site-packages. Installing Python packages
this way often requires you to be able to write to the Python
directories, which may require root priveleges, hence the "sudo"
prefix. If this is not the case, you can drop the "sudo".
Alternatively, you can install the LAMMPS files (or any other Python
packages) in your own user space. The second "install" command does
this, where you should replace "foo" with your directory of choice.
If these commands are successful, a {lammps.py} and
{_lammps_serial.so} file will be put in the appropriate directory.
:line
11.2 Creating a shared MPI library :link(py_2),h4
A shared library is one that is dynamically loadable, which is what
Python requires. On Linux this is a library file that ends in ".so",
not ".a". Such a shared library is normally not built if you
installed MPI yourself, but it is easy to do. Here is how to do it
for "MPICH"_mpich, a popular open-source version of MPI, distributed
by Argonne National Labs. From within the mpich directory, type
:link(mpich,http://www-unix.mcs.anl.gov/mpi)
-./configure --enable-sharedlib=gcc
+./configure --enable-shared
make
make install :pre
You may need to use "sudo make install" in place of the last line.
The end result should be the file libmpich.so in /usr/local/lib.
IMPORTANT NOTE: If the file libmpich.a already exists in your
installation directory (e.g. /usr/local/lib), you will now have both a
static and shared MPI library. This will be fine for running LAMMPS
from Python since it only uses the shared library. But if you now try
to build LAMMPS by itself as a stand-alone program (cd lammps/src;
make foo) or build other codes that expect to link against libmpich.a,
-then those builds will typically fail if the linker uses libmpich.so
-instead. This means you will need to remove the file
+then those builds may fail if the linker uses libmpich.so instead. If
+this happens, it means you will need to remove the file
/usr/local/lib/libmich.so before building LAMMPS again as a
stand-alone code.
:line
11.3 Extending Python with a parallel version of LAMMPS :link(py_3),h4
From the python directory, type
python setup.py build :pre
and then one of these commands:
sudo python setup.py install
python setup.py install --home=~/foo :pre
The "build" command should compile all the needed LAMMPS C++ files,
which will require MPI to be installed on your system. This means it
must find both the header file mpi.h and a shared library file,
e.g. libmpich.so if the MPICH version of MPI is installed. See the
preceding section for how to create a shared library version of MPI if
it does not exist. You may need to adjust the "include_dirs" and
"library_dirs" and "libraries" fields in python/setup.py to
insure the Python build finds all the files it needs.
The first "install" command will put the needed files in your Python's
site-packages sub-directory, so that Python can load them. For
example, if you installed Python yourself on a Linux machine, it would
typically be somewhere like /usr/local/lib/python2.5/site-packages.
Installing Python packages this way often requires you to be able to
write to the Python directories, which may require root priveleges,
hence the "sudo" prefix. If this is not the case, you can drop the
"sudo".
Alternatively, you can install the LAMMPS files (or any other Python
packages) in your own user space. The second "install" command does
this, where you should replace "foo" with your directory of choice.
If these commands are successful, a {lammps.py} and {_lammps.so} file
will be put in the appropriate directory.
:line
11.4 Extending Python with MPI :link(py_4),h4
There are several Python packages available that purport to wrap MPI
as a library and allow MPI functions to be called from Python.
These include
"pyMPI"_http://pympi.sourceforge.net/
"maroonmpi"_http://code.google.com/p/maroonmpi/
"mpi4py"_http://code.google.com/p/mpi4py/
"myMPI"_http://nbcr.sdsc.edu/forum/viewtopic.php?t=89&sid=c997fefc3933bd66204875b436940f16
"Pypar"_http://datamining.anu.edu.au/~ole/pypar :ul
All of these except pyMPI work by wrapping the MPI library (which must
be available on your system as a shared library, as discussed above),
and exposing (some portion of) its interface to your Python script.
This means they cannot be used interactively in parallel, since they
do not address the issue of interactive input to multiple instances of
Python running on different processors. The one exception is pyMPI,
which alters the Python interpreter to address this issue, and (I
believe) creates a new alternate executable (in place of python
itself) as a result.
In principle any of these Python/MPI packages should work to invoke
both calls to LAMMPS and MPI itself from a Python script running in
parallel. However, when I downloaded and looked at a few of them,
their docuemtation was incomplete and I had trouble with their
installation. It's not clear if some of the packages are still being
actively developed and supported.
The one I recommend, since I have successfully used it with LAMMPS, is
Pypar. Pypar requires the ubiquitous "Numpy
package"_http://numpy.scipy.org be installed in your Python. After
launching python, type
>>> import numpy :pre
to see if it is installed. If not, here is how to install it (version
1.3.0b1 as of April 2009). Unpack the numpy tarball and from its
top-level directory, type
python setup.py build
sudo python setup.py install :pre
The "sudo" is only needed if required to copy Numpy files into your
Python distribution's site-packages directory.
To install Pypar (version pypar-2.1.0_66 as of April 2009), unpack it
and from its "source" directory, type
python setup.py build
sudo python setup.py install :pre
Again, the "sudo" is only needed if required to copy PyPar files into
your Python distribution's site-packages directory.
If you have successully installed Pypar, you should be able to run
python serially and type
>>> import pypar :pre
without error. You should also be able to run python in parallel
on a simple test script
% mpirun -np 4 python test.script :pre
where test.script contains the lines
import pypar
print "Proc %d out of %d procs" % (pypar.rank(),pypar.size()) :pre
and see one line of output for each processor you ran on.
:line
11.5 Testing the Python-LAMMPS interface :link(py_5),h4
Before using LAMMPS in a Python program, one more step is needed. The
interface to LAMMPS is via the Python ctypes package, which loads the
shared LAMMPS library via a CDLL() call, which in turn is a wrapper on
the C-library dlopen(). This command is different than a normal
Python "import" and needs to be able to find the LAMMPS shared
library, which is either in the Python site-packages directory or in a
local directory you specified in the "python setup.py install"
command, as described above.
The simplest way to do this is add a line like this to your
.cshrc or other shell start-up file.
setenv LD_LIBRARY_PATH
$\{LD_LIBRARY_PATH\}:/usr/local/lib/python2.5/site-packages :pre
and then execute the shell file to insure the path has been updated.
This will extend the path that dlopen() uses to look for shared
libraries.
To test if the serial LAMMPS library has been successfully installed
(mode 1 above), launch Python and type
>>> from lammps import lammps
>>> lmp = lammps() :pre
If you get no errors, you're ready to use serial LAMMPS from Python.
If you built LAMMPS for parallel use (mode 2 or 3 above), launch
Python in parallel:
% mpirun -np 4 python test.script :pre
where test.script contains the lines
import pypar
from lammps import lammps
lmp = lammps()
print "Proc %d out of %d procs has" % (pypar.rank(),pypar.size()), lmp
pypar.finalize() :pre
Again, if you get no errors, you're good to go.
Note that if you left out the "import pypar" line from this script,
you would instantiate and run LAMMPS independently on each of the P
processors specified in the mpirun command. You can test if Pypar is
enabling true parallel Python and LAMMPS by adding a line to the above
sequence of commands like lmp.file("in.lj") to run an input script and
see if the LAMMPS run says it ran on P processors or if you get output
from P duplicated 1-processor runs written to the screen. In the
latter case, Pypar is not working correctly.
Note that this line:
from lammps import lammps :pre
will import either the serial or parallel version of the LAMMPS
library, as wrapped by lammps.py. But if you installed both via
setup_serial.py and setup.py, it will always import the parallel
version, since it attempts that first.
Note that if your Python script imports the Pypar package (as above),
so that it can use MPI calls directly, then Pypar initializes MPI for
you. Thus the last line of your Python script should be
pypar.finalize(), to insure MPI is shut down correctly.
Also note that a Python script can be invoked in one of several ways:
% python foo.script
% python -i foo.script
% foo.script
The last command requires that the first line of the script be
something like this:
#!/usr/local/bin/python
#!/usr/local/bin/python -i
where the path points to where you have Python installed, and that you
have made the script file executable:
% chmod +x foo.script
Without the "-i" flag, Python will exit when the script finishes.
With the "-i" flag, you will be left in the Python interpreter when
the script finishes, so you can type subsequent commands. As
mentioned above, you can only run Python interactively when running
Python on a single processor, not in parallel.
:line
:line
11.6 Using LAMMPS from Python :link(py_6),h4
The Python interface to LAMMPS consists of a Python "lammps" module,
the source code for which is in python/lammps.py, which creates a
"lammps" object, with a set of methods that can be invoked on that
object. The sample Python code below assumes you have first imported
the "lammps" module in your Python script and its settings as
follows:
from lammps import lammps
from lammps import LMPINT as INT
from lammps import LMPDOUBLE as DOUBLE
from lammps import LMPIPTR as IPTR
from lammps import LMPDPTR as DPTR
from lammps import LMPDPTRPTR as DPTRPTR :pre
These are the methods defined by the lammps module. If you look
at the file src/library.cpp you will see that they correspond
one-to-one with calls you can make to the LAMMPS library from a C++ or
C or Fortran program.
lmp = lammps() # create a LAMMPS object
lmp = lammps(list) # ditto, with command-line args, list = \["-echo","screen"\] :pre
lmp.close() # destroy a LAMMPS object :pre
lmp.file(file) # run an entire input script, file = "in.lj"
lmp.command(cmd) # invoke a single LAMMPS command, cmd = "run 100" :pre
xlo = lmp.extract_global(name,type) # extract a global quantity
# name = "boxxlo", "nlocal", etc
# type = INT or DOUBLE :pre
coords = lmp.extract_atom(name,type) # extract a per-atom quantity
# name = "x", "type", etc
# type = IPTR or DPTR or DPTRPTR :pre
eng = lmp.extract_compute(id,style,type) # extract value(s) from a compute
v3 = lmp.extract_fix(id,style,type,i,j) # extract value(s) from a fix
# id = ID of compute or fix
# style = 0 = global data
# 1 = per-atom data
# 2 = local data
# type = 0 = scalar
# 1 = vector
# 2 = array
# i,j = indices of value in global vector or array :pre
var = lmp.extract_variable(name,group,flag) # extract value(s) from a variable
# name = name of variable
# group = group ID (ignored for equal-style variables)
# flag = 0 = equal-style variable
# 1 = atom-style variable :pre
natoms = lmp.get_natoms() # total # of atoms as int
x = lmp.get_coords() # return coords of all atoms in x
lmp.put_coords(x) # set all atom coords via x :pre
:line
The creation of a LAMMPS object does not take an MPI communicator as
an argument. There should be a way to do this, so that the LAMMPS
instance runs on a subset of processors, if desired, but I don't yet
know how from Pypar. So for now, it runs on MPI_COMM_WORLD, which is
all the processors.
The file() and command() methods allow an input script or single
commands to be invoked.
The extract_global(), extract_atom(), extract_compute(),
extract_fix(), and extract_variable() methods return values or
pointers to data structures internal to LAMMPS.
For extract_global() see the src/library.cpp file for the list of
valid names. New names could easily be added. A double or integer is
returned. You need to specify the appropriate data type via the type
argument.
For extract_atom(), a pointer to internal LAMMPS atom-based data is
returned, which you can use via normal Python subscripting. See the
extract() method in the src/atom.cpp file for a list of valid names.
Again, new names could easily be added. A pointer to a vector of
doubles or integers, or a pointer to an array of doubles (double **)
is returned. You need to specify the appropriate data type via the
type argument.
For extract_compute() and extract_fix(), the global, per-atom, or
local data calulated by the compute or fix can be accessed. What is
returned depends on whether the compute or fix calculates a scalar or
vector or array. For a scalar, a single double value is returned. If
the compute or fix calculates a vector or array, a pointer to the
internal LAMMPS data is returned, which you can use via normal Python
subscripting. The one exception is that for a fix that calculates a
global vector or array, a single double value from the vector or array
is returned, indexed by I (vector) or I and J (array). I,J are
zero-based indices. The I,J arguments can be left out if not needed.
-See "this section"_Section_howto.html#howto_15 of the manual for a
+See "Section_howto 15"_Section_howto.html#howto_15 of the manual for a
discussion of global, per-atom, and local data, and of scalar, vector,
and array data types. See the doc pages for individual
"computes"_compute.html and "fixes"_fix.html for a description of what
they calculate and store.
For extract_variable(), an "equal-style or atom-style
variable"_variable.html is evaluated and its result returned.
For equal-style variables a single double value is returned and the
group argument is ignored. For atom-style variables, a vector of
doubles is returned, one value per atom, which you can use via normal
Python subscripting. The values will be zero for atoms not in the
specified group.
The get_natoms() method returns the total number of atoms in the
simulation, as an int. Note that extract_global("natoms") returns the
same value, but as a double, which is the way LAMMPS stores it to
allow for systems with more atoms than can be stored in an int (> 2
billion).
The get_coords() method returns an ctypes vector of doubles of length
3*natoms, for the coordinates of all the atoms in the simulation,
ordered by x,y,z and then by atom ID (see code for put_coords()
below). The array can be used via normal Python subscripting. If
atom IDs are not consecutively ordered within LAMMPS, a None is
returned as indication of an error.
Note that the data structure get_coords() returns is different from
the data structure returned by extract_atom("x") in four ways. (1)
Get_coords() returns a vector which you index as x\[i\];
extract_atom() returns an array which you index as x\[i\]\[j\]. (2)
Get_coords() orders the atoms by atom ID while extract_atom() does
not. (3) Get_coords() returns a list of all atoms in the simulation;
extract_atoms() returns just the atoms local to each processor. (4)
Finally, the get_coords() data structure is a copy of the atom coords
stored internally in LAMMPS, whereas extract_atom returns an array
that points directly to the internal data. This means you can change
values inside LAMMPS from Python by assigning a new values to the
extract_atom() array. To do this with the get_atoms() vector, you
need to change values in the vector, then invoke the put_coords()
method.
The put_coords() method takes a vector of coordinates for all atoms in
the simulation, assumed to be ordered by x,y,z and then by atom ID,
and uses the values to overwrite the corresponding coordinates for
each atom inside LAMMPS. This requires LAMMPS to have its "map"
option enabled; see the "atom_modify"_atom_modify.html command for
details. If it is not or if atom IDs are not consecutively ordered,
no coordinates are reset,
The array of coordinates passed to put_coords() must be a ctypes
vector of doubles, allocated and initialized something like this:
from ctypes import *
natoms = lmp.get_atoms()
n3 = 3*natoms
x = (c_double*n3)()
x[0] = x coord of atom with ID 1
x[1] = y coord of atom with ID 1
x[2] = z coord of atom with ID 1
x[3] = x coord of atom with ID 2
...
x[n3-1] = z coord of atom with ID natoms
lmp.put_coords(x) :pre
Alternatively, you can just change values in the vector returned by
get_coords(), since it is a ctypes vector of doubles.
:line
As noted above, these Python class methods correspond one-to-one with
the functions in the LAMMPS library interface in src/library.cpp and
library.h. This means you can extend the Python wrapper via the
following steps:
Add a new interface function to src/library.cpp and
src/library.h. :ulb,l
Verify the new function is syntactically correct by building LAMMPS as
-a library - see "this section"_Section_start.html#start_4 of the
+a library - see "Section_start 4"_Section_start.html#start_4 of the
manual. :l
Add a wrapper method in the Python LAMMPS module to python/lammps.py
for this interface function. :l
Rebuild the Python wrapper via python/setup_serial.py or
python/setup.py. :l
You should now be able to invoke the new interface function from a
Python script. Isn't ctypes amazing? :l,ule
:line
:line
11.7 Example Python scripts that use LAMMPS :link(py_7),h4
These are the Python scripts included as demos in the python/examples
directory of the LAMMPS distribution, to illustrate the kinds of
things that are possible when Python wraps LAMMPS. If you create your
own scripts, send them to us and we can include them in the LAMMPS
distribution.
trivial.py, read/run a LAMMPS input script thru Python,
demo.py, invoke various LAMMPS library interface routines,
simple.py, mimic operation of couple/simple/simple.cpp in Python,
gui.py, GUI go/stop/temperature-slider to control LAMMPS,
plot.py, real-time temeperature plot with GnuPlot via Pizza.py,
viz_tool.py, real-time viz via some viz package,
vizplotgui_tool.py, combination of viz_tool.py and plot.py and gui.py :tb(c=2)
:line
For the viz_tool.py and vizplotgui_tool.py commands, replace "tool"
with "gl" or "atomeye" or "pymol" or "vmd", depending on what
visualization package you have installed.
Note that for GL, you need to be able to run the Pizza.py GL tool,
which is included in the pizza sub-directory. See the "Pizza.py doc
pages"_pizza for more info:
:link(pizza,http://www.sandia.gov/~sjplimp/pizza.html)
Note that for AtomEye, you need version 3, and there is a line in the
scripts that specifies the path and name of the executable. See the
AtomEye WWW pages "here"_atomeye or "here"_atomeye3 for more details:
http://mt.seas.upenn.edu/Archive/Graphics/A
http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html :pre
:link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A)
:link(atomeye3,http://mt.seas.upenn.edu/Archive/Graphics/A3/A3.html)
The latter link is to AtomEye 3 which has the scriping
capability needed by these Python scripts.
Note that for PyMol, you need to have built and installed the
open-source version of PyMol in your Python, so that you can import it
from a Python script. See the PyMol WWW pages "here"_pymol or
"here"_pymolopen for more details:
http://www.pymol.org
http://sourceforge.net/scm/?type=svn&group_id=4546 :pre
:link(pymol,http://www.pymol.org)
:link(pymolopen,http://sourceforge.net/scm/?type=svn&group_id=4546)
The latter link is to the open-source version.
Note that for VMD, you need a fairly current version (1.8.7 works for
me) and there are some lines in the pizza/vmd.py script for 4 PIZZA
variables that have to match the VMD installation on your system.
:line
See the python/README file for instructions on how to run them and the
source code for individual scripts for comments about what they do.
Here are screenshots of the vizplotgui_tool.py script in action for
different visualization package options. Click to see larger images:
:image(JPG/screenshot_gl_small.jpg,JPG/screenshot_gl.jpg)
:image(JPG/screenshot_atomeye_small.jpg,JPG/screenshot_atomeye.jpg)
:image(JPG/screenshot_pymol_small.jpg,JPG/screenshot_pymol.jpg)
:image(JPG/screenshot_vmd_small.jpg,JPG/screenshot_vmd.jpg)
diff --git a/doc/Section_start.html b/doc/Section_start.html
index 438f879dd..29682bcd0 100644
--- a/doc/Section_start.html
+++ b/doc/Section_start.html
@@ -1,1161 +1,1245 @@
<HTML>
<CENTER><A HREF = "Section_intro.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_commands.html">Next Section</A>
</CENTER>
<HR>
<H3>2. Getting Started
</H3>
<P>This section describes how to build and run LAMMPS, for both new and
experienced users.
</P>
2.1 <A HREF = "#start_1">What's in the LAMMPS distribution</A><BR>
2.2 <A HREF = "#start_2">Making LAMMPS</A><BR>
2.3 <A HREF = "#start_3">Making LAMMPS with optional packages</A><BR>
2.4 <A HREF = "#start_4">Building LAMMPS as a library</A><BR>
2.5 <A HREF = "#start_5">Running LAMMPS</A><BR>
2.6 <A HREF = "#start_6">Command-line options</A><BR>
2.7 <A HREF = "#start_7">Screen output</A><BR>
2.8 <A HREF = "#start_8">Tips for users of previous versions</A> <BR>
<HR>
+<HR>
+
<H4><A NAME = "start_1"></A>2.1 What's in the LAMMPS distribution
</H4>
<P>When you download LAMMPS you will need to unzip and untar the
downloaded file with the following commands, after placing the file in
an appropriate directory.
</P>
<PRE>gunzip lammps*.tar.gz
tar xvf lammps*.tar
</PRE>
<P>This will create a LAMMPS directory containing two files and several
sub-directories:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >README</TD><TD > text file</TD></TR>
<TR><TD >LICENSE</TD><TD > the GNU General Public License (GPL)</TD></TR>
<TR><TD >bench</TD><TD > benchmark problems</TD></TR>
<TR><TD >couple</TD><TD > code coupling examples, using LAMMPS as a library</TD></TR>
<TR><TD >doc</TD><TD > documentation</TD></TR>
<TR><TD >examples</TD><TD > simple test problems</TD></TR>
<TR><TD >potentials</TD><TD > embedded atom method (EAM) potential files</TD></TR>
<TR><TD >src</TD><TD > source files</TD></TR>
<TR><TD >tools</TD><TD > pre- and post-processing tools
</TD></TR></TABLE></DIV>
<P>If you download one of the Windows executables from the download page,
then you just get a single file:
</P>
<PRE>lmp_windows.exe
</PRE>
<P>Skip to the <A HREF = "#start_5">Running LAMMPS</A> sections for info on how to
launch these executables on a Windows box.
</P>
<P>The Windows executables for serial or parallel only include certain
packages and bug-fixes/upgrades listed on <A HREF = "http://lammps.sandia.gov/bug.html">this
page</A> up to a certain date, as
stated on the download page. If you want something with more packages
or that is more current, you'll have to download the source tarball
and build it yourself from source code using Microsoft Visual Studio,
as described in the next section.
</P>
<HR>
<H4><A NAME = "start_2"></A>2.2 Making LAMMPS
</H4>
<P>This section has the following sub-sections:
</P>
<UL><LI><A HREF = "#start_2_1">Read this first</A>
<LI><A HREF = "#start_2_2">Steps to build a LAMMPS executable</A>
<LI><A HREF = "#start_2_3">Common errors that can occur when making LAMMPS</A>
<LI><A HREF = "#start_2_4">Additional build tips</A>
<LI><A HREF = "#start_2_5">Building for a Mac</A>
<LI><A HREF = "#start_2_6">Building for Windows</A>
</UL>
<HR>
<A NAME = "start_2_1"></A><B><I>Read this first:</I></B>
<P>Building LAMMPS can be non-trivial. You may need to edit a makefile,
there are compiler options to consider, additional libraries can be
used (MPI, FFT, JPEG), LAMMPS packages may be included or excluded,
some of these packages use auxiliary libraries which need to be
pre-built, etc.
</P>
<P>Please read this section carefully. If you are not comfortable with
makefiles, or building codes on a Unix platform, or running an MPI job
on your machine, please find a local expert to help you. Many
compiling, linking, and run problems that users have are not really
LAMMPS issues - they are peculiar to the user's system, compilers,
libraries, etc. Such questions are better answered by a local expert.
</P>
<P>If you have a build problem that you are convinced is a LAMMPS issue
(e.g. the compiler complains about a line of LAMMPS source code), then
please send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
</P>
<P>If you succeed in building LAMMPS on a new kind of machine, for which
there isn't a similar Makefile for in the src/MAKE directory, send it
to the developers and we'll include it in future LAMMPS releases.
</P>
<HR>
<A NAME = "start_2_2"></A><B><I>Steps to build a LAMMPS executable:</I></B>
<P><B>Step 0</B>
</P>
<P>The src directory contains the C++ source and header files for LAMMPS.
It also contains a top-level Makefile and a MAKE sub-directory with
low-level Makefile.* files for many machines. From within the src
directory, type "make" or "gmake". You should see a list of available
choices. If one of those is the machine and options you want, you can
type a command like:
</P>
<PRE>make linux
or
gmake mac
</PRE>
<P>Note that on a multi-processor or multi-core platform you can launch a
parallel make, by using the "-j" switch with the make command, which
will build LAMMPS more quickly.
</P>
<P>If you get no errors and an executable like lmp_linux or lmp_mac is
produced, you're done; it's your lucky day.
</P>
<P>Note that by default only a few of LAMMPS optional pacakges are
installed. To build LAMMPS with optional packages, see <A HREF = "#start_3">this
section</A> below.
</P>
<P><B>Step 1</B>
</P>
<P>If Step 0 did not work, you will need to create a low-level Makefile
for your machine, like Makefile.foo. You should make a copy of an
existing src/MAKE/Makefile.* as a starting point. The only portions
of the file you need to edit are the first line, the "compiler/linker
settings" section, and the "LAMMPS-specific settings" section.
</P>
<P><B>Step 2</B>
</P>
<P>Change the first line of src/MAKE/Makefile.foo to list the word "foo"
after the "#", and whatever other options it will set. This is the
line you will see if you just type "make".
</P>
<P><B>Step 3</B>
</P>
<P>The "compiler/linker settings" section lists compiler and linker
settings for your C++ compiler, including optimization flags. You can
use g++, the open-source GNU compiler, which is available on all Unix
systems. You can also use mpicc which will typically be available if
MPI is installed on your system, though you should check which actual
compiler it wraps. Vendor compilers often produce faster code. On
boxes with Intel CPUs, we suggest using the commercial Intel icc
compiler, which can be downloaded from <A HREF = "http://www.intel.com/software/products/noncom">Intel's compiler site</A>.
</P>
<P>If building a C++ code on your machine requires additional libraries,
then you should list them as part of the LIB variable.
</P>
<P>The DEPFLAGS setting is what triggers the C++ compiler to create a
dependency list for a source file. This speeds re-compilation when
source (*.cpp) or header (*.h) files are edited. Some compilers do
not support dependency file creation, or may use a different switch
than -D. GNU g++ works with -D. If your compiler can't create
dependency files, then you'll need to create a Makefile.foo patterned
after Makefile.storm, which uses different rules that do not involve
dependency files. Note that when you build LAMMPS for the first time
on a new platform, a long list of *.d files will be printed out
rapidly. This is not an error; it is the Makefile doing its normal
creation of dependencies.
</P>
<P><B>Step 4</B>
</P>
<P>The "system-specific settings" section has several parts. Note that
if you change any -D setting in this section, you should do a full
re-compile, after typing "make clean" (which will describe different
clean options).
</P>
<P>The LMP_INC variable is used to include options that turn on ifdefs
within the LAMMPS code. The options that are currently recogized are:
</P>
<UL><LI>-DLAMMPS_GZIP
<LI>-DLAMMPS_JPEG
+<LI>-DLAMMPS_MEMALIGN
<LI>-DLAMMPS_XDR
<LI>-DLAMMPS_SMALLBIG
<LI>-DLAMMPS_BIGBIG
<LI>-DLAMMPS_SMALLSMALL
<LI>-DLAMMPS_LONGLONG_TO_LONG
<LI>-DPACK_ARRAY
<LI>-DPACK_POINTER
<LI>-DPACK_MEMCPY
</UL>
<P>The read_data and dump commands will read/write gzipped files if you
compile with -DLAMMPS_GZIP. It requires that your Unix support the
"popen" command.
</P>
<P>If you use -DLAMMPS_JPEG, the <A HREF = "dump.html">dump image</A> command will be
able to write out JPEG image files. If not, it will only be able to
write out text-based PPM image files. For JPEG files, you must also
link LAMMPS with a JPEG library, as described below.
</P>
+<P>Using -DLAMMPS_MEMALIGN=<bytes> enables the use of the
+posix_memalign() call instead of malloc() when large chunks or memory
+are allocated by LAMMPS. This can help to make more efficient use of
+vector instructions of modern CPUS, since dynamically allocated memory
+has to be aligned on larger than default byte boundaries (e.g. 16
+bytes instead of 8 bytes on x86 type platforms) for optimal
+performance.
+</P>
<P>If you use -DLAMMPS_XDR, the build will include XDR compatibility
files for doing particle dumps in XTC format. This is only necessary
if your platform does have its own XDR files available. See the
Restrictions section of the <A HREF = "dump.html">dump</A> command for details.
</P>
<P>Use at most one of the -DLAMMPS_SMALLBIG, -DLAMMPS_BIGBIG,
-D-DLAMMPS_SMALLSMALL settings. The default is -DLAMMPS_SMALLBIG.
These refer to use of 4-byte (small) vs 8-byte (big) integers within
LAMMPS, as described in src/lmptype.h. The only reason to use the
BIGBIG setting is to enable simulation of huge molecular systems with
more than 2 billion atoms. The only reason to use the SMALLSMALL
setting is if your machine does not support 64-bit integers.
</P>
<P>The -DLAMMPS_LONGLONG_TO_LONG setting may be needed if your system or
MPI version does not recognize "long long" data types. In this case a
"long" data type is likely already 64-bits, in which case this setting
will convert to that data type.
</P>
<P>Using one of the -DPACK_ARRAY, -DPACK_POINTER, and -DPACK_MEMCPY
options can make for faster parallel FFTs (in the PPPM solver) on some
platforms. The -DPACK_ARRAY setting is the default. See the
<A HREF = "kspace_style.html">kspace_style</A> command for info about PPPM. See
Step 6 below for info about building LAMMPS with an FFT library.
</P>
<P><B>Step 5</B>
</P>
<P>The 3 MPI variables are used to specify an MPI library to build LAMMPS
with.
</P>
<P>If you want LAMMPS to run in parallel, you must have an MPI library
installed on your platform. If you use an MPI-wrapped compiler, such
as "mpicc" to build LAMMPS, you should be able to leave these 3
variables blank; the MPI wrapper knows where to find the needed files.
If not, and MPI is installed on your system in the usual place (under
/usr/local), you also may not need to specify these 3 variables. On
some large parallel machines which use "modules" for their
compile/link environements, you may simply need to include the correct
module in your build environment. Or the parallel machine may have a
vendor-provided MPI which the compiler has no trouble finding.
</P>
<P>Failing this, with these 3 variables you can specify where the mpi.h
file (MPI_INC) and the MPI library file (MPI_PATH) are found and the
name of the library file (MPI_LIB).
</P>
<P>If you are installing MPI yourself, we recommend Argonne's MPICH2
or OpenMPI. MPICH can be downloaded from the <A HREF = "http://www.mcs.anl.gov/research/projects/mpich2/">Argonne MPI
site</A>. OpenMPI can
be downloaded from the <A HREF = "http://www.open-mpi.org">OpenMPI site</A>.
Other MPI packages should also work. If you are running on a big
parallel platform, your system people or the vendor should have
already installed a version of MPI, which is likely to be faster
than a self-installed MPICH or OpenMPI, so find out how to build
and link with it. If you use MPICH or OpenMPI, you will have to
configure and build it for your platform. The MPI configure script
should have compiler options to enable you to use the same compiler
you are using for the LAMMPS build, which can avoid problems that can
arise when linking LAMMPS to the MPI library.
</P>
<P>If you just want to run LAMMPS on a single processor, you can use the
dummy MPI library provided in src/STUBS, since you don't need a true
MPI library installed on your system. See the
src/MAKE/Makefile.serial file for how to specify the 3 MPI variables
in this case. You will also need to build the STUBS library for your
platform before making LAMMPS itself. From the src directory, type
"make stubs", or from the STUBS dir, type "make" and it should create
a libmpi.a suitable for linking to LAMMPS. If this build fails, you
will need to edit the STUBS/Makefile for your platform.
</P>
<P>The file STUBS/mpi.cpp provides a CPU timer function called
MPI_Wtime() that calls gettimeofday() . If your system doesn't
support gettimeofday() , you'll need to insert code to call another
timer. Note that the ANSI-standard function clock() rolls over after
an hour or so, and is therefore insufficient for timing long LAMMPS
simulations.
</P>
<P><B>Step 6</B>
</P>
<P>The 3 FFT variables allow you to specify an FFT library which LAMMPS
uses (for performing 1d FFTs) when running the particle-particle
particle-mesh (PPPM) option for long-range Coulombics via the
<A HREF = "kspace_style.html">kspace_style</A> command.
</P>
<P>LAMMPS supports various open-source or vendor-supplied FFT libraries
for this purpose. If you leave these 3 variables blank, LAMMPS will
use the open-source <A HREF = "http://kissfft.sf.net">KISS FFT library</A>, which is
included in the LAMMPS distribution. This library is portable to all
platforms and for typical LAMMPS simulations is almost as fast as FFTW
or vendor optimized libraries. If you are not including the KSPACE
package in your build, you can also leave the 3 variables blank.
</P>
<P>Otherwise, select which kinds of FFTs to use as part of the FFT_INC
setting by a switch of the form -DFFT_XXX. Recommended values for XXX
are: MKL, SCSL, FFTW2, and FFTW3. Legacy options are: INTEL, SGI,
ACML, and T3E. For backward compatability, using -DFFT_FFTW will use
the FFTW2 library. Using -DFFT_NONE will use the KISS library
described above.
</P>
<P>You may also need to set the FFT_INC, FFT_PATH, and FFT_LIB variables,
so the compiler and linker can find the needed FFT header and library
files. Note that on some large parallel machines which use "modules"
for their compile/link environements, you may simply need to include
the correct module in your build environment. Or the parallel machine
may have a vendor-provided FFT library which the compiler has no
trouble finding.
</P>
<P>FFTW is a fast, portable library that should also work on any
platform. You can download it from
<A HREF = "http://www.fftw.org">www.fftw.org</A>. Both the legacy version 2.1.X and
the newer 3.X versions are supported as -DFFT_FFTW2 or -DFFT_FFTW3.
Building FFTW for your box should be as simple as ./configure; make.
Note that on some platforms FFTW2 has been pre-installed, and uses
renamed files indicating the precision it was compiled with,
e.g. sfftw.h, or dfftw.h instead of fftw.h. In this case, you can
specify an additional define variable for FFT_INC called -DFFTW2_SIZE,
which will select the correct include file. In this case, for FFT_LIB
you must also manually specify the correct library, namely -lsfftw or
-ldfftw.
</P>
<P>The FFT_INC variable also allows for a -DFFT_SINGLE setting that will
use single-precision FFTs with PPPM, which can speed-up long-range
calulations, particularly in parallel or on GPUs. Fourier transform
and related PPPM operations are somewhat insensitive to floating point
truncation errors and thus do not always need to be performed in
double precision. Using the -DFFT_SINGLE setting trades off a little
accuracy for reduced memory use and parallel communication costs for
transposing 3d FFT data. Note that single precision FFTs have only
been tested with the FFTW3, FFTW2, MKL, and KISS FFT options.
</P>
<P><B>Step 7</B>
</P>
<P>The 3 JPG variables allow you to specify a JPEG library which LAMMPS
uses when writing out JPEG files via the <A HREF = "dump_image.html">dump image</A>
command. These can be left blank if you do not use the -DLAMMPS_JPEG
switch discussed above in Step 4, since in that case JPEG output will
be disabled.
</P>
<P>A standard JPEG library usually goes by the name libjpeg.a and has an
associated header file jpeglib.h. Whichever JPEG library you have on
your platform, you'll need to set the appropriate JPG_INC, JPG_PATH,
and JPG_LIB variables, so that the compiler and linker can find it.
</P>
<P>As before, if these header and library files are in the usual place on
your machine, you may not need to set these variables.
</P>
<P><B>Step 8</B>
</P>
<P>Note that by default only a few of LAMMPS optional pacakges are
installed. To build LAMMPS with optional packages, see <A HREF = "#start_3">this
section</A> below, before proceeding to Step 9.
</P>
<P><B>Step 9</B>
</P>
<P>That's it. Once you have a correct Makefile.foo, you have installed
the optional LAMMPS packages you want to include in your build, and
you have pre-built any other needed libraries (e.g. MPI, FFT, package
libraries), all you need to do from the src directory is type
something like this:
</P>
<PRE>make foo
or
gmake foo
</PRE>
<P>You should get the executable lmp_foo when the build is complete.
</P>
<HR>
<A NAME = "start_2_3"></A><B><I>Errors that can occur when making LAMMPS:</I></B>
<P>IMPORTANT NOTE: If an error occurs when building LAMMPS, the compiler
or linker will state very explicitly what the problem is. The error
message should give you a hint as to which of the steps above has
failed, and what you need to do in order to fix it. Building a code
with a Makefile is a very logical process. The compiler and linker
need to find the appropriate files and those files need to be
compatible with LAMMPS source files. When a make fails, there is
usually a very simple reason, which you or a local expert will need to
fix.
</P>
<P>Here are two non-obvious errors that can occur:
</P>
<P>(1) If the make command breaks immediately with errors that indicate
it can't find files with a "*" in their names, this can be because
your machine's native make doesn't support wildcard expansion in a
makefile. Try gmake instead of make. If that doesn't work, try using
a -f switch with your make command to use a pre-generated
Makefile.list which explicitly lists all the needed files, e.g.
</P>
<PRE>make makelist
make -f Makefile.list linux
gmake -f Makefile.list mac
</PRE>
<P>The first "make" command will create a current Makefile.list with all
the file names in your src dir. The 2nd "make" command (make or
gmake) will use it to build LAMMPS. Note that you should
include/exclude any desired optional packages before using the "make
makelist" command.
</P>
<P>(2) If you get an error that says something like 'identifier "atoll"
is undefined', then your machine does not support "long long"
integers. Try using the -DLAMMPS_LONGLONG_TO_LONG setting described
above in Step 4.
</P>
<HR>
<A NAME = "start_2_4"></A><B><I>Additional build tips:</I></B>
<P>(1) Building LAMMPS for multiple platforms.
</P>
<P>You can make LAMMPS for multiple platforms from the same src
directory. Each target creates its own object sub-directory called
Obj_name where it stores the system-specific *.o files.
</P>
<P>(2) Cleaning up.
</P>
<P>Typing "make clean-all" or "make clean-foo" will delete *.o object
files created when LAMMPS is built, for either all builds or for a
particular machine.
</P>
<P>(3) Changing the size limits in src/lmptype.h
</P>
<P>If you are running a very large problem (billions of atoms or more)
and get a run-time error about the system being too big, either on a
per-processor basis or in total size, then you may need to change one
or more settings in src/lmptype.h and re-compile LAMMPS.
</P>
<P>As the documentation in that file explains, you have basically
two choices to make:
</P>
<UL><LI>set the data type size of integer atom IDs to 4 or 8 bytes
<LI>set the data type size of integers that store the total system size to 4 or 8 bytes
</UL>
<P>The default for atom IDs is 4-byte integers since there is a memory
and communication cost for 8-byte integers. Non-molecular problems do
not need atom IDs so this does not restrict their size. Molecular
problems (which use IDs to define molecular topology), are limited to
about 2 billion atoms (2^31) with 4-byte IDs. With 8-byte IDs they
are effectively unlimited in size (2^63).
</P>
<P>The default for total system size quantities (like the number of atoms
or timesteps) is 8-byte integers by default which is effectively
unlimited in size (2^63). If your system or MPI implementation does
not support 8-byte integers, an error will be generated, and you will
need to set "bigint" to 4-byte integers. This restricts your total
system size to about 2 billion atoms or timesteps (2^31).
</P>
<P>Note that in src/lmptype.h there are also settings for the MPI data
types associated with the integers that store atom IDs and total
system sizes, which need to be set consistent with the associated C
data types.
</P>
<P>In all cases, the size of problem that can be run on a per-processor
basis is limited by 4-byte integer storage to about 2 billion atoms
per processor (2^31), which should not normally be a restriction since
such a problem would have a huge per-processor memory footprint due to
neighbor lists and would run very slowly in terms of CPU
secs/timestep.
</P>
<HR>
<A NAME = "start_2_5"></A><B><I>Building for a Mac:</I></B>
<P>OS X is BSD Unix, so it should just work. See the Makefile.mac file.
</P>
<HR>
<A NAME = "start_2_6"></A><B><I>Building for Windows:</I></B>
<P>The LAMMPS download page has an option to download both a serial and
parallel pre-built Windows exeutable. See the <A HREF = "#start_5">Running
LAMMPS</A> section for instructions for running these
executables on a Windows box.
</P>
<P>If the pre-built executable doesn't have the options you want, then
you can build LAMMPS from its source files on a Windows box. One way
to do this is install and use cygwin to build LAMMPS with a standard
Linus make, just as you would on any Linux box; see
src/MAKE/Makefile.cygwin.
</P>
<P>There is a also a src/WINDOWS directory that contains project files
for Microsoft Visual Studio 2005, which should also work with later
versions of VS. That directory contains a README.txt file which
provides instructions for building LAMMPS from source code using
Visual Studio that are hopefully easy to follow for Windows and VS
users.
</P>
<P>Four VS project options are provided. The first includes the default
packages (MANYBODY, MOLECULE, and KSPACE). The second includes all
standard packages (except GPU, MEAM, and REAX which are not yet
included because they require NVIDIA or Fortran compilation). The
third includes all standard packages (with the exceptions) and some
user packages. The included user packages are USER-EFF, USER-CG-CMM,
and USER-REAXC. The fourth project includes the USER-AWPMD package.
</P>
<HR>
<H4><A NAME = "start_3"></A>2.3 Making LAMMPS with optional packages
</H4>
<P>This section has the following sub-sections:
</P>
<UL><LI><A HREF = "#start_3_1">Package basics</A>
<LI><A HREF = "#start_3_2">Including/excluding packages</A>
<LI><A HREF = "#start_3_3">Packages that require extra libraries</A>
<LI><A HREF = "#start_3_4">Additional Makefile settings for extra libraries</A>
</UL>
<HR>
<A NAME = "start_3_1"></A><B><I>Package basics:</I></B>
<P>The source code for LAMMPS is structured as a set of core files which
are always included, plus optional packages. Packages are groups of
files that enable a specific set of features. For example, force
fields for molecular systems or granular systems are in packages. You
can see the list of all packages by typing "make package" from within
the src directory of the LAMMPS distribution.
</P>
<P>If you use a command in a LAMMPS input script that is specific to a
particular package, you must have built LAMMPS with that package, else
you will get an error that the style is invalid or the command is
unknown. Every command's doc page specfies if it is part of a
package. You can also type
</P>
<PRE>lmp_machine -h
</PRE>
<P>to run your executable with the optional <A HREF = "#start_6">-h command-line
switch</A> for "help", which will list the styles and commands
known to your executable.
</P>
<P>There are two kinds of packages in LAMMPS, standard and user packages.
More information about the contents of standard and user packages is
-given in <A HREF = "Section_packages.html">this section</A> of the manual. The
+given in <A HREF = "Section_packages.html">Section_packages</A> of the manual. The
difference between standard and user packages is as follows:
</P>
<P>Standard packages are supported by the LAMMPS developers and are
written in a syntax and style consistent with the rest of LAMMPS.
This means we will answer questions about them, debug and fix them if
necessary, and keep them compatible with future changes to LAMMPS.
</P>
<P>User packages have been contributed by users, and always begin with
the user prefix. If they are a single command (single file), they are
typically in the user-misc package. Otherwise, they are a a set of
files grouped together which add a specific functionality to the code.
</P>
<P>User packages don't necessarily meet the requirements of the standard
packages. If you have problems using a feature provided in a user
package, you will likely need to contact the contributor directly to
get help. Information on how to submit additions you make to LAMMPS
as a user-contributed package is given in <A HREF = "Section_modify.html#mod_14">this
section</A> of the documentation.
</P>
<HR>
<A NAME = "start_3_2"></A><B><I>Including/excluding packages:</I></B>
<P>To use or not use a package you must include or exclude it before
building LAMMPS. From the src directory, this is typically as simple
as:
</P>
<PRE>make yes-colloid
make g++
</PRE>
<P>or
</P>
<PRE>make no-manybody
make g++
</PRE>
<P>Some packages have individual files that depend on other packages
being included. LAMMPS checks for this and does the right thing.
I.e. individual files are only included if their dependencies are
already included. Likewise, if a package is excluded, other files
dependent on that package are also excluded.
</P>
<P>The reason to exclude packages is if you will never run certain kinds
of simulations. For some packages, this will keep you from having to
build auxiliary libraries (see below), and will also produce a smaller
executable which may run a bit faster.
</P>
<P>When you download a LAMMPS tarball, these packages are pre-installed
in the src directory: KSPACE, MANYBODY,MOLECULE. When you download
LAMMPS source files from the SVN or Git repositories, no packages are
pre-installed.
</P>
<P>Packages are included or excluded by typing "make yes-name" or "make
no-name", where "name" is the name of the package in lower-case, e.g.
name = kspace for the KSPACE package or name = user-atc for the
USER-ATC package. You can also type "make yes-standard", "make
no-standard", "make yes-user", "make no-user", "make yes-all" or "make
no-all" to include/exclude various sets of packages. Type "make
package" to see the all of the package-related make options.
</P>
<P>IMPORTANT NOTE: Inclusion/exclusion of a package works by simply
moving files back and forth between the main src directory and
sub-directories with the package name (e.g. src/KSPACE, src/USER-ATC),
so that the files are seen or not seen when LAMMPS is built. After
you have included or excluded a package, you must re-build LAMMPS.
</P>
<P>Additional package-related make options exist to help manage LAMMPS
files that exist in both the src directory and in package
sub-directories. You do not normally need to use these commands
unless you are editing LAMMPS files or have downloaded a patch from
the LAMMPS WWW site.
</P>
<P>Typing "make package-update" will overwrite src files with files from
the package sub-directories if the package has been included. It
should be used after a patch is installed, since patches only update
the files in the package sub-directory, but not the src files. Typing
"make package-overwrite" will overwrite files in the package
sub-directories with src files.
</P>
<P>Typing "make package-status" will show which packages are currently
included. Of those that are included, it will list files that are
different in the src directory and package sub-directory. Typing
"make package-diff" lists all differences between these files. Again,
type "make package" to see all of the package-related make options.
</P>
<HR>
<A NAME = "start_3_3"></A><B><I>Packages that require extra libraries:</I></B>
<P>A few of the standard and user packages require additional auxiliary
libraries to be compiled first. If you get a LAMMPS build error about
a missing library, this is likely the reason. The source code for
these libraries is included in the LAMMPS distribution under the "lib"
directory. Look at the lib/README file for a list of these or see
-<A HREF = "Section_packages.html">this section</A> of the doc pages.
+<A HREF = "Section_packages.html">Section_packages</A> of the doc pages.
</P>
<P>Each lib directory has a README file (e.g. lib/reax/README) with
instructions on how to build that library. Typically this is done
in this manner:
</P>
<PRE>make -f Makefile.g++
</PRE>
<P>in the appropriate directory, e.g. in lib/reax. Some of the libraries
do not build this way. Again, see the libary README file for details.
</P>
<P>In any event, you will need to use a Makefile that is a match for your
system. If one of the provided Makefiles is not appropriate for your
system you will need to edit or add one. For example, in the case of
Fortran-based libraries, your system must have a Fortran compiler, the
settings for which will need to be listed in the Makefile.
</P>
<P>When you have built one of these libraries, there are 2 things to
check:
</P>
<P>(1) The file libname.a should now exist in lib/name.
E.g. lib/reax/libreax.a. This is the library file LAMMPS will link
against. One exception is the lib/cuda library which produces the
file liblammpscuda.a, because there is already a system library
libcuda.a.
</P>
<P>(2) The file Makefile.lammps should exist in lib/name. E.g.
lib/cuda/Makefile.lammps. This file may be auto-generated by the
build of the library, or you may need to make a copy of the
appropriate provided file (e.g. lib/meam/Makefile.lammps.gfortran).
Either way you should insure that the settings in this file are
appropriate for your system.
</P>
<P>There are typically 3 settings in the Makefile.lammps file (unless
some are blank or not needed): a SYSINC, SYSPATH, and SYSLIB setting,
specific to this package. These are settings the LAMMPS build will
import when compiling the LAMMPS package files (not the library
files), and linking to the auxiliary library. They typically list any
other system libraries needed to support the package and where to find
them. An example is the BLAS and LAPACK libraries needed by the
USER-ATC package. Or the system libraries that support calling
Fortran from C++, as the MEAM and REAX packages do.
</P>
<P>Note that if these settings are not correct for your box, the LAMMPS
build will likely fail.
</P>
<HR>
<H4><A NAME = "start_4"></A>2.4 Building LAMMPS as a library
</H4>
<P>LAMMPS itself can be built as a library, which can then be called from
another application or a scripting language. See <A HREF = "Section_howto.html#howto_10">this
section</A> for more info on coupling LAMMPS
to other codes. Building LAMMPS as a library is done by typing
</P>
<PRE>make makelib
make -f Makefile.lib foo
</PRE>
<P>where foo is the machine name. Note that inclusion or exclusion of
any desired optional packages should be done before typing "make
makelib". The first "make" command will create a current Makefile.lib
with all the file names in your src dir. The 2nd "make" command will
use it to build LAMMPS as a library. This requires that Makefile.foo
have a library target (lib) and system-specific settings for ARCHIVE
and ARFLAGS. See Makefile.linux for an example. The build will
create the file liblmp_foo.a which another application can link to.
</P>
<P>When used from a C++ program, the library allows one or more LAMMPS
objects to be instantiated. All of LAMMPS is wrapped in a LAMMPS_NS
namespace; you can safely use any of its classes and methods from
within your application code, as needed.
</P>
<P>When used from a C or Fortran program or a scripting language, the
library has a simple function-style interface, provided in
src/library.cpp and src/library.h.
</P>
<P>See the sample codes couple/simple/simple.cpp and simple.c as examples
of C++ and C codes that invoke LAMMPS thru its library interface.
There are other examples as well in the couple directory which are
-discussed in <A HREF = "Section_howto.html#howto_10">this section</A> of the manual.
-See <A HREF = "Section_python.html">this section</A> of the manual for a description
-of the Python wrapper provided with LAMMPS that operates through the
-LAMMPS library interface.
+discussed in <A HREF = "Section_howto.html#howto_10">Section_howto 10</A> of the
+manual. See <A HREF = "Section_python.html">Section_python</A> of the manual for a
+description of the Python wrapper provided with LAMMPS that operates
+through the LAMMPS library interface.
</P>
<P>The files src/library.cpp and library.h contain the C-style interface
-to LAMMPS. See <A HREF = "Section_howto.html#howto_19">this section</A> of the
+to LAMMPS. See <A HREF = "Section_howto.html#howto_19">Section_howto 19</A> of the
manual for a description of the interface and how to extend it for
your needs.
</P>
<HR>
<H4><A NAME = "start_5"></A>2.5 Running LAMMPS
</H4>
<P>By default, LAMMPS runs by reading commands from stdin; e.g. lmp_linux
< in.file. This means you first create an input script (e.g. in.file)
containing the desired commands. <A HREF = "Section_commands.html">This section</A>
describes how input scripts are structured and what commands they
contain.
</P>
<P>You can test LAMMPS on any of the sample inputs provided in the
examples or bench directory. Input scripts are named in.* and sample
outputs are named log.*.name.P where name is a machine and P is the
number of processors it was run on.
</P>
<P>Here is how you might run a standard Lennard-Jones benchmark on a
Linux box, using mpirun to launch a parallel job:
</P>
<PRE>cd src
make linux
cp lmp_linux ../bench
cd ../bench
mpirun -np 4 lmp_linux < in.lj
</PRE>
<P>See <A HREF = "http://lammps.sandia.gov/bench.html">this page</A> for timings for this and the other benchmarks
on various platforms.
</P>
<HR>
<P>On a Windows box, you can skip making LAMMPS and simply download an
executable, as described above, though the pre-packaged executables
include only certain packages.
</P>
<P>To run a LAMMPS executable on a Windows machine, first decide whether
you want to download the non-MPI (serial) or the MPI (parallel)
version of the executable. Download and save the version you have
chosen.
</P>
<P>For the non-MPI version, follow these steps:
</P>
<UL><LI>Get a command prompt by going to Start->Run... ,
then typing "cmd".
<LI>Move to the directory where you have saved lmp_win_no-mpi.exe
(e.g. by typing: cd "Documents").
<LI>At the command prompt, type "lmp_win_no-mpi -in in.lj", replacing in.lj
with the name of your LAMMPS input script.
</UL>
<P>For the MPI version, which allows you to run LAMMPS under Windows on
multiple processors, follow these steps:
</P>
<UL><LI>Download and install
<A HREF = "http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads">MPICH2</A>
for Windows.
<LI>You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 package. Put them in
same directory (or path) as the LAMMPS Windows executable.
<LI>Get a command prompt by going to Start->Run... ,
then typing "cmd".
<LI>Move to the directory where you have saved lmp_win_mpi.exe
(e.g. by typing: cd "Documents").
<LI>Then type something like this: "mpiexec -np 4 -localonly lmp_win_mpi -in in.lj",
replacing in.lj with the name of your LAMMPS input script.
<LI>Note that you may need to provide smpd with a passphrase --- it doesn't matter what you
type.
<LI>In this mode, output may not immediately show up on the screen, so
if your input script takes a long time to execute, you may need to be
patient before the output shows up.
<LI>Alternatively, you can still use this executable to run on a single processor by
typing something like: "lmp_win_mpi -in in.lj".
</UL>
<HR>
<P>The screen output from LAMMPS is described in the next section. As it
runs, LAMMPS also writes a log.lammps file with the same information.
</P>
<P>Note that this sequence of commands copies the LAMMPS executable
(lmp_linux) to the directory with the input files. This may not be
necessary, but some versions of MPI reset the working directory to
where the executable is, rather than leave it as the directory where
you launch mpirun from (if you launch lmp_linux on its own and not
under mpirun). If that happens, LAMMPS will look for additional input
files and write its output files to the executable directory, rather
than your working directory, which is probably not what you want.
</P>
<P>If LAMMPS encounters errors in the input script or while running a
simulation it will print an ERROR message and stop or a WARNING
-message and continue. See <A HREF = "Section_errors.html">this section</A> for a
+message and continue. See <A HREF = "Section_errors.html">Section_errors</A> for a
discussion of the various kinds of errors LAMMPS can or can't detect,
a list of all ERROR and WARNING messages, and what to do about them.
</P>
<P>LAMMPS can run a problem on any number of processors, including a
single processor. In theory you should get identical answers on any
number of processors and on any machine. In practice, numerical
round-off can cause slight differences and eventual divergence of
molecular dynamics phase space trajectories.
</P>
<P>LAMMPS can run as large a problem as will fit in the physical memory
of one or more processors. If you run out of memory, you must run on
more processors or setup a smaller problem.
</P>
<HR>
<H4><A NAME = "start_6"></A>2.6 Command-line options
</H4>
<P>At run time, LAMMPS recognizes several optional command-line switches
which may be used in any order. Either the full word or a one-or-two
letter abbreviation can be used:
</P>
<UL><LI>-c or -cuda
<LI>-e or -echo
<LI>-i or -in
<LI>-h or -help
<LI>-l or -log
<LI>-p or -partition
<LI>-pl or -plog
<LI>-ps or -pscreen
+<LI>-r or -reorder
<LI>-sc or -screen
<LI>-sf or -suffix
<LI>-v or -var
</UL>
<P>For example, lmp_ibm might be launched as follows:
</P>
<PRE>mpirun -np 16 lmp_ibm -v f tmp.out -l my.log -sc none < in.alloy
mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy
</PRE>
<P>Here are the details on the options:
</P>
<PRE>-cuda on/off
</PRE>
<P>Explicitly enable or disable CUDA support, as provided by the
USER-CUDA package. If LAMMPS is built with this package, as described
above in <A HREF = "#start_3">Section 2.3</A>, then by default LAMMPS will run in
CUDA mode. If this switch is set to "off", then it will not, even if
it was built with the USER-CUDA package, which means you can run
standard LAMMPS or with the GPU package for testing or benchmarking
purposes. The only reason to set the switch to "on", is to check if
LAMMPS was built with the USER-CUDA package, since an error will be
generated if it was not.
</P>
<PRE>-echo style
</PRE>
<P>Set the style of command echoing. The style can be <I>none</I> or <I>screen</I>
or <I>log</I> or <I>both</I>. Depending on the style, each command read from
the input script will be echoed to the screen and/or logfile. This
can be useful to figure out which line of your script is causing an
input error. The default value is <I>log</I>. The echo style can also be
set by using the <A HREF = "echo.html">echo</A> command in the input script itself.
</P>
<PRE>-in file
</PRE>
<P>Specify a file to use as an input script. This is an optional switch
when running LAMMPS in one-partition mode. If it is not specified,
LAMMPS reads its input script from stdin - e.g. lmp_linux < in.run.
This is a required switch when running LAMMPS in multi-partition mode,
since multiple processors cannot all read from stdin.
</P>
<PRE>-help
</PRE>
<P>Print a list of options compiled into this executable for each LAMMPS
style (atom_style, fix, compute, pair_style, bond_style, etc). This
can help you know if the command you want to use was included via the
appropriate package. LAMMPS will print the info and immediately exit
if this switch is used.
</P>
<PRE>-log file
</PRE>
<P>Specify a log file for LAMMPS to write status information to. In
one-partition mode, if the switch is not used, LAMMPS writes to the
file log.lammps. If this switch is used, LAMMPS writes to the
specified file. In multi-partition mode, if the switch is not used, a
log.lammps file is created with hi-level status information. Each
partition also writes to a log.lammps.N file where N is the partition
ID. If the switch is specified in multi-partition mode, the hi-level
logfile is named "file" and each partition also logs information to a
file.N. For both one-partition and multi-partition mode, if the
specified file is "none", then no log files are created. Using a
<A HREF = "log.html">log</A> command in the input script will override this setting.
Option -plog will override the name of the partition log files file.N.
</P>
<PRE>-partition 8x2 4 5 ...
</PRE>
<P>Invoke LAMMPS in multi-partition mode. When LAMMPS is run on P
processors and this switch is not used, LAMMPS runs in one partition,
i.e. all P processors run a single simulation. If this switch is
used, the P processors are split into separate partitions and each
partition runs its own simulation. The arguments to the switch
specify the number of processors in each partition. Arguments of the
form MxN mean M partitions, each with N processors. Arguments of the
form N mean a single partition with N processors. The sum of
processors in all partitions must equal P. Thus the command
"-partition 8x2 4 5" has 10 partitions and runs on a total of 25
processors.
</P>
-<P>Note that with MPI installed on a machine (e.g. your desktop), you can
-run on more (virtual) processors than you have physical processors.
-This can be useful for running <A HREF = "Section_howto.html#howto_5">multi-replica
-simulations</A>, on one or a few processors.
+<P>Running with multiple partitions can e useful for running
+<A HREF = "Section_howto.html#howto_5">multi-replica simulations</A>, where each
+replica runs on on one or a few processors. Note that with MPI
+installed on a machine (e.g. your desktop), you can run on more
+(virtual) processors than you have physical processors.
</P>
-<P>The input script specifies what simulation is run on which partition;
-see the <A HREF = "variable.html">variable</A> and <A HREF = "next.html">next</A> commands. This
-<A HREF = "Section_howto.html#howto_4">howto section</A> gives examples of how to
-use these commands in this way. Simulations running on different
-partitions can also communicate with each other; see the
-<A HREF = "temper.html">temper</A> command.
+<P>To run multiple independent simulatoins from one input script, using
+multiple partitions, see <A HREF = "Section_howto.html#howto_4">Section_howto 4</A>
+of the manual. World- and universe-style <A HREF = "variable.html">variables</A>
+are useful in this context.
</P>
<PRE>-plog file
</PRE>
-<P>Specify the base name for the partition log files,
-so partition N writes log information to file.N. If file is
-none, then no partition log files are created.
-This overrides the
-filename specified in the -log command-line option.
-This option is useful when working with large numbers of partitions,
-allowing the partition log files to be suppressed (-plog none) or
-placed in a sub-directory (-plog replica_files/log.lammps)
-If this option is not used
-the log file for partition N is log.lammps.N or whatever is specified by
-the -log command-line option.
+<P>Specify the base name for the partition log files, so partition N
+writes log information to file.N. If file is none, then no partition
+log files are created. This overrides the filename specified in the
+-log command-line option. This option is useful when working with
+large numbers of partitions, allowing the partition log files to be
+suppressed (-plog none) or placed in a sub-directory (-plog
+replica_files/log.lammps) If this option is not used the log file for
+partition N is log.lammps.N or whatever is specified by the -log
+command-line option.
</P>
<PRE>-pscreen file
</PRE>
-<P>Specify the base name for the
-partition screen file, so partition N writes
-screen information to file.N. If file is
-none, then no partition screen files are created.
-This overrides the
-filename specified in the -screen command-line option.
-This option is useful when working with large numbers of partitions,
-allowing the partition screen files to be suppressed (-pscreen none) or
-placed in a sub-directory (-pscreen replica_files/screen)
-If this option is not used
-the screen file for partition N is screen.N or whatever is specified by
-the -screen command-line option.
+<P>Specify the base name for the partition screen file, so partition N
+writes screen information to file.N. If file is none, then no
+partition screen files are created. This overrides the filename
+specified in the -screen command-line option. This option is useful
+when working with large numbers of partitions, allowing the partition
+screen files to be suppressed (-pscreen none) or placed in a
+sub-directory (-pscreen replica_files/screen). If this option is not
+used the screen file for partition N is screen.N or whatever is
+specified by the -screen command-line option.
+</P>
+<PRE>-reorder nth N
+-reorder custom filename
+</PRE>
+<P>Reorder the processors in the MPI communicator used to instantiate
+LAMMPS, in one of several ways. The original MPI communicator ranks
+all P processors from 0 to P-1. The mapping of these ranks to
+physical processors is done by MPI before LAMMPS begins. It may be
+useful in some cases to alter the rank order. E.g. to insure that
+cores within each node are ranked in a desired order. Or when using
+the <A HREF = "run_style.html">run_style verlet/split</A> command with 2 partitions
+to insure that a specific Kspace processor (in the 2nd partition) is
+matched up with a specific set of processors in the 1st partition.
+See the <A HREF = "Section_accelerate.html">Section_accelerate</A> doc pages for
+more details.
+</P>
+<P>If the keyword <I>nth</I> is used with a setting <I>N</I>, then it means every
+Nth processor will be moved to the end of the ranking. This is useful
+when using the <A HREF = "run_style.html">run_style verlet/split</A> command with 2
+partitions via the -partition command-line switch. The first set of
+processors will be in the first partition, the 2nd set in the 2nd
+partition. The -reorder command-line switch can alter this so that
+the 1st N procs in the 1st partition and one proc in the 2nd partition
+will be ordered consecutively, e.g. as the cores on one physical node.
+This can boost performance. For example, if you use "-reorder nth 4"
+and "-partition 9 3" and you are running on 12 processors, the
+processors will be reordered from
+</P>
+<PRE>0 1 2 3 4 5 6 7 8 9 10 11
+</PRE>
+<P>to
+</P>
+<PRE>0 1 2 4 5 6 8 9 10 3 7 11
+</PRE>
+<P>so that the processors in each partition will be
+</P>
+<PRE>0 1 2 4 5 6 8 9 10
+3 7 11
+</PRE>
+<P>See the "processors" command for how to insure processors from each
+partition could then be grouped optimally for quad-core nodes.
+</P>
+<P>If the keyword is <I>custom", then a file that specifies a permutation
+of the processor ranks is also specified. The format of the reorder
+file is as follows. Any number of initial blank or comment lines
+(starting with a "#" character) can be present. These should be
+followed by P lines of the form:
+</P>
+<PRE>I J
+</PRE>
+<P>where P is the number of processors LAMMPS was launched with. Note
+that if running in multi-partition mode (see the -partition switch
+above) P is the total number of processors in all partitions. The I
+and J values describe a permutation of the P processors. Every I and
+J should be values from 0 to P-1 inclusive. In the set of P I values,
+every proc ID should appear exactly once. Ditto for the set of P J
+values. A single I,J pairing means that the physical processor with
+rank I in the original MPI communicator will have rank J in the
+reordered communicator.
+</P>
+<P>Note that rank ordering can also be specified by many MPI
+implementations, either by environment variables that specify how to
+order physical processors, or by config files that specify what
+physical processors to assign to each MPI rank. The -reorder switch
+simply gives you a portable way to do this without relying on MPI
+itself. See the <A HREF = "processors">processors out</A> command for how to output
+info on the final assignment of physical processors to the LAMMPS
+simulation domain.
</P>
<PRE>-screen file
</PRE>
<P>Specify a file for LAMMPS to write its screen information to. In
one-partition mode, if the switch is not used, LAMMPS writes to the
screen. If this switch is used, LAMMPS writes to the specified file
instead and you will see no screen output. In multi-partition mode,
if the switch is not used, hi-level status information is written to
the screen. Each partition also writes to a screen.N file where N is
the partition ID. If the switch is specified in multi-partition mode,
the hi-level screen dump is named "file" and each partition also
writes screen information to a file.N. For both one-partition and
multi-partition mode, if the specified file is "none", then no screen
-output is performed. Option -pscreen will override the name of the
+output is performed. Option -pscreen will override the name of the
partition screen files file.N.
</P>
<PRE>-suffix style
</PRE>
<P>Use variants of various styles if they exist. The specified style can
be <I>opt</I>, <I>omp</I>, <I>gpu</I>, or <I>cuda</I>. These refer to optional packages that
LAMMPS can be built with, as described above in <A HREF = "#start_3">Section
2.3</A>. The "opt" style corrsponds to the OPT package, the
"omp" style to the USER-OMP package, the "gpu" style to the GPU
package, and the "cuda" style to the USER-CUDA package.
</P>
<P>As an example, all of the packages provide a <A HREF = "pair_lj.html">pair_style
lj/cut</A> variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
-suffix switch is used, you do not need to modify your input script.
-The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever
-your input script command creates a new <A HREF = "atom_style.html">atom</A>,
-<A HREF = "pair_style.html">pair</A>, <A HREF = "fix.html">fix</A>, <A HREF = "compute.html">compute</A>, or
-<A HREF = "run_style.html">run</A> style. atom, pair, fix, compute, or integrate
-style. If the variant version does not exist, the standard version is
-created.
+The specified suffix (opt,omp,gpu,cuda) is automatically appended
+whenever your input script command creates a new
+<A HREF = "atom_style.html">atom</A>, <A HREF = "pair_style.html">pair</A>, <A HREF = "fix.html">fix</A>,
+<A HREF = "compute.html">compute</A>, or <A HREF = "run_style.html">run</A> style. If the variant
+version does not exist, the standard version is created.
+</P>
+<P>For the GPU package, using this command-line switch also invokes the
+default GPU settings, as if the command "package gpu force/neigh 0 0
+1" were used at the top of your input script. These settings can be
+changed by using the <A HREF = "pacakge.html">package gpu</A> command in your script
+if desired.
+</P>
+<P>For the OMP package, using this command-line switch also invokes the
+default OMP settings, as if the command "package omp *" were used at
+the top of your input script. These settings can be changed by using
+the <A HREF = "pacakge.html">package omp</A> command in your script if desired.
</P>
<P>The <A HREF = "suffix.html">suffix</A> command can also set a suffix and it can also
turn off/on any suffix setting made via the command line.
</P>
<PRE>-var name value1 value2 ...
</PRE>
<P>Specify a variable that will be defined for substitution purposes when
the input script is read. "Name" is the variable name which can be a
single character (referenced as $x in the input script) or a full
string (referenced as ${abc}). An <A HREF = "variable.html">index-style
variable</A> will be created and populated with the
subsequent values, e.g. a set of filenames. Using this command-line
option is equivalent to putting the line "variable name index value1
value2 ..." at the beginning of the input script. Defining an index
variable as a command-line argument overrides any setting for the same
index variable in the input script, since index variables cannot be
re-defined. See the <A HREF = "variable.html">variable</A> command for more info on
defining index and other kinds of variables and <A HREF = "Section_commands.html#cmd_2">this
section</A> for more info on using variables
in input scripts.
</P>
<P>NOTE: Currently, the command-line parser looks for arguments that
start with "-" to indicate new switches. Thus you cannot specify
multiple variable values if any of they start with a "-", e.g. a
negative numeric value. It is OK if the first value1 starts with a
"-", since it is automatically skipped.
</P>
<HR>
<H4><A NAME = "start_7"></A>2.7 LAMMPS screen output
</H4>
<P>As LAMMPS reads an input script, it prints information to both the
screen and a log file about significant actions it takes to setup a
simulation. When the simulation is ready to begin, LAMMPS performs
various initializations and prints the amount of memory (in MBytes per
processor) that the simulation requires. It also prints details of
the initial thermodynamic state of the system. During the run itself,
thermodynamic information is printed periodically, every few
timesteps. When the run concludes, LAMMPS prints the final
thermodynamic state and a total run time for the simulation. It then
appends statistics about the CPU time and storage requirements for the
simulation. An example set of statistics is shown here:
</P>
<PRE>Loop time of 49.002 on 2 procs for 2004 atoms
</PRE>
<PRE>Pair time (%) = 35.0495 (71.5267)
Bond time (%) = 0.092046 (0.187841)
Kspce time (%) = 6.42073 (13.103)
Neigh time (%) = 2.73485 (5.5811)
Comm time (%) = 1.50291 (3.06703)
Outpt time (%) = 0.013799 (0.0281601)
Other time (%) = 2.13669 (4.36041)
</PRE>
<PRE>Nlocal: 1002 ave, 1015 max, 989 min
Histogram: 1 0 0 0 0 0 0 0 0 1
Nghost: 8720 ave, 8724 max, 8716 min
Histogram: 1 0 0 0 0 0 0 0 0 1
Neighs: 354141 ave, 361422 max, 346860 min
Histogram: 1 0 0 0 0 0 0 0 0 1
</PRE>
<PRE>Total # of neighbors = 708282
Ave neighs/atom = 353.434
Ave special neighs/atom = 2.34032
Number of reneighborings = 42
Dangerous reneighborings = 2
</PRE>
<P>The first section gives the breakdown of the CPU run time (in seconds)
into major categories. The second section lists the number of owned
atoms (Nlocal), ghost atoms (Nghost), and pair-wise neighbors stored
per processor. The max and min values give the spread of these values
across processors with a 10-bin histogram showing the distribution.
The total number of histogram counts is equal to the number of
processors.
</P>
<P>The last section gives aggregate statistics for pair-wise neighbors
and special neighbors that LAMMPS keeps track of (see the
<A HREF = "special_bonds.html">special_bonds</A> command). The number of times
neighbor lists were rebuilt during the run is given as well as the
number of potentially "dangerous" rebuilds. If atom movement
triggered neighbor list rebuilding (see the
<A HREF = "neigh_modify.html">neigh_modify</A> command), then dangerous
reneighborings are those that were triggered on the first timestep
atom movement was checked for. If this count is non-zero you may wish
to reduce the delay factor to insure no force interactions are missed
by atoms moving beyond the neighbor skin distance before a rebuild
takes place.
</P>
<P>If an energy minimization was performed via the
<A HREF = "minimize.html">minimize</A> command, additional information is printed,
e.g.
</P>
<PRE>Minimization stats:
E initial, next-to-last, final = -0.895962 -2.94193 -2.94342
Gradient 2-norm init/final= 1920.78 20.9992
Gradient inf-norm init/final= 304.283 9.61216
Iterations = 36
Force evaluations = 177
</PRE>
<P>The first line lists the initial and final energy, as well as the
energy on the next-to-last iteration. The next 2 lines give a measure
of the gradient of the energy (force on all atoms). The 2-norm is the
"length" of this force vector; the inf-norm is the largest component.
The last 2 lines are statistics on how many iterations and
force-evaluations the minimizer required. Multiple force evaluations
are typically done at each iteration to perform a 1d line minimization
in the search direction.
</P>
<P>If a <A HREF = "kspace_style.html">kspace_style</A> long-range Coulombics solve was
performed during the run (PPPM, Ewald), then additional information is
printed, e.g.
</P>
<PRE>FFT time (% of Kspce) = 0.200313 (8.34477)
FFT Gflps 3d 1d-only = 2.31074 9.19989
</PRE>
<P>The first line gives the time spent doing 3d FFTs (4 per timestep) and
the fraction it represents of the total KSpace time (listed above).
Each 3d FFT requires computation (3 sets of 1d FFTs) and communication
(transposes). The total flops performed is 5Nlog_2(N), where N is the
number of points in the 3d grid. The FFTs are timed with and without
the communication and a Gflop rate is computed. The 3d rate is with
communication; the 1d rate is without (just the 1d FFTs). Thus you
can estimate what fraction of your FFT time was spent in
communication, roughly 75% in the example above.
</P>
<HR>
<H4><A NAME = "start_8"></A>2.8 Tips for users of previous LAMMPS versions
</H4>
<P>The current C++ began with a complete rewrite of LAMMPS 2001, which
was written in F90. Features of earlier versions of LAMMPS are listed
-in <A HREF = "Section_history.html">this section</A>. The F90 and F77 versions
+in <A HREF = "Section_history.html">Section_history</A>. The F90 and F77 versions
(2001 and 99) are also freely distributed as open-source codes; check
the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> for distribution information if you prefer
those versions. The 99 and 2001 versions are no longer under active
development; they do not have all the features of C++ LAMMPS.
</P>
<P>If you are a previous user of LAMMPS 2001, these are the most
significant changes you will notice in C++ LAMMPS:
</P>
<P>(1) The names and arguments of many input script commands have
changed. All commands are now a single word (e.g. read_data instead
of read data).
</P>
<P>(2) All the functionality of LAMMPS 2001 is included in C++ LAMMPS,
but you may need to specify the relevant commands in different ways.
</P>
<P>(3) The format of the data file can be streamlined for some problems.
See the <A HREF = "read_data.html">read_data</A> command for details. The data file
section "Nonbond Coeff" has been renamed to "Pair Coeff" in C++ LAMMPS.
</P>
<P>(4) Binary restart files written by LAMMPS 2001 cannot be read by C++
LAMMPS with a <A HREF = "read_restart.html">read_restart</A> command. This is
because they were output by F90 which writes in a different binary
format than C or C++ writes or reads. Use the <I>restart2data</I> tool
provided with LAMMPS 2001 to convert the 2001 restart file to a text
data file. Then edit the data file as necessary before using the C++
LAMMPS <A HREF = "read_data.html">read_data</A> command to read it in.
</P>
<P>(5) There are numerous small numerical changes in C++ LAMMPS that mean
you will not get identical answers when comparing to a 2001 run.
However, your initial thermodynamic energy and MD trajectory should be
close if you have setup the problem for both codes the same.
</P>
</HTML>
diff --git a/doc/Section_start.txt b/doc/Section_start.txt
index 9e632e731..8b15c97f1 100644
--- a/doc/Section_start.txt
+++ b/doc/Section_start.txt
@@ -1,1163 +1,1246 @@
"Previous Section"_Section_intro.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_commands.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
2. Getting Started :h3
This section describes how to build and run LAMMPS, for both new and
experienced users.
2.1 "What's in the LAMMPS distribution"_#start_1
2.2 "Making LAMMPS"_#start_2
2.3 "Making LAMMPS with optional packages"_#start_3
2.4 "Building LAMMPS as a library"_#start_4
2.5 "Running LAMMPS"_#start_5
2.6 "Command-line options"_#start_6
2.7 "Screen output"_#start_7
2.8 "Tips for users of previous versions"_#start_8 :all(b)
+:line
:line
2.1 What's in the LAMMPS distribution :h4,link(start_1)
When you download LAMMPS you will need to unzip and untar the
downloaded file with the following commands, after placing the file in
an appropriate directory.
gunzip lammps*.tar.gz
tar xvf lammps*.tar :pre
This will create a LAMMPS directory containing two files and several
sub-directories:
README: text file
LICENSE: the GNU General Public License (GPL)
bench: benchmark problems
couple: code coupling examples, using LAMMPS as a library
doc: documentation
examples: simple test problems
potentials: embedded atom method (EAM) potential files
src: source files
tools: pre- and post-processing tools :tb(s=:)
If you download one of the Windows executables from the download page,
then you just get a single file:
lmp_windows.exe :pre
Skip to the "Running LAMMPS"_#start_5 sections for info on how to
launch these executables on a Windows box.
The Windows executables for serial or parallel only include certain
packages and bug-fixes/upgrades listed on "this
page"_http://lammps.sandia.gov/bug.html up to a certain date, as
stated on the download page. If you want something with more packages
or that is more current, you'll have to download the source tarball
and build it yourself from source code using Microsoft Visual Studio,
as described in the next section.
:line
2.2 Making LAMMPS :h4,link(start_2)
This section has the following sub-sections:
"Read this first"_#start_2_1
"Steps to build a LAMMPS executable"_#start_2_2
"Common errors that can occur when making LAMMPS"_#start_2_3
"Additional build tips"_#start_2_4
"Building for a Mac"_#start_2_5
"Building for Windows"_#start_2_6 :ul
:line
[{Read this first:}] :link(start_2_1)
Building LAMMPS can be non-trivial. You may need to edit a makefile,
there are compiler options to consider, additional libraries can be
used (MPI, FFT, JPEG), LAMMPS packages may be included or excluded,
some of these packages use auxiliary libraries which need to be
pre-built, etc.
Please read this section carefully. If you are not comfortable with
makefiles, or building codes on a Unix platform, or running an MPI job
on your machine, please find a local expert to help you. Many
compiling, linking, and run problems that users have are not really
LAMMPS issues - they are peculiar to the user's system, compilers,
libraries, etc. Such questions are better answered by a local expert.
If you have a build problem that you are convinced is a LAMMPS issue
(e.g. the compiler complains about a line of LAMMPS source code), then
please send an email to the
"developers"_http://lammps.sandia.gov/authors.html.
If you succeed in building LAMMPS on a new kind of machine, for which
there isn't a similar Makefile for in the src/MAKE directory, send it
to the developers and we'll include it in future LAMMPS releases.
:line
[{Steps to build a LAMMPS executable:}] :link(start_2_2)
[Step 0]
The src directory contains the C++ source and header files for LAMMPS.
It also contains a top-level Makefile and a MAKE sub-directory with
low-level Makefile.* files for many machines. From within the src
directory, type "make" or "gmake". You should see a list of available
choices. If one of those is the machine and options you want, you can
type a command like:
make linux
or
gmake mac :pre
Note that on a multi-processor or multi-core platform you can launch a
parallel make, by using the "-j" switch with the make command, which
will build LAMMPS more quickly.
If you get no errors and an executable like lmp_linux or lmp_mac is
produced, you're done; it's your lucky day.
Note that by default only a few of LAMMPS optional pacakges are
installed. To build LAMMPS with optional packages, see "this
section"_#start_3 below.
[Step 1]
If Step 0 did not work, you will need to create a low-level Makefile
for your machine, like Makefile.foo. You should make a copy of an
existing src/MAKE/Makefile.* as a starting point. The only portions
of the file you need to edit are the first line, the "compiler/linker
settings" section, and the "LAMMPS-specific settings" section.
[Step 2]
Change the first line of src/MAKE/Makefile.foo to list the word "foo"
after the "#", and whatever other options it will set. This is the
line you will see if you just type "make".
[Step 3]
The "compiler/linker settings" section lists compiler and linker
settings for your C++ compiler, including optimization flags. You can
use g++, the open-source GNU compiler, which is available on all Unix
systems. You can also use mpicc which will typically be available if
MPI is installed on your system, though you should check which actual
compiler it wraps. Vendor compilers often produce faster code. On
boxes with Intel CPUs, we suggest using the commercial Intel icc
compiler, which can be downloaded from "Intel's compiler site"_intel.
:link(intel,http://www.intel.com/software/products/noncom)
If building a C++ code on your machine requires additional libraries,
then you should list them as part of the LIB variable.
The DEPFLAGS setting is what triggers the C++ compiler to create a
dependency list for a source file. This speeds re-compilation when
source (*.cpp) or header (*.h) files are edited. Some compilers do
not support dependency file creation, or may use a different switch
than -D. GNU g++ works with -D. If your compiler can't create
dependency files, then you'll need to create a Makefile.foo patterned
after Makefile.storm, which uses different rules that do not involve
dependency files. Note that when you build LAMMPS for the first time
on a new platform, a long list of *.d files will be printed out
rapidly. This is not an error; it is the Makefile doing its normal
creation of dependencies.
[Step 4]
The "system-specific settings" section has several parts. Note that
if you change any -D setting in this section, you should do a full
re-compile, after typing "make clean" (which will describe different
clean options).
The LMP_INC variable is used to include options that turn on ifdefs
within the LAMMPS code. The options that are currently recogized are:
-DLAMMPS_GZIP
-DLAMMPS_JPEG
+-DLAMMPS_MEMALIGN
-DLAMMPS_XDR
-DLAMMPS_SMALLBIG
-DLAMMPS_BIGBIG
-DLAMMPS_SMALLSMALL
-DLAMMPS_LONGLONG_TO_LONG
-DPACK_ARRAY
-DPACK_POINTER
-DPACK_MEMCPY
-DNODE_PARTITION :ul
The read_data and dump commands will read/write gzipped files if you
compile with -DLAMMPS_GZIP. It requires that your Unix support the
"popen" command.
If you use -DLAMMPS_JPEG, the "dump image"_dump.html command will be
able to write out JPEG image files. If not, it will only be able to
write out text-based PPM image files. For JPEG files, you must also
link LAMMPS with a JPEG library, as described below.
+Using -DLAMMPS_MEMALIGN=<bytes> enables the use of the
+posix_memalign() call instead of malloc() when large chunks or memory
+are allocated by LAMMPS. This can help to make more efficient use of
+vector instructions of modern CPUS, since dynamically allocated memory
+has to be aligned on larger than default byte boundaries (e.g. 16
+bytes instead of 8 bytes on x86 type platforms) for optimal
+performance.
+
If you use -DLAMMPS_XDR, the build will include XDR compatibility
files for doing particle dumps in XTC format. This is only necessary
if your platform does have its own XDR files available. See the
Restrictions section of the "dump"_dump.html command for details.
Use at most one of the -DLAMMPS_SMALLBIG, -DLAMMPS_BIGBIG,
-D-DLAMMPS_SMALLSMALL settings. The default is -DLAMMPS_SMALLBIG.
These refer to use of 4-byte (small) vs 8-byte (big) integers within
LAMMPS, as described in src/lmptype.h. The only reason to use the
BIGBIG setting is to enable simulation of huge molecular systems with
more than 2 billion atoms. The only reason to use the SMALLSMALL
setting is if your machine does not support 64-bit integers.
The -DLAMMPS_LONGLONG_TO_LONG setting may be needed if your system or
MPI version does not recognize "long long" data types. In this case a
"long" data type is likely already 64-bits, in which case this setting
will convert to that data type.
Using one of the -DPACK_ARRAY, -DPACK_POINTER, and -DPACK_MEMCPY
options can make for faster parallel FFTs (in the PPPM solver) on some
platforms. The -DPACK_ARRAY setting is the default. See the
"kspace_style"_kspace_style.html command for info about PPPM. See
Step 6 below for info about building LAMMPS with an FFT library.
The -DNODE_PARTITION option will perform a two-level factorization
of the simulation box to minimize the inter-node communication. This
can improve parallel efficiency by reducing network traffic.
When this is set, the simulation box is divided amoung the nodes.
Within each node, the subdomain is further divided between the
cores on each node. The setting will have no impact on a simulation
if 1) there are less than 4 cores per node, 2) the number of MPI
processes is not divisible by the number of cores used per node, or
3) the "processors"_processors.html command is used to specify a
grid dimension with a value greater than 1.
[Step 5]
The 3 MPI variables are used to specify an MPI library to build LAMMPS
with.
If you want LAMMPS to run in parallel, you must have an MPI library
installed on your platform. If you use an MPI-wrapped compiler, such
as "mpicc" to build LAMMPS, you should be able to leave these 3
variables blank; the MPI wrapper knows where to find the needed files.
If not, and MPI is installed on your system in the usual place (under
/usr/local), you also may not need to specify these 3 variables. On
some large parallel machines which use "modules" for their
compile/link environements, you may simply need to include the correct
module in your build environment. Or the parallel machine may have a
vendor-provided MPI which the compiler has no trouble finding.
Failing this, with these 3 variables you can specify where the mpi.h
file (MPI_INC) and the MPI library file (MPI_PATH) are found and the
name of the library file (MPI_LIB).
If you are installing MPI yourself, we recommend Argonne's MPICH2
or OpenMPI. MPICH can be downloaded from the "Argonne MPI
site"_http://www.mcs.anl.gov/research/projects/mpich2/. OpenMPI can
be downloaded from the "OpenMPI site"_http://www.open-mpi.org.
Other MPI packages should also work. If you are running on a big
parallel platform, your system people or the vendor should have
already installed a version of MPI, which is likely to be faster
than a self-installed MPICH or OpenMPI, so find out how to build
and link with it. If you use MPICH or OpenMPI, you will have to
configure and build it for your platform. The MPI configure script
should have compiler options to enable you to use the same compiler
you are using for the LAMMPS build, which can avoid problems that can
arise when linking LAMMPS to the MPI library.
If you just want to run LAMMPS on a single processor, you can use the
dummy MPI library provided in src/STUBS, since you don't need a true
MPI library installed on your system. See the
src/MAKE/Makefile.serial file for how to specify the 3 MPI variables
in this case. You will also need to build the STUBS library for your
platform before making LAMMPS itself. From the src directory, type
"make stubs", or from the STUBS dir, type "make" and it should create
a libmpi.a suitable for linking to LAMMPS. If this build fails, you
will need to edit the STUBS/Makefile for your platform.
The file STUBS/mpi.cpp provides a CPU timer function called
MPI_Wtime() that calls gettimeofday() . If your system doesn't
support gettimeofday() , you'll need to insert code to call another
timer. Note that the ANSI-standard function clock() rolls over after
an hour or so, and is therefore insufficient for timing long LAMMPS
simulations.
[Step 6]
The 3 FFT variables allow you to specify an FFT library which LAMMPS
uses (for performing 1d FFTs) when running the particle-particle
particle-mesh (PPPM) option for long-range Coulombics via the
"kspace_style"_kspace_style.html command.
LAMMPS supports various open-source or vendor-supplied FFT libraries
for this purpose. If you leave these 3 variables blank, LAMMPS will
use the open-source "KISS FFT library"_http://kissfft.sf.net, which is
included in the LAMMPS distribution. This library is portable to all
platforms and for typical LAMMPS simulations is almost as fast as FFTW
or vendor optimized libraries. If you are not including the KSPACE
package in your build, you can also leave the 3 variables blank.
Otherwise, select which kinds of FFTs to use as part of the FFT_INC
setting by a switch of the form -DFFT_XXX. Recommended values for XXX
are: MKL, SCSL, FFTW2, and FFTW3. Legacy options are: INTEL, SGI,
ACML, and T3E. For backward compatability, using -DFFT_FFTW will use
the FFTW2 library. Using -DFFT_NONE will use the KISS library
described above.
You may also need to set the FFT_INC, FFT_PATH, and FFT_LIB variables,
so the compiler and linker can find the needed FFT header and library
files. Note that on some large parallel machines which use "modules"
for their compile/link environements, you may simply need to include
the correct module in your build environment. Or the parallel machine
may have a vendor-provided FFT library which the compiler has no
trouble finding.
FFTW is a fast, portable library that should also work on any
platform. You can download it from
"www.fftw.org"_http://www.fftw.org. Both the legacy version 2.1.X and
the newer 3.X versions are supported as -DFFT_FFTW2 or -DFFT_FFTW3.
Building FFTW for your box should be as simple as ./configure; make.
Note that on some platforms FFTW2 has been pre-installed, and uses
renamed files indicating the precision it was compiled with,
e.g. sfftw.h, or dfftw.h instead of fftw.h. In this case, you can
specify an additional define variable for FFT_INC called -DFFTW2_SIZE,
which will select the correct include file. In this case, for FFT_LIB
you must also manually specify the correct library, namely -lsfftw or
-ldfftw.
The FFT_INC variable also allows for a -DFFT_SINGLE setting that will
use single-precision FFTs with PPPM, which can speed-up long-range
calulations, particularly in parallel or on GPUs. Fourier transform
and related PPPM operations are somewhat insensitive to floating point
truncation errors and thus do not always need to be performed in
double precision. Using the -DFFT_SINGLE setting trades off a little
accuracy for reduced memory use and parallel communication costs for
transposing 3d FFT data. Note that single precision FFTs have only
been tested with the FFTW3, FFTW2, MKL, and KISS FFT options.
[Step 7]
The 3 JPG variables allow you to specify a JPEG library which LAMMPS
uses when writing out JPEG files via the "dump image"_dump_image.html
command. These can be left blank if you do not use the -DLAMMPS_JPEG
switch discussed above in Step 4, since in that case JPEG output will
be disabled.
A standard JPEG library usually goes by the name libjpeg.a and has an
associated header file jpeglib.h. Whichever JPEG library you have on
your platform, you'll need to set the appropriate JPG_INC, JPG_PATH,
and JPG_LIB variables, so that the compiler and linker can find it.
As before, if these header and library files are in the usual place on
your machine, you may not need to set these variables.
[Step 8]
Note that by default only a few of LAMMPS optional pacakges are
installed. To build LAMMPS with optional packages, see "this
section"_#start_3 below, before proceeding to Step 9.
[Step 9]
That's it. Once you have a correct Makefile.foo, you have installed
the optional LAMMPS packages you want to include in your build, and
you have pre-built any other needed libraries (e.g. MPI, FFT, package
libraries), all you need to do from the src directory is type
something like this:
make foo
or
gmake foo :pre
You should get the executable lmp_foo when the build is complete.
:line
[{Errors that can occur when making LAMMPS:}] :link(start_2_3)
IMPORTANT NOTE: If an error occurs when building LAMMPS, the compiler
or linker will state very explicitly what the problem is. The error
message should give you a hint as to which of the steps above has
failed, and what you need to do in order to fix it. Building a code
with a Makefile is a very logical process. The compiler and linker
need to find the appropriate files and those files need to be
compatible with LAMMPS source files. When a make fails, there is
usually a very simple reason, which you or a local expert will need to
fix.
Here are two non-obvious errors that can occur:
(1) If the make command breaks immediately with errors that indicate
it can't find files with a "*" in their names, this can be because
your machine's native make doesn't support wildcard expansion in a
makefile. Try gmake instead of make. If that doesn't work, try using
a -f switch with your make command to use a pre-generated
Makefile.list which explicitly lists all the needed files, e.g.
make makelist
make -f Makefile.list linux
gmake -f Makefile.list mac :pre
The first "make" command will create a current Makefile.list with all
the file names in your src dir. The 2nd "make" command (make or
gmake) will use it to build LAMMPS. Note that you should
include/exclude any desired optional packages before using the "make
makelist" command.
(2) If you get an error that says something like 'identifier "atoll"
is undefined', then your machine does not support "long long"
integers. Try using the -DLAMMPS_LONGLONG_TO_LONG setting described
above in Step 4.
:line
[{Additional build tips:}] :link(start_2_4)
(1) Building LAMMPS for multiple platforms.
You can make LAMMPS for multiple platforms from the same src
directory. Each target creates its own object sub-directory called
Obj_name where it stores the system-specific *.o files.
(2) Cleaning up.
Typing "make clean-all" or "make clean-foo" will delete *.o object
files created when LAMMPS is built, for either all builds or for a
particular machine.
(3) Changing the size limits in src/lmptype.h
If you are running a very large problem (billions of atoms or more)
and get a run-time error about the system being too big, either on a
per-processor basis or in total size, then you may need to change one
or more settings in src/lmptype.h and re-compile LAMMPS.
As the documentation in that file explains, you have basically
two choices to make:
set the data type size of integer atom IDs to 4 or 8 bytes
set the data type size of integers that store the total system size to 4 or 8 bytes :ul
The default for atom IDs is 4-byte integers since there is a memory
and communication cost for 8-byte integers. Non-molecular problems do
not need atom IDs so this does not restrict their size. Molecular
problems (which use IDs to define molecular topology), are limited to
about 2 billion atoms (2^31) with 4-byte IDs. With 8-byte IDs they
are effectively unlimited in size (2^63).
The default for total system size quantities (like the number of atoms
or timesteps) is 8-byte integers by default which is effectively
unlimited in size (2^63). If your system or MPI implementation does
not support 8-byte integers, an error will be generated, and you will
need to set "bigint" to 4-byte integers. This restricts your total
system size to about 2 billion atoms or timesteps (2^31).
Note that in src/lmptype.h there are also settings for the MPI data
types associated with the integers that store atom IDs and total
system sizes, which need to be set consistent with the associated C
data types.
In all cases, the size of problem that can be run on a per-processor
basis is limited by 4-byte integer storage to about 2 billion atoms
per processor (2^31), which should not normally be a restriction since
such a problem would have a huge per-processor memory footprint due to
neighbor lists and would run very slowly in terms of CPU
secs/timestep.
:line
[{Building for a Mac:}] :link(start_2_5)
OS X is BSD Unix, so it should just work. See the Makefile.mac file.
:line
[{Building for Windows:}] :link(start_2_6)
The LAMMPS download page has an option to download both a serial and
parallel pre-built Windows exeutable. See the "Running
LAMMPS"_#start_5 section for instructions for running these
executables on a Windows box.
If the pre-built executable doesn't have the options you want, then
you can build LAMMPS from its source files on a Windows box. One way
to do this is install and use cygwin to build LAMMPS with a standard
Linus make, just as you would on any Linux box; see
src/MAKE/Makefile.cygwin.
There is a also a src/WINDOWS directory that contains project files
for Microsoft Visual Studio 2005, which should also work with later
versions of VS. That directory contains a README.txt file which
provides instructions for building LAMMPS from source code using
Visual Studio that are hopefully easy to follow for Windows and VS
users.
Four VS project options are provided. The first includes the default
packages (MANYBODY, MOLECULE, and KSPACE). The second includes all
standard packages (except GPU, MEAM, and REAX which are not yet
included because they require NVIDIA or Fortran compilation). The
third includes all standard packages (with the exceptions) and some
user packages. The included user packages are USER-EFF, USER-CG-CMM,
and USER-REAXC. The fourth project includes the USER-AWPMD package.
:line
2.3 Making LAMMPS with optional packages :h4,link(start_3)
This section has the following sub-sections:
"Package basics"_#start_3_1
"Including/excluding packages"_#start_3_2
"Packages that require extra libraries"_#start_3_3
"Additional Makefile settings for extra libraries"_#start_3_4 :ul
:line
[{Package basics:}] :link(start_3_1)
The source code for LAMMPS is structured as a set of core files which
are always included, plus optional packages. Packages are groups of
files that enable a specific set of features. For example, force
fields for molecular systems or granular systems are in packages. You
can see the list of all packages by typing "make package" from within
the src directory of the LAMMPS distribution.
If you use a command in a LAMMPS input script that is specific to a
particular package, you must have built LAMMPS with that package, else
you will get an error that the style is invalid or the command is
unknown. Every command's doc page specfies if it is part of a
package. You can also type
lmp_machine -h :pre
to run your executable with the optional "-h command-line
switch"_#start_6 for "help", which will list the styles and commands
known to your executable.
There are two kinds of packages in LAMMPS, standard and user packages.
More information about the contents of standard and user packages is
-given in "this section"_Section_packages.html of the manual. The
+given in "Section_packages"_Section_packages.html of the manual. The
difference between standard and user packages is as follows:
Standard packages are supported by the LAMMPS developers and are
written in a syntax and style consistent with the rest of LAMMPS.
This means we will answer questions about them, debug and fix them if
necessary, and keep them compatible with future changes to LAMMPS.
User packages have been contributed by users, and always begin with
the user prefix. If they are a single command (single file), they are
typically in the user-misc package. Otherwise, they are a a set of
files grouped together which add a specific functionality to the code.
User packages don't necessarily meet the requirements of the standard
packages. If you have problems using a feature provided in a user
package, you will likely need to contact the contributor directly to
get help. Information on how to submit additions you make to LAMMPS
as a user-contributed package is given in "this
section"_Section_modify.html#mod_14 of the documentation.
:line
[{Including/excluding packages:}] :link(start_3_2)
To use or not use a package you must include or exclude it before
building LAMMPS. From the src directory, this is typically as simple
as:
make yes-colloid
make g++ :pre
or
make no-manybody
make g++ :pre
Some packages have individual files that depend on other packages
being included. LAMMPS checks for this and does the right thing.
I.e. individual files are only included if their dependencies are
already included. Likewise, if a package is excluded, other files
dependent on that package are also excluded.
The reason to exclude packages is if you will never run certain kinds
of simulations. For some packages, this will keep you from having to
build auxiliary libraries (see below), and will also produce a smaller
executable which may run a bit faster.
When you download a LAMMPS tarball, these packages are pre-installed
in the src directory: KSPACE, MANYBODY,MOLECULE. When you download
LAMMPS source files from the SVN or Git repositories, no packages are
pre-installed.
Packages are included or excluded by typing "make yes-name" or "make
no-name", where "name" is the name of the package in lower-case, e.g.
name = kspace for the KSPACE package or name = user-atc for the
USER-ATC package. You can also type "make yes-standard", "make
no-standard", "make yes-user", "make no-user", "make yes-all" or "make
no-all" to include/exclude various sets of packages. Type "make
package" to see the all of the package-related make options.
IMPORTANT NOTE: Inclusion/exclusion of a package works by simply
moving files back and forth between the main src directory and
sub-directories with the package name (e.g. src/KSPACE, src/USER-ATC),
so that the files are seen or not seen when LAMMPS is built. After
you have included or excluded a package, you must re-build LAMMPS.
Additional package-related make options exist to help manage LAMMPS
files that exist in both the src directory and in package
sub-directories. You do not normally need to use these commands
unless you are editing LAMMPS files or have downloaded a patch from
the LAMMPS WWW site.
Typing "make package-update" will overwrite src files with files from
the package sub-directories if the package has been included. It
should be used after a patch is installed, since patches only update
the files in the package sub-directory, but not the src files. Typing
"make package-overwrite" will overwrite files in the package
sub-directories with src files.
Typing "make package-status" will show which packages are currently
included. Of those that are included, it will list files that are
different in the src directory and package sub-directory. Typing
"make package-diff" lists all differences between these files. Again,
type "make package" to see all of the package-related make options.
:line
[{Packages that require extra libraries:}] :link(start_3_3)
A few of the standard and user packages require additional auxiliary
libraries to be compiled first. If you get a LAMMPS build error about
a missing library, this is likely the reason. The source code for
these libraries is included in the LAMMPS distribution under the "lib"
directory. Look at the lib/README file for a list of these or see
-"this section"_Section_packages.html of the doc pages.
+"Section_packages"_Section_packages.html of the doc pages.
Each lib directory has a README file (e.g. lib/reax/README) with
instructions on how to build that library. Typically this is done
in this manner:
make -f Makefile.g++ :pre
in the appropriate directory, e.g. in lib/reax. Some of the libraries
do not build this way. Again, see the libary README file for details.
In any event, you will need to use a Makefile that is a match for your
system. If one of the provided Makefiles is not appropriate for your
system you will need to edit or add one. For example, in the case of
Fortran-based libraries, your system must have a Fortran compiler, the
settings for which will need to be listed in the Makefile.
When you have built one of these libraries, there are 2 things to
check:
(1) The file libname.a should now exist in lib/name.
E.g. lib/reax/libreax.a. This is the library file LAMMPS will link
against. One exception is the lib/cuda library which produces the
file liblammpscuda.a, because there is already a system library
libcuda.a.
(2) The file Makefile.lammps should exist in lib/name. E.g.
lib/cuda/Makefile.lammps. This file may be auto-generated by the
build of the library, or you may need to make a copy of the
appropriate provided file (e.g. lib/meam/Makefile.lammps.gfortran).
Either way you should insure that the settings in this file are
appropriate for your system.
There are typically 3 settings in the Makefile.lammps file (unless
some are blank or not needed): a SYSINC, SYSPATH, and SYSLIB setting,
specific to this package. These are settings the LAMMPS build will
import when compiling the LAMMPS package files (not the library
files), and linking to the auxiliary library. They typically list any
other system libraries needed to support the package and where to find
them. An example is the BLAS and LAPACK libraries needed by the
USER-ATC package. Or the system libraries that support calling
Fortran from C++, as the MEAM and REAX packages do.
Note that if these settings are not correct for your box, the LAMMPS
build will likely fail.
:line
2.4 Building LAMMPS as a library :h4,link(start_4)
LAMMPS itself can be built as a library, which can then be called from
another application or a scripting language. See "this
section"_Section_howto.html#howto_10 for more info on coupling LAMMPS
to other codes. Building LAMMPS as a library is done by typing
make makelib
make -f Makefile.lib foo :pre
where foo is the machine name. Note that inclusion or exclusion of
any desired optional packages should be done before typing "make
makelib". The first "make" command will create a current Makefile.lib
with all the file names in your src dir. The 2nd "make" command will
use it to build LAMMPS as a library. This requires that Makefile.foo
have a library target (lib) and system-specific settings for ARCHIVE
and ARFLAGS. See Makefile.linux for an example. The build will
create the file liblmp_foo.a which another application can link to.
When used from a C++ program, the library allows one or more LAMMPS
objects to be instantiated. All of LAMMPS is wrapped in a LAMMPS_NS
namespace; you can safely use any of its classes and methods from
within your application code, as needed.
When used from a C or Fortran program or a scripting language, the
library has a simple function-style interface, provided in
src/library.cpp and src/library.h.
See the sample codes couple/simple/simple.cpp and simple.c as examples
of C++ and C codes that invoke LAMMPS thru its library interface.
There are other examples as well in the couple directory which are
-discussed in "this section"_Section_howto.html#howto_10 of the manual.
-See "this section"_Section_python.html of the manual for a description
-of the Python wrapper provided with LAMMPS that operates through the
-LAMMPS library interface.
+discussed in "Section_howto 10"_Section_howto.html#howto_10 of the
+manual. See "Section_python"_Section_python.html of the manual for a
+description of the Python wrapper provided with LAMMPS that operates
+through the LAMMPS library interface.
The files src/library.cpp and library.h contain the C-style interface
-to LAMMPS. See "this section"_Section_howto.html#howto_19 of the
+to LAMMPS. See "Section_howto 19"_Section_howto.html#howto_19 of the
manual for a description of the interface and how to extend it for
your needs.
:line
2.5 Running LAMMPS :h4,link(start_5)
By default, LAMMPS runs by reading commands from stdin; e.g. lmp_linux
< in.file. This means you first create an input script (e.g. in.file)
containing the desired commands. "This section"_Section_commands.html
describes how input scripts are structured and what commands they
contain.
You can test LAMMPS on any of the sample inputs provided in the
examples or bench directory. Input scripts are named in.* and sample
outputs are named log.*.name.P where name is a machine and P is the
number of processors it was run on.
Here is how you might run a standard Lennard-Jones benchmark on a
Linux box, using mpirun to launch a parallel job:
cd src
make linux
cp lmp_linux ../bench
cd ../bench
mpirun -np 4 lmp_linux < in.lj :pre
See "this page"_bench for timings for this and the other benchmarks
on various platforms.
:link(bench,http://lammps.sandia.gov/bench.html)
:line
On a Windows box, you can skip making LAMMPS and simply download an
executable, as described above, though the pre-packaged executables
include only certain packages.
To run a LAMMPS executable on a Windows machine, first decide whether
you want to download the non-MPI (serial) or the MPI (parallel)
version of the executable. Download and save the version you have
chosen.
For the non-MPI version, follow these steps:
Get a command prompt by going to Start->Run... ,
then typing "cmd". :ulb,l
Move to the directory where you have saved lmp_win_no-mpi.exe
(e.g. by typing: cd "Documents"). :l
At the command prompt, type "lmp_win_no-mpi -in in.lj", replacing in.lj
with the name of your LAMMPS input script. :l,ule
For the MPI version, which allows you to run LAMMPS under Windows on
multiple processors, follow these steps:
Download and install
"MPICH2"_http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads
for Windows. :ulb,l
You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 package. Put them in
same directory (or path) as the LAMMPS Windows executable. :l
Get a command prompt by going to Start->Run... ,
then typing "cmd". :l
Move to the directory where you have saved lmp_win_mpi.exe
(e.g. by typing: cd "Documents"). :l
Then type something like this: "mpiexec -np 4 -localonly lmp_win_mpi -in in.lj",
replacing in.lj with the name of your LAMMPS input script. :l
Note that you may need to provide smpd with a passphrase --- it doesn't matter what you
type. :l
In this mode, output may not immediately show up on the screen, so
if your input script takes a long time to execute, you may need to be
patient before the output shows up. :l
Alternatively, you can still use this executable to run on a single processor by
typing something like: "lmp_win_mpi -in in.lj". :l,ule
:line
The screen output from LAMMPS is described in the next section. As it
runs, LAMMPS also writes a log.lammps file with the same information.
Note that this sequence of commands copies the LAMMPS executable
(lmp_linux) to the directory with the input files. This may not be
necessary, but some versions of MPI reset the working directory to
where the executable is, rather than leave it as the directory where
you launch mpirun from (if you launch lmp_linux on its own and not
under mpirun). If that happens, LAMMPS will look for additional input
files and write its output files to the executable directory, rather
than your working directory, which is probably not what you want.
If LAMMPS encounters errors in the input script or while running a
simulation it will print an ERROR message and stop or a WARNING
-message and continue. See "this section"_Section_errors.html for a
+message and continue. See "Section_errors"_Section_errors.html for a
discussion of the various kinds of errors LAMMPS can or can't detect,
a list of all ERROR and WARNING messages, and what to do about them.
LAMMPS can run a problem on any number of processors, including a
single processor. In theory you should get identical answers on any
number of processors and on any machine. In practice, numerical
round-off can cause slight differences and eventual divergence of
molecular dynamics phase space trajectories.
LAMMPS can run as large a problem as will fit in the physical memory
of one or more processors. If you run out of memory, you must run on
more processors or setup a smaller problem.
:line
2.6 Command-line options :h4,link(start_6)
At run time, LAMMPS recognizes several optional command-line switches
which may be used in any order. Either the full word or a one-or-two
letter abbreviation can be used:
-c or -cuda
-e or -echo
-i or -in
-h or -help
-l or -log
-p or -partition
-pl or -plog
-ps or -pscreen
+-r or -reorder
-sc or -screen
-sf or -suffix
-v or -var :ul
For example, lmp_ibm might be launched as follows:
mpirun -np 16 lmp_ibm -v f tmp.out -l my.log -sc none < in.alloy
mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy :pre
Here are the details on the options:
-cuda on/off :pre
Explicitly enable or disable CUDA support, as provided by the
USER-CUDA package. If LAMMPS is built with this package, as described
above in "Section 2.3"_#start_3, then by default LAMMPS will run in
CUDA mode. If this switch is set to "off", then it will not, even if
it was built with the USER-CUDA package, which means you can run
standard LAMMPS or with the GPU package for testing or benchmarking
purposes. The only reason to set the switch to "on", is to check if
LAMMPS was built with the USER-CUDA package, since an error will be
generated if it was not.
-echo style :pre
Set the style of command echoing. The style can be {none} or {screen}
or {log} or {both}. Depending on the style, each command read from
the input script will be echoed to the screen and/or logfile. This
can be useful to figure out which line of your script is causing an
input error. The default value is {log}. The echo style can also be
set by using the "echo"_echo.html command in the input script itself.
-in file :pre
Specify a file to use as an input script. This is an optional switch
when running LAMMPS in one-partition mode. If it is not specified,
LAMMPS reads its input script from stdin - e.g. lmp_linux < in.run.
This is a required switch when running LAMMPS in multi-partition mode,
since multiple processors cannot all read from stdin.
-help :pre
Print a list of options compiled into this executable for each LAMMPS
style (atom_style, fix, compute, pair_style, bond_style, etc). This
can help you know if the command you want to use was included via the
appropriate package. LAMMPS will print the info and immediately exit
if this switch is used.
-log file :pre
Specify a log file for LAMMPS to write status information to. In
one-partition mode, if the switch is not used, LAMMPS writes to the
file log.lammps. If this switch is used, LAMMPS writes to the
specified file. In multi-partition mode, if the switch is not used, a
log.lammps file is created with hi-level status information. Each
partition also writes to a log.lammps.N file where N is the partition
ID. If the switch is specified in multi-partition mode, the hi-level
logfile is named "file" and each partition also logs information to a
file.N. For both one-partition and multi-partition mode, if the
specified file is "none", then no log files are created. Using a
"log"_log.html command in the input script will override this setting.
Option -plog will override the name of the partition log files file.N.
-partition 8x2 4 5 ... :pre
Invoke LAMMPS in multi-partition mode. When LAMMPS is run on P
processors and this switch is not used, LAMMPS runs in one partition,
i.e. all P processors run a single simulation. If this switch is
used, the P processors are split into separate partitions and each
partition runs its own simulation. The arguments to the switch
specify the number of processors in each partition. Arguments of the
form MxN mean M partitions, each with N processors. Arguments of the
form N mean a single partition with N processors. The sum of
processors in all partitions must equal P. Thus the command
"-partition 8x2 4 5" has 10 partitions and runs on a total of 25
processors.
-Note that with MPI installed on a machine (e.g. your desktop), you can
-run on more (virtual) processors than you have physical processors.
-This can be useful for running "multi-replica
-simulations"_Section_howto.html#howto_5, on one or a few processors.
+Running with multiple partitions can e useful for running
+"multi-replica simulations"_Section_howto.html#howto_5, where each
+replica runs on on one or a few processors. Note that with MPI
+installed on a machine (e.g. your desktop), you can run on more
+(virtual) processors than you have physical processors.
-The input script specifies what simulation is run on which partition;
-see the "variable"_variable.html and "next"_next.html commands. This
-"howto section"_Section_howto.html#howto_4 gives examples of how to
-use these commands in this way. Simulations running on different
-partitions can also communicate with each other; see the
-"temper"_temper.html command.
+To run multiple independent simulatoins from one input script, using
+multiple partitions, see "Section_howto 4"_Section_howto.html#howto_4
+of the manual. World- and universe-style "variables"_variable.html
+are useful in this context.
-plog file :pre
-Specify the base name for the partition log files,
-so partition N writes log information to file.N. If file is
-none, then no partition log files are created.
-This overrides the
-filename specified in the -log command-line option.
-This option is useful when working with large numbers of partitions,
-allowing the partition log files to be suppressed (-plog none) or
-placed in a sub-directory (-plog replica_files/log.lammps)
-If this option is not used
-the log file for partition N is log.lammps.N or whatever is specified by
-the -log command-line option.
+Specify the base name for the partition log files, so partition N
+writes log information to file.N. If file is none, then no partition
+log files are created. This overrides the filename specified in the
+-log command-line option. This option is useful when working with
+large numbers of partitions, allowing the partition log files to be
+suppressed (-plog none) or placed in a sub-directory (-plog
+replica_files/log.lammps) If this option is not used the log file for
+partition N is log.lammps.N or whatever is specified by the -log
+command-line option.
-pscreen file :pre
-Specify the base name for the
-partition screen file, so partition N writes
-screen information to file.N. If file is
-none, then no partition screen files are created.
-This overrides the
-filename specified in the -screen command-line option.
-This option is useful when working with large numbers of partitions,
-allowing the partition screen files to be suppressed (-pscreen none) or
-placed in a sub-directory (-pscreen replica_files/screen)
-If this option is not used
-the screen file for partition N is screen.N or whatever is specified by
-the -screen command-line option.
+Specify the base name for the partition screen file, so partition N
+writes screen information to file.N. If file is none, then no
+partition screen files are created. This overrides the filename
+specified in the -screen command-line option. This option is useful
+when working with large numbers of partitions, allowing the partition
+screen files to be suppressed (-pscreen none) or placed in a
+sub-directory (-pscreen replica_files/screen). If this option is not
+used the screen file for partition N is screen.N or whatever is
+specified by the -screen command-line option.
+
+-reorder nth N
+-reorder custom filename :pre
+
+Reorder the processors in the MPI communicator used to instantiate
+LAMMPS, in one of several ways. The original MPI communicator ranks
+all P processors from 0 to P-1. The mapping of these ranks to
+physical processors is done by MPI before LAMMPS begins. It may be
+useful in some cases to alter the rank order. E.g. to insure that
+cores within each node are ranked in a desired order. Or when using
+the "run_style verlet/split"_run_style.html command with 2 partitions
+to insure that a specific Kspace processor (in the 2nd partition) is
+matched up with a specific set of processors in the 1st partition.
+See the "Section_accelerate"_Section_accelerate.html doc pages for
+more details.
+
+If the keyword {nth} is used with a setting {N}, then it means every
+Nth processor will be moved to the end of the ranking. This is useful
+when using the "run_style verlet/split"_run_style.html command with 2
+partitions via the -partition command-line switch. The first set of
+processors will be in the first partition, the 2nd set in the 2nd
+partition. The -reorder command-line switch can alter this so that
+the 1st N procs in the 1st partition and one proc in the 2nd partition
+will be ordered consecutively, e.g. as the cores on one physical node.
+This can boost performance. For example, if you use "-reorder nth 4"
+and "-partition 9 3" and you are running on 12 processors, the
+processors will be reordered from
+
+0 1 2 3 4 5 6 7 8 9 10 11 :pre
+
+to
+
+0 1 2 4 5 6 8 9 10 3 7 11 :pre
+
+so that the processors in each partition will be
+
+0 1 2 4 5 6 8 9 10
+3 7 11 :pre
+
+See the "processors" command for how to insure processors from each
+partition could then be grouped optimally for quad-core nodes.
+
+If the keyword is {custom", then a file that specifies a permutation
+of the processor ranks is also specified. The format of the reorder
+file is as follows. Any number of initial blank or comment lines
+(starting with a "#" character) can be present. These should be
+followed by P lines of the form:
+
+I J :pre
+
+where P is the number of processors LAMMPS was launched with. Note
+that if running in multi-partition mode (see the -partition switch
+above) P is the total number of processors in all partitions. The I
+and J values describe a permutation of the P processors. Every I and
+J should be values from 0 to P-1 inclusive. In the set of P I values,
+every proc ID should appear exactly once. Ditto for the set of P J
+values. A single I,J pairing means that the physical processor with
+rank I in the original MPI communicator will have rank J in the
+reordered communicator.
+
+Note that rank ordering can also be specified by many MPI
+implementations, either by environment variables that specify how to
+order physical processors, or by config files that specify what
+physical processors to assign to each MPI rank. The -reorder switch
+simply gives you a portable way to do this without relying on MPI
+itself. See the "processors out"_processors command for how to output
+info on the final assignment of physical processors to the LAMMPS
+simulation domain.
-screen file :pre
Specify a file for LAMMPS to write its screen information to. In
one-partition mode, if the switch is not used, LAMMPS writes to the
screen. If this switch is used, LAMMPS writes to the specified file
instead and you will see no screen output. In multi-partition mode,
if the switch is not used, hi-level status information is written to
the screen. Each partition also writes to a screen.N file where N is
the partition ID. If the switch is specified in multi-partition mode,
the hi-level screen dump is named "file" and each partition also
writes screen information to a file.N. For both one-partition and
multi-partition mode, if the specified file is "none", then no screen
-output is performed. Option -pscreen will override the name of the
+output is performed. Option -pscreen will override the name of the
partition screen files file.N.
-suffix style :pre
Use variants of various styles if they exist. The specified style can
be {opt}, {omp}, {gpu}, or {cuda}. These refer to optional packages that
LAMMPS can be built with, as described above in "Section
2.3"_#start_3. The "opt" style corrsponds to the OPT package, the
"omp" style to the USER-OMP package, the "gpu" style to the GPU
package, and the "cuda" style to the USER-CUDA package.
As an example, all of the packages provide a "pair_style
lj/cut"_pair_lj.html variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
-suffix switch is used, you do not need to modify your input script.
-The specified suffix (opt,omp,gpu,cuda) is automatically appended whenever
-your input script command creates a new "atom"_atom_style.html,
-"pair"_pair_style.html, "fix"_fix.html, "compute"_compute.html, or
-"run"_run_style.html style. atom, pair, fix, compute, or integrate
-style. If the variant version does not exist, the standard version is
-created.
+The specified suffix (opt,omp,gpu,cuda) is automatically appended
+whenever your input script command creates a new
+"atom"_atom_style.html, "pair"_pair_style.html, "fix"_fix.html,
+"compute"_compute.html, or "run"_run_style.html style. If the variant
+version does not exist, the standard version is created.
+
+For the GPU package, using this command-line switch also invokes the
+default GPU settings, as if the command "package gpu force/neigh 0 0
+1" were used at the top of your input script. These settings can be
+changed by using the "package gpu"_pacakge.html command in your script
+if desired.
+
+For the OMP package, using this command-line switch also invokes the
+default OMP settings, as if the command "package omp *" were used at
+the top of your input script. These settings can be changed by using
+the "package omp"_pacakge.html command in your script if desired.
The "suffix"_suffix.html command can also set a suffix and it can also
turn off/on any suffix setting made via the command line.
-var name value1 value2 ... :pre
Specify a variable that will be defined for substitution purposes when
the input script is read. "Name" is the variable name which can be a
single character (referenced as $x in the input script) or a full
string (referenced as $\{abc\}). An "index-style
variable"_variable.html will be created and populated with the
subsequent values, e.g. a set of filenames. Using this command-line
option is equivalent to putting the line "variable name index value1
value2 ..." at the beginning of the input script. Defining an index
variable as a command-line argument overrides any setting for the same
index variable in the input script, since index variables cannot be
re-defined. See the "variable"_variable.html command for more info on
defining index and other kinds of variables and "this
section"_Section_commands.html#cmd_2 for more info on using variables
in input scripts.
NOTE: Currently, the command-line parser looks for arguments that
start with "-" to indicate new switches. Thus you cannot specify
multiple variable values if any of they start with a "-", e.g. a
negative numeric value. It is OK if the first value1 starts with a
"-", since it is automatically skipped.
:line
2.7 LAMMPS screen output :h4,link(start_7)
As LAMMPS reads an input script, it prints information to both the
screen and a log file about significant actions it takes to setup a
simulation. When the simulation is ready to begin, LAMMPS performs
various initializations and prints the amount of memory (in MBytes per
processor) that the simulation requires. It also prints details of
the initial thermodynamic state of the system. During the run itself,
thermodynamic information is printed periodically, every few
timesteps. When the run concludes, LAMMPS prints the final
thermodynamic state and a total run time for the simulation. It then
appends statistics about the CPU time and storage requirements for the
simulation. An example set of statistics is shown here:
Loop time of 49.002 on 2 procs for 2004 atoms :pre
Pair time (%) = 35.0495 (71.5267)
Bond time (%) = 0.092046 (0.187841)
Kspce time (%) = 6.42073 (13.103)
Neigh time (%) = 2.73485 (5.5811)
Comm time (%) = 1.50291 (3.06703)
Outpt time (%) = 0.013799 (0.0281601)
Other time (%) = 2.13669 (4.36041) :pre
Nlocal: 1002 ave, 1015 max, 989 min
Histogram: 1 0 0 0 0 0 0 0 0 1
Nghost: 8720 ave, 8724 max, 8716 min
Histogram: 1 0 0 0 0 0 0 0 0 1
Neighs: 354141 ave, 361422 max, 346860 min
Histogram: 1 0 0 0 0 0 0 0 0 1 :pre
Total # of neighbors = 708282
Ave neighs/atom = 353.434
Ave special neighs/atom = 2.34032
Number of reneighborings = 42
Dangerous reneighborings = 2 :pre
The first section gives the breakdown of the CPU run time (in seconds)
into major categories. The second section lists the number of owned
atoms (Nlocal), ghost atoms (Nghost), and pair-wise neighbors stored
per processor. The max and min values give the spread of these values
across processors with a 10-bin histogram showing the distribution.
The total number of histogram counts is equal to the number of
processors.
The last section gives aggregate statistics for pair-wise neighbors
and special neighbors that LAMMPS keeps track of (see the
"special_bonds"_special_bonds.html command). The number of times
neighbor lists were rebuilt during the run is given as well as the
number of potentially "dangerous" rebuilds. If atom movement
triggered neighbor list rebuilding (see the
"neigh_modify"_neigh_modify.html command), then dangerous
reneighborings are those that were triggered on the first timestep
atom movement was checked for. If this count is non-zero you may wish
to reduce the delay factor to insure no force interactions are missed
by atoms moving beyond the neighbor skin distance before a rebuild
takes place.
If an energy minimization was performed via the
"minimize"_minimize.html command, additional information is printed,
e.g.
Minimization stats:
E initial, next-to-last, final = -0.895962 -2.94193 -2.94342
Gradient 2-norm init/final= 1920.78 20.9992
Gradient inf-norm init/final= 304.283 9.61216
Iterations = 36
Force evaluations = 177 :pre
The first line lists the initial and final energy, as well as the
energy on the next-to-last iteration. The next 2 lines give a measure
of the gradient of the energy (force on all atoms). The 2-norm is the
"length" of this force vector; the inf-norm is the largest component.
The last 2 lines are statistics on how many iterations and
force-evaluations the minimizer required. Multiple force evaluations
are typically done at each iteration to perform a 1d line minimization
in the search direction.
If a "kspace_style"_kspace_style.html long-range Coulombics solve was
performed during the run (PPPM, Ewald), then additional information is
printed, e.g.
FFT time (% of Kspce) = 0.200313 (8.34477)
FFT Gflps 3d 1d-only = 2.31074 9.19989 :pre
The first line gives the time spent doing 3d FFTs (4 per timestep) and
the fraction it represents of the total KSpace time (listed above).
Each 3d FFT requires computation (3 sets of 1d FFTs) and communication
(transposes). The total flops performed is 5Nlog_2(N), where N is the
number of points in the 3d grid. The FFTs are timed with and without
the communication and a Gflop rate is computed. The 3d rate is with
communication; the 1d rate is without (just the 1d FFTs). Thus you
can estimate what fraction of your FFT time was spent in
communication, roughly 75% in the example above.
:line
2.8 Tips for users of previous LAMMPS versions :h4,link(start_8)
The current C++ began with a complete rewrite of LAMMPS 2001, which
was written in F90. Features of earlier versions of LAMMPS are listed
-in "this section"_Section_history.html. The F90 and F77 versions
+in "Section_history"_Section_history.html. The F90 and F77 versions
(2001 and 99) are also freely distributed as open-source codes; check
the "LAMMPS WWW Site"_lws for distribution information if you prefer
those versions. The 99 and 2001 versions are no longer under active
development; they do not have all the features of C++ LAMMPS.
If you are a previous user of LAMMPS 2001, these are the most
significant changes you will notice in C++ LAMMPS:
(1) The names and arguments of many input script commands have
changed. All commands are now a single word (e.g. read_data instead
of read data).
(2) All the functionality of LAMMPS 2001 is included in C++ LAMMPS,
but you may need to specify the relevant commands in different ways.
(3) The format of the data file can be streamlined for some problems.
See the "read_data"_read_data.html command for details. The data file
section "Nonbond Coeff" has been renamed to "Pair Coeff" in C++ LAMMPS.
(4) Binary restart files written by LAMMPS 2001 cannot be read by C++
LAMMPS with a "read_restart"_read_restart.html command. This is
because they were output by F90 which writes in a different binary
format than C or C++ writes or reads. Use the {restart2data} tool
provided with LAMMPS 2001 to convert the 2001 restart file to a text
data file. Then edit the data file as necessary before using the C++
LAMMPS "read_data"_read_data.html command to read it in.
(5) There are numerous small numerical changes in C++ LAMMPS that mean
you will not get identical answers when comparing to a 2001 run.
However, your initial thermodynamic energy and MD trajectory should be
close if you have setup the problem for both codes the same.
diff --git a/doc/angle_charmm.html b/doc/angle_charmm.html
index 94c0e3bcf..9cc950f56 100644
--- a/doc/angle_charmm.html
+++ b/doc/angle_charmm.html
@@ -1,68 +1,94 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style charmm command
</H3>
+<H3>angle_style charmm/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style charmm
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style charmm
angle_coeff 1 300.0 107.0 50.0 3.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>charmm</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_charmm.jpg">
</CENTER>
<P>with an additional Urey_Bradley term based on the distance <I>r</I> between
the 1st and 3rd atoms in the angle. K, theta0, Kub, and Rub are
coefficients defined for each angle type.
</P>
<P>See <A HREF = "#MacKerell">(MacKerell)</A> for a description of the CHARMM force
field.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/radian^2)
<LI>theta0 (degrees)
<LI>K_ub (energy/distance^2)
<LI>r_ub (distance)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "MacKerell"></A>
<P><B>(MacKerell)</B> MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
</P>
</HTML>
diff --git a/doc/angle_charmm.txt b/doc/angle_charmm.txt
index 13cdc03f8..78500a538 100644
--- a/doc/angle_charmm.txt
+++ b/doc/angle_charmm.txt
@@ -1,62 +1,87 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
angle_style charmm command :h3
+angle_style charmm/omp command :h3
[Syntax:]
angle_style charmm :pre
[Examples:]
angle_style charmm
angle_coeff 1 300.0 107.0 50.0 3.0 :pre
[Description:]
The {charmm} angle style uses the potential
:c,image(Eqs/angle_charmm.jpg)
with an additional Urey_Bradley term based on the distance {r} between
the 1st and 3rd atoms in the angle. K, theta0, Kub, and Rub are
coefficients defined for each angle type.
See "(MacKerell)"_#MacKerell for a description of the CHARMM force
field.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/radian^2)
theta0 (degrees)
K_ub (energy/distance^2)
r_ub (distance) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
:line
:link(MacKerell)
[(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
diff --git a/doc/angle_class2.html b/doc/angle_class2.html
index c2aea849a..ddc19dd1b 100644
--- a/doc/angle_class2.html
+++ b/doc/angle_class2.html
@@ -1,99 +1,125 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style class2 command
</H3>
+<H3>angle_style class2/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style class2
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style class2
angle_coeff * 75.0
angle_coeff 1 bb 10.5872 1.0119 1.5228
angle_coeff * ba 3.6551 24.895 1.0119 1.5228
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>class2</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_class2.jpg">
</CENTER>
<P>where Ea is the angle term, Ebb is a bond-bond term, and Eba is a
bond-angle term. Theta0 is the equilibrium angle and r1 and r2 are
the equilibrium bond lengths.
</P>
<P>See <A HREF = "#Sun">(Sun)</A> for a description of the COMPASS class2 force field.
</P>
<P>Coefficients for the Ea, Ebb, and Eba formulas must be defined for
each angle type via the <A HREF = "bond_coeff.html">bond_coeff</A> command as in the
example above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands.
</P>
<P>These are the 4 coefficients for the Ea formula:
</P>
<UL><LI>theta0 (degrees)
<LI>K2 (energy/radian^2)
<LI>K3 (energy/radian^3)
<LI>K4 (energy/radian^4)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of the various K are in per-radian.
</P>
<P>For the Ebb formula, each line in a <A HREF = "bond_coeff.html">bond_coeff</A>
command in the input script lists 4 coefficients, the first of which
is "bb" to indicate they are BondBond coefficients. In a data file,
these coefficients should be listed under a "BondBond Coeffs" heading
and you must leave out the "bb", i.e. only list 3 coefficients after
the angle type.
</P>
<UL><LI>bb
<LI>M (energy/distance^2)
<LI>r1 (distance)
<LI>r2 (distance)
</UL>
<P>For the Eba formula, each line in a <A HREF = "bond_coeff.html">bond_coeff</A>
command in the input script lists 5 coefficients, the first of which
is "ba" to indicate they are BondAngle coefficients. In a data file,
these coefficients should be listed under a "BondAngle Coeffs" heading
and you must leave out the "ba", i.e. only list 4 coefficients after
the angle type.
</P>
<UL><LI>ba
<LI>N1 (energy/distance^2)
<LI>N2 (energy/distance^2)
<LI>r1 (distance)
<LI>r2 (distance)
</UL>
<P>The theta0 value in the Eba formula is not specified, since it is the
same value from the Ea formula.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the CLASS2
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Sun"></A>
<P><B>(Sun)</B> Sun, J Phys Chem B 102, 7338-7364 (1998).
</P>
</HTML>
diff --git a/doc/angle_class2.txt b/doc/angle_class2.txt
index 93e2ea25e..36a16e836 100644
--- a/doc/angle_class2.txt
+++ b/doc/angle_class2.txt
@@ -1,93 +1,118 @@
"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
angle_style class2 command :h3
+angle_style class2/omp command :h3
[Syntax:]
angle_style class2 :pre
[Examples:]
angle_style class2
angle_coeff * 75.0
angle_coeff 1 bb 10.5872 1.0119 1.5228
angle_coeff * ba 3.6551 24.895 1.0119 1.5228 :pre
[Description:]
The {class2} angle style uses the potential
:c,image(Eqs/angle_class2.jpg)
where Ea is the angle term, Ebb is a bond-bond term, and Eba is a
bond-angle term. Theta0 is the equilibrium angle and r1 and r2 are
the equilibrium bond lengths.
See "(Sun)"_#Sun for a description of the COMPASS class2 force field.
Coefficients for the Ea, Ebb, and Eba formulas must be defined for
each angle type via the "bond_coeff"_bond_coeff.html command as in the
example above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands.
These are the 4 coefficients for the Ea formula:
theta0 (degrees)
K2 (energy/radian^2)
K3 (energy/radian^3)
K4 (energy/radian^4) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of the various K are in per-radian.
For the Ebb formula, each line in a "bond_coeff"_bond_coeff.html
command in the input script lists 4 coefficients, the first of which
is "bb" to indicate they are BondBond coefficients. In a data file,
these coefficients should be listed under a "BondBond Coeffs" heading
and you must leave out the "bb", i.e. only list 3 coefficients after
the angle type.
bb
M (energy/distance^2)
r1 (distance)
r2 (distance) :ul
For the Eba formula, each line in a "bond_coeff"_bond_coeff.html
command in the input script lists 5 coefficients, the first of which
is "ba" to indicate they are BondAngle coefficients. In a data file,
these coefficients should be listed under a "BondAngle Coeffs" heading
and you must leave out the "ba", i.e. only list 4 coefficients after
the angle type.
ba
N1 (energy/distance^2)
N2 (energy/distance^2)
r1 (distance)
r2 (distance) :ul
The theta0 value in the Eba formula is not specified, since it is the
same value from the Ea formula.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the CLASS2
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
:line
:link(Sun)
[(Sun)] Sun, J Phys Chem B 102, 7338-7364 (1998).
diff --git a/doc/angle_cosine.html b/doc/angle_cosine.html
index 3321405fb..1c376614a 100644
--- a/doc/angle_cosine.html
+++ b/doc/angle_cosine.html
@@ -1,50 +1,76 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine command
</H3>
+<H3>angle_style cosine/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine
angle_coeff * 75.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine.jpg">
</CENTER>
<P>where K is defined for each angle type.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cosine.txt b/doc/angle_cosine.txt
index a2fbabf98..9c7b72297 100644
--- a/doc/angle_cosine.txt
+++ b/doc/angle_cosine.txt
@@ -1,45 +1,70 @@
"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
angle_style cosine command :h3
+angle_style cosine/omp command :h3
[Syntax:]
angle_style cosine :pre
[Examples:]
angle_style cosine
angle_coeff * 75.0 :pre
[Description:]
The {cosine} angle style uses the potential
:c,image(Eqs/angle_cosine.jpg)
where K is defined for each angle type.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
diff --git a/doc/angle_cosine_delta.html b/doc/angle_cosine_delta.html
index 9bfd85ea0..dd8c9965c 100644
--- a/doc/angle_cosine_delta.html
+++ b/doc/angle_cosine_delta.html
@@ -1,56 +1,82 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine/delta command
</H3>
+<H3>angle_style cosine/delta/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine/delta
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine/delta
angle_coeff 2*4 75.0 100.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/delta</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine_delta.jpg">
</CENTER>
<P>where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy)
<LI>theta0 (degrees)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>, <A HREF = "angle_cosine_squared.html">angle_style
cosine/squared</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cosine_delta.txt b/doc/angle_cosine_delta.txt
index 57de081f8..92b809b67 100644
--- a/doc/angle_cosine_delta.txt
+++ b/doc/angle_cosine_delta.txt
@@ -1,51 +1,76 @@
"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
angle_style cosine/delta command :h3
+angle_style cosine/delta/omp command :h3
[Syntax:]
angle_style cosine/delta :pre
[Examples:]
angle_style cosine/delta
angle_coeff 2*4 75.0 100.0 :pre
[Description:]
The {cosine/delta} angle style uses the potential
:c,image(Eqs/angle_cosine_delta.jpg)
where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy)
theta0 (degrees) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html, "angle_style
cosine/squared"_angle_cosine_squared.html
[Default:] none
diff --git a/doc/angle_cosine_periodic.html b/doc/angle_cosine_periodic.html
index 5e409b025..55469c2c6 100644
--- a/doc/angle_cosine_periodic.html
+++ b/doc/angle_cosine_periodic.html
@@ -1,70 +1,96 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine/periodic command
</H3>
+<H3>angle_style cosine/periodic/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine/periodic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine/periodic
angle_coeff * 75.0 1 6
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/periodic</I> angle style uses the following potential, which
is commonly used in the <A HREF = "Section_howto.html#howto_4">DREIDING</A> force
field, particularly for organometallic systems where <I>n</I> = 4 might be
used for an octahedral complex and <I>n</I> = 3 might be used for a
trigonal center:
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine_periodic.jpg">
</CENTER>
<P>where C, B and n are coefficients defined for each angle type.
</P>
<P>See <A HREF = "#Mayo">(Mayo)</A> for a description of the DREIDING force field
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>C (energy)
<LI>B = 1 or -1
<LI>n = 1, 2, 3, 4, 5 or 6 for periodicity
</UL>
<P>Note that the prefactor C is specified and not the overall force
constant K = C / n^2. When B = 1, it leads to a minimum for the
linear geometry. When B = -1, it leads to a maximum for the linear
geometry.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Mayo"></A>
<P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
</P>
</HTML>
diff --git a/doc/angle_cosine_periodic.txt b/doc/angle_cosine_periodic.txt
index a5fb88fdb..c5ea3563b 100644
--- a/doc/angle_cosine_periodic.txt
+++ b/doc/angle_cosine_periodic.txt
@@ -1,64 +1,89 @@
"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
angle_style cosine/periodic command :h3
+angle_style cosine/periodic/omp command :h3
[Syntax:]
angle_style cosine/periodic :pre
[Examples:]
angle_style cosine/periodic
angle_coeff * 75.0 1 6 :pre
[Description:]
The {cosine/periodic} angle style uses the following potential, which
is commonly used in the "DREIDING"_Section_howto.html#howto_4 force
field, particularly for organometallic systems where {n} = 4 might be
used for an octahedral complex and {n} = 3 might be used for a
trigonal center:
:c,image(Eqs/angle_cosine_periodic.jpg)
where C, B and n are coefficients defined for each angle type.
See "(Mayo)"_#Mayo for a description of the DREIDING force field
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
C (energy)
B = 1 or -1
n = 1, 2, 3, 4, 5 or 6 for periodicity :ul
Note that the prefactor C is specified and not the overall force
constant K = C / n^2. When B = 1, it leads to a minimum for the
linear geometry. When B = -1, it leads to a maximum for the linear
geometry.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
:line
:link(Mayo)
[(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
diff --git a/doc/angle_cosine_shift.html b/doc/angle_cosine_shift.html
index 8f97069f7..76b1cea55 100644
--- a/doc/angle_cosine_shift.html
+++ b/doc/angle_cosine_shift.html
@@ -1,54 +1,80 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine/shift command
</H3>
+<H3>angle_style cosine/shift/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine/shift
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine/shift
angle_coeff * 10.0 45.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/shift</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine_shift.jpg">
</CENTER>
<P>where theta0 is the equilibrium angle. The potential is bounded
between -Umin and zero. In the neighborhood of the minimum E=- Umin +
Umin/4(theta-theta0)^2 hence the spring constant is umin/2.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>umin (energy)
<LI>theta (angle)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>,
<A HREF = "angle_cosineshiftexp.html">angle_cosineshiftexp</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cosine_shift.txt b/doc/angle_cosine_shift.txt
index e7c641718..cd2b7fe10 100644
--- a/doc/angle_cosine_shift.txt
+++ b/doc/angle_cosine_shift.txt
@@ -1,49 +1,74 @@
"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
angle_style cosine/shift command :h3
+angle_style cosine/shift/omp command :h3
[Syntax:]
angle_style cosine/shift :pre
[Examples:]
angle_style cosine/shift
angle_coeff * 10.0 45.0 :pre
[Description:]
The {cosine/shift} angle style uses the potential
:c,image(Eqs/angle_cosine_shift.jpg)
where theta0 is the equilibrium angle. The potential is bounded
between -Umin and zero. In the neighborhood of the minimum E=- Umin +
Umin/4(theta-theta0)^2 hence the spring constant is umin/2.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
umin (energy)
theta (angle) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html,
"angle_cosineshiftexp"_angle_cosineshiftexp.html
[Default:] none
diff --git a/doc/angle_cosine_shift_exp.html b/doc/angle_cosine_shift_exp.html
index ceccb16b8..3a30784ee 100644
--- a/doc/angle_cosine_shift_exp.html
+++ b/doc/angle_cosine_shift_exp.html
@@ -1,67 +1,93 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine/shift/exp command
</H3>
+<H3>angle_style cosine/shift/exp/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine/shift/exp
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine/shift/exp
angle_coeff * 10.0 45.0 2.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/shift/exp</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine_shift_exp.jpg">
</CENTER>
<P>where Umin, theta, and a are defined for each angle type.
</P>
<P>The potential is bounded between [-Umin:0] and the minimum is
located at the angle theta0. The a parameter can be both positive or
negative and is used to control the spring constant at the
equilibrium.
</P>
<P>The spring constant is given by k = A exp(A) Umin / [2 (Exp(a)-1)].
For a > 3, k/Umin = a/2 to better than 5% relative error. For negative
values of the a parameter, the spring constant is essentially zero,
and anharmonic terms takes over. The potential is furthermore well
behaved in the limit a -> 0, where it has been implemented to linear
order in a for a < 0.001. In this limit the potential reduces to the
cosineshifted potential.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>umin (energy)
<LI>theta (angle)
<LI>A (real number)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>,
<A HREF = "angle_cosineshift.html">angle_cosineshift</A>,
<A HREF = "dihedral_cosineshift.html">dihedral_cosineshift</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cosine_shift_exp.txt b/doc/angle_cosine_shift_exp.txt
index 12612a533..f9b2efdf9 100644
--- a/doc/angle_cosine_shift_exp.txt
+++ b/doc/angle_cosine_shift_exp.txt
@@ -1,62 +1,87 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
angle_style cosine/shift/exp command :h3
+angle_style cosine/shift/exp/omp command :h3
[Syntax:]
angle_style cosine/shift/exp :pre
[Examples:]
angle_style cosine/shift/exp
angle_coeff * 10.0 45.0 2.0 :pre
[Description:]
The {cosine/shift/exp} angle style uses the potential
:c,image(Eqs/angle_cosine_shift_exp.jpg)
where Umin, theta, and a are defined for each angle type.
The potential is bounded between \[-Umin:0\] and the minimum is
located at the angle theta0. The a parameter can be both positive or
negative and is used to control the spring constant at the
equilibrium.
The spring constant is given by k = A exp(A) Umin / \[2 (Exp(a)-1)\].
For a > 3, k/Umin = a/2 to better than 5% relative error. For negative
values of the a parameter, the spring constant is essentially zero,
and anharmonic terms takes over. The potential is furthermore well
behaved in the limit a -> 0, where it has been implemented to linear
order in a for a < 0.001. In this limit the potential reduces to the
cosineshifted potential.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
umin (energy)
theta (angle)
A (real number) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html,
"angle_cosineshift"_angle_cosineshift.html,
"dihedral_cosineshift"_dihedral_cosineshift.html
[Default:] none
diff --git a/doc/angle_cosine_squared.html b/doc/angle_cosine_squared.html
index 2b888d40e..08af46901 100644
--- a/doc/angle_cosine_squared.html
+++ b/doc/angle_cosine_squared.html
@@ -1,55 +1,81 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style cosine/squared command
</H3>
+<H3>angle_style cosine/squared/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style cosine/squared
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style cosine/squared
angle_coeff 2*4 75.0 100.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/squared</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_cosine_squared.jpg">
</CENTER>
<P>where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy)
<LI>theta0 (degrees)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cosine_squared.txt b/doc/angle_cosine_squared.txt
index 383c0b302..ec7dbd217 100644
--- a/doc/angle_cosine_squared.txt
+++ b/doc/angle_cosine_squared.txt
@@ -1,50 +1,75 @@
"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
angle_style cosine/squared command :h3
+angle_style cosine/squared/omp command :h3
[Syntax:]
angle_style cosine/squared :pre
[Examples:]
angle_style cosine/squared
angle_coeff 2*4 75.0 100.0 :pre
[Description:]
The {cosine/squared} angle style uses the potential
:c,image(Eqs/angle_cosine_squared.jpg)
where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy)
theta0 (degrees) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
diff --git a/doc/angle_harmonic.html b/doc/angle_harmonic.html
index 2094fb2cc..4242327db 100644
--- a/doc/angle_harmonic.html
+++ b/doc/angle_harmonic.html
@@ -1,55 +1,81 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style harmonic command
</H3>
+<H3>angle_style harmonic/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style harmonic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>angle_style harmonic
angle_coeff 1 300.0 107.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic</I> angle style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/angle_harmonic.jpg">
</CENTER>
<P>where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/radian^2)
<LI>theta0 (degrees)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B> none
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_harmonic.txt b/doc/angle_harmonic.txt
index 92c318dc2..b0695631e 100644
--- a/doc/angle_harmonic.txt
+++ b/doc/angle_harmonic.txt
@@ -1,50 +1,75 @@
"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
angle_style harmonic command :h3
+angle_style harmonic/omp command :h3
[Syntax:]
angle_style harmonic :pre
[Examples:]
angle_style harmonic
angle_coeff 1 300.0 107.0 :pre
[Description:]
The {harmonic} angle style uses the potential
:c,image(Eqs/angle_harmonic.jpg)
where theta0 is the equilibrium value of the angle, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/radian^2)
theta0 (degrees) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:] none
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
diff --git a/doc/angle_cmm.html b/doc/angle_sdk.html
similarity index 63%
rename from doc/angle_cmm.html
rename to doc/angle_sdk.html
index bfd2507f6..fa1b5f37d 100644
--- a/doc/angle_cmm.html
+++ b/doc/angle_sdk.html
@@ -1,65 +1,64 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
-<H3>angle_style cg/cmm command
+<H3>angle_style sdk command
</H3>
<P><B>Syntax:</B>
</P>
-<PRE>angle_style cg/cmm
+<PRE>angle_style sdk
+</PRE>
+<PRE>angle_style sdk/omp
</PRE>
<P><B>Examples:</B>
</P>
-<PRE>angle_style cg/cmm
-angle_coeff 1 300.0 107.0 lj9_6 0.4491 3.7130
+<PRE>angle_style sdk
+angle_coeff 1 300.0 107.0
</PRE>
<P><B>Description:</B>
</P>
-<P>The <I>cg/cmm</I> angle style is a combination of the harmonic angle potential,
+<P>The <I>sdk</I> angle style is a combination of the harmonic angle potential,
</P>
<CENTER><IMG SRC = "Eqs/angle_harmonic.jpg">
</CENTER>
<P>where theta0 is the equilibrium value of the angle and K a prefactor,
-with the <I>repulsive</I> part of the non-bonded <I>cg/cmm</I> pair style
+with the <I>repulsive</I> part of the non-bonded <I>lj/sdk</I> pair style
between the atoms 1 and 3. This angle potential is intended for
coarse grained MD simulations with the CMM parametrization using the
-<A HREF = "pair_cmm.html">pair_style cg/cmm</A>. Relative to the pair_style
-<I>cg/cmm</I>, however, the energy is shifted by <I>epsilon</I>, to avoid sudden
+<A HREF = "pair_sdk.html">pair_style lj/sdk</A>. Relative to the pair_style
+<I>lj/sdk</I>, however, the energy is shifted by <I>epsilon</I>, to avoid sudden
jumps. Note that the usual 1/2 factor is included in K.
</P>
<P>The following coefficients must be defined for each angle type via the
-<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above. As
-with other CMM coarse grained parameters, they cannot be set in the
-data file, but can be restored from restarts via the
-<A HREF = "read_restart.html">read_restart</A> command:
+<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above:
</P>
<UL><LI>K (energy/radian^2)
-<LI>theta0 (degrees)
-<LI>cg_type (string, one of lj9_6, lj12_4, lj12_6)
-<LI>epsilon (energy units)
-<LI>sigma (distance units)
+<LI>theta0 (degrees)
</UL>
<P>Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
+The also required <I>lj/sdk</I> parameters will be extracted automatically
+from the pair_style.
</P>
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
USER-CG-CMM package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>, <A HREF = "angle_harmonic.html">angle_style
-harmonic</A>, <A HREF = "pair_cmm.html">pair_style cg/cmm</A>
+harmonic</A>, <A HREF = "pair_sdk.html">pair_style lj/sdk</A>,
+<A HREF = "pair_sdk.html">pair_style lj/sdk/coul/long</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_cmm.txt b/doc/angle_sdk.txt
similarity index 55%
rename from doc/angle_cmm.txt
rename to doc/angle_sdk.txt
index bbc5033ad..3c70d4223 100644
--- a/doc/angle_cmm.txt
+++ b/doc/angle_sdk.txt
@@ -1,60 +1,58 @@
"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
-angle_style cg/cmm command :h3
+angle_style sdk command :h3
[Syntax:]
-angle_style cg/cmm :pre
+angle_style sdk :pre
+angle_style sdk/omp :pre
[Examples:]
-angle_style cg/cmm
-angle_coeff 1 300.0 107.0 lj9_6 0.4491 3.7130 :pre
+angle_style sdk
+angle_coeff 1 300.0 107.0 :pre
[Description:]
-The {cg/cmm} angle style is a combination of the harmonic angle potential,
+The {sdk} angle style is a combination of the harmonic angle potential,
:c,image(Eqs/angle_harmonic.jpg)
where theta0 is the equilibrium value of the angle and K a prefactor,
-with the {repulsive} part of the non-bonded {cg/cmm} pair style
+with the {repulsive} part of the non-bonded {lj/sdk} pair style
between the atoms 1 and 3. This angle potential is intended for
coarse grained MD simulations with the CMM parametrization using the
-"pair_style cg/cmm"_pair_cmm.html. Relative to the pair_style
-{cg/cmm}, however, the energy is shifted by {epsilon}, to avoid sudden
+"pair_style lj/sdk"_pair_sdk.html. Relative to the pair_style
+{lj/sdk}, however, the energy is shifted by {epsilon}, to avoid sudden
jumps. Note that the usual 1/2 factor is included in K.
The following coefficients must be defined for each angle type via the
-"angle_coeff"_angle_coeff.html command as in the example above. As
-with other CMM coarse grained parameters, they cannot be set in the
-data file, but can be restored from restarts via the
-"read_restart"_read_restart.html command:
+"angle_coeff"_angle_coeff.html command as in the example above:
K (energy/radian^2)
-theta0 (degrees)
-cg_type (string, one of lj9_6, lj12_4, lj12_6)
-epsilon (energy units)
-sigma (distance units) :ul
+theta0 (degrees) :ul
Theta0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
+The also required {lj/sdk} parameters will be extracted automatically
+from the pair_style.
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
USER-CG-CMM package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html, "angle_style
-harmonic"_angle_harmonic.html, "pair_style cg/cmm"_pair_cmm.html
+harmonic"_angle_harmonic.html, "pair_style lj/sdk"_pair_sdk.html,
+"pair_style lj/sdk/coul/long"_pair_sdk.html
[Default:] none
diff --git a/doc/angle_table.html b/doc/angle_table.html
index 2b1bfb165..992eeeb26 100644
--- a/doc/angle_table.html
+++ b/doc/angle_table.html
@@ -1,136 +1,162 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>angle_style table command
</H3>
+<H3>angle_style table/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>angle_style table style N
</PRE>
<UL><LI>style = <I>linear</I> or <I>spline</I> = method of interpolation
<LI>N = use N values in table
</UL>
<P><B>Examples:</B>
</P>
<PRE>angle_style table linear 1000
angle_coeff 3 file.table ENTRY1
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>table</I> creates interpolation tables of length <I>N</I> from angle
potential and derivative values listed in a file(s) as a function of
angle The files are read by the <A HREF = "angle_coeff.html">angle_coeff</A>
command.
</P>
<P>The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and derivative values at each of
<I>N</I> angles. During a simulation, these tables are used to interpolate
energy and force values on individual atoms as needed. The
interpolation is done in one of 2 styles: <I>linear</I> or <I>spline</I>.
</P>
<P>For the <I>linear</I> style, the angle is used to find 2 surrounding table
values from which an energy or its derivative is computed by linear
interpolation.
</P>
<P>For the <I>spline</I> style, a cubic spline coefficients are computed and
stored at each of the <I>N</I> values in the table. The angle is used to
find the appropriate set of coefficients which are used to evaluate a
cubic polynomial which computes the energy or derivative.
</P>
<P>The following coefficients must be defined for each angle type via the
<A HREF = "angle_coeff.html">angle_coeff</A> command as in the example above.
</P>
<UL><LI>filename
<LI>keyword
</UL>
<P>The filename specifies a file containing tabulated energy and
derivative values. The keyword specifies a section of the file. The
format of this file is described below.
</P>
<HR>
<P>The format of a tabulated file is as follows (without the
parenthesized comments):
</P>
<PRE># Angle potential for harmonic (one or more comment or blank lines)
</PRE>
<PRE>HAM (keyword is the first text on line)
N 181 FP 0 0 EQ 90.0 (N, FP, EQ parameters)
(blank line)
N 181 FP 0 0 (N, FP parameters)
1 0.0 200.5 2.5 (index, angle, energy, derivative)
2 1.0 198.0 2.5
...
181 180.0 0.0 0.0
</PRE>
<P>A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the
<A HREF = "angle_coeff.html">angle_coeff</A> command. The next line lists (in any
order) one or more parameters for the table. Each parameter is a
keyword followed by one or more numeric values.
</P>
<P>The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the <I>N</I>
specified in the <A HREF = "angle_style.html">angle_style table</A> command. Let
Ntable = <I>N</I> in the angle_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and derivative
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual angles and their atoms. This means that if you
want the interpolation tables of length Ntable to match exactly what
is in the tabulated file (with effectively no preliminary
interpolation), you should set Ntable = Nfile.
</P>
<P>The "FP" parameter is optional. If used, it is followed by two values
fplo and fphi, which are the 2nd derivatives at the innermost and
outermost angle settings. These values are needed by the spline
construction routines. If not specified by the "FP" parameter, they
are estimated (less accurately) by the first two and last two
derivative values in the table.
</P>
<P>The "EQ" parameter is also optional. If used, it is followed by a the
equilibrium angle value, which is used, for example, by the <A HREF = "fix_shake.html">fix
shake</A> command. If not used, the equilibrium angle is
set to 180.0.
</P>
<P>Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
the angle value (in degrees), the 3rd value is the energy (in energy
units), and the 4th is -dE/d(theta) (also in energy units). The 3rd
term is the energy of the 3-atom configuration for the specified
angle. The last term is the derivative of the energy with respect to
the angle (in degrees, not radians). Thus the units of the last term
are still energy, not force. The angle values must increase from one
line to the next. The angle values must also begin with 0.0 and end
with 180.0, i.e. span the full range of possible angles.
</P>
<P>Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "angle_coeff.html">angle_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/angle_table.txt b/doc/angle_table.txt
index eaee17968..008d0c21f 100644
--- a/doc/angle_table.txt
+++ b/doc/angle_table.txt
@@ -1,131 +1,156 @@
"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
angle_style table command :h3
+angle_style table/omp command :h3
[Syntax:]
angle_style table style N :pre
style = {linear} or {spline} = method of interpolation
N = use N values in table :ul
[Examples:]
angle_style table linear 1000
angle_coeff 3 file.table ENTRY1 :pre
[Description:]
Style {table} creates interpolation tables of length {N} from angle
potential and derivative values listed in a file(s) as a function of
angle The files are read by the "angle_coeff"_angle_coeff.html
command.
The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and derivative values at each of
{N} angles. During a simulation, these tables are used to interpolate
energy and force values on individual atoms as needed. The
interpolation is done in one of 2 styles: {linear} or {spline}.
For the {linear} style, the angle is used to find 2 surrounding table
values from which an energy or its derivative is computed by linear
interpolation.
For the {spline} style, a cubic spline coefficients are computed and
stored at each of the {N} values in the table. The angle is used to
find the appropriate set of coefficients which are used to evaluate a
cubic polynomial which computes the energy or derivative.
The following coefficients must be defined for each angle type via the
"angle_coeff"_angle_coeff.html command as in the example above.
filename
keyword :ul
The filename specifies a file containing tabulated energy and
derivative values. The keyword specifies a section of the file. The
format of this file is described below.
:line
The format of a tabulated file is as follows (without the
parenthesized comments):
# Angle potential for harmonic (one or more comment or blank lines) :pre
HAM (keyword is the first text on line)
N 181 FP 0 0 EQ 90.0 (N, FP, EQ parameters)
(blank line)
N 181 FP 0 0 (N, FP parameters)
1 0.0 200.5 2.5 (index, angle, energy, derivative)
2 1.0 198.0 2.5
...
181 180.0 0.0 0.0 :pre
A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the
"angle_coeff"_angle_coeff.html command. The next line lists (in any
order) one or more parameters for the table. Each parameter is a
keyword followed by one or more numeric values.
The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the {N}
specified in the "angle_style table"_angle_style.html command. Let
Ntable = {N} in the angle_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and derivative
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual angles and their atoms. This means that if you
want the interpolation tables of length Ntable to match exactly what
is in the tabulated file (with effectively no preliminary
interpolation), you should set Ntable = Nfile.
The "FP" parameter is optional. If used, it is followed by two values
fplo and fphi, which are the 2nd derivatives at the innermost and
outermost angle settings. These values are needed by the spline
construction routines. If not specified by the "FP" parameter, they
are estimated (less accurately) by the first two and last two
derivative values in the table.
The "EQ" parameter is also optional. If used, it is followed by a the
equilibrium angle value, which is used, for example, by the "fix
shake"_fix_shake.html command. If not used, the equilibrium angle is
set to 180.0.
Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
the angle value (in degrees), the 3rd value is the energy (in energy
units), and the 4th is -dE/d(theta) (also in energy units). The 3rd
term is the energy of the 3-atom configuration for the specified
angle. The last term is the derivative of the energy with respect to
the angle (in degrees, not radians). Thus the units of the last term
are still energy, not force. The angle values must increase from one
line to the next. The angle values must also begin with 0.0 and end
with 180.0, i.e. span the full range of possible angles.
Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"angle_coeff"_angle_coeff.html
[Default:] none
diff --git a/doc/bond_class2.html b/doc/bond_class2.html
index b560a514d..d12a5254a 100644
--- a/doc/bond_class2.html
+++ b/doc/bond_class2.html
@@ -1,61 +1,87 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style class2 command
</H3>
+<H3>bond_style class2/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style class2
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style class2
bond_coeff 1 1.0 100.0 80.0 80.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>class2</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_class2.jpg">
</CENTER>
<P>where r0 is the equilibrium bond distance.
</P>
<P>See <A HREF = "#Sun">(Sun)</A> for a description of the COMPASS class2 force field.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>R0 (distance)
<LI>K2 (energy/distance^2)
<LI>K3 (energy/distance^3)
<LI>K4 (energy/distance^4)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the CLASS2
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Sun"></A>
<P><B>(Sun)</B> Sun, J Phys Chem B 102, 7338-7364 (1998).
</P>
</HTML>
diff --git a/doc/bond_class2.txt b/doc/bond_class2.txt
index 855be7b91..c6a9c317e 100644
--- a/doc/bond_class2.txt
+++ b/doc/bond_class2.txt
@@ -1,55 +1,80 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style class2 command :h3
+bond_style class2/omp command :h3
[Syntax:]
bond_style class2 :pre
[Examples:]
bond_style class2
bond_coeff 1 1.0 100.0 80.0 80.0 :pre
[Description:]
The {class2} bond style uses the potential
:c,image(Eqs/bond_class2.jpg)
where r0 is the equilibrium bond distance.
See "(Sun)"_#Sun for a description of the COMPASS class2 force field.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
R0 (distance)
K2 (energy/distance^2)
K3 (energy/distance^3)
K4 (energy/distance^4) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the CLASS2
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
:line
:link(Sun)
[(Sun)] Sun, J Phys Chem B 102, 7338-7364 (1998).
diff --git a/doc/bond_fene.html b/doc/bond_fene.html
index 6076d3cdb..06efe05a1 100644
--- a/doc/bond_fene.html
+++ b/doc/bond_fene.html
@@ -1,67 +1,93 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style fene command
</H3>
+<H3>bond_style fene/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style fene
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style fene
bond_coeff 1 30.0 1.5 1.0 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>fene</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_fene.jpg">
</CENTER>
<P>to define a finite extensible nonlinear elastic (FENE) potential
<A HREF = "#Kremer">(Kremer)</A>, used for bead-spring polymer models. The first
term is attractive, the 2nd Lennard-Jones term is repulsive. The
first term extends to R0, the maximum extent of the bond. The 2nd
term is cutoff at 2^(1/6) sigma, the minimum of the LJ potential.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/distance^2)
<LI>R0 (distance)
<LI>epsilon (energy)
<LI>sigma (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P>You typically should specify <A HREF = "special_bonds.html"">special_bonds fene</A>
or <A HREF = "special_bonds.html">special_bonds lj/coul 0 1 1</A> to use this bond
style. LAMMPS will issue a warning it that's not the case.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Kremer"></A>
<P><B>(Kremer)</B> Kremer, Grest, J Chem Phys, 92, 5057 (1990).
</P>
</HTML>
diff --git a/doc/bond_fene.txt b/doc/bond_fene.txt
index 6a6a40acd..8ce6ae89c 100644
--- a/doc/bond_fene.txt
+++ b/doc/bond_fene.txt
@@ -1,61 +1,86 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style fene command :h3
+bond_style fene/omp command :h3
[Syntax:]
bond_style fene :pre
[Examples:]
bond_style fene
bond_coeff 1 30.0 1.5 1.0 1.0 :pre
[Description:]
The {fene} bond style uses the potential
:c,image(Eqs/bond_fene.jpg)
to define a finite extensible nonlinear elastic (FENE) potential
"(Kremer)"_#Kremer, used for bead-spring polymer models. The first
term is attractive, the 2nd Lennard-Jones term is repulsive. The
first term extends to R0, the maximum extent of the bond. The 2nd
term is cutoff at 2^(1/6) sigma, the minimum of the LJ potential.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/distance^2)
R0 (distance)
epsilon (energy)
sigma (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
You typically should specify "special_bonds fene"_special_bonds.html"
or "special_bonds lj/coul 0 1 1"_special_bonds.html to use this bond
style. LAMMPS will issue a warning it that's not the case.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
:line
:link(Kremer)
[(Kremer)] Kremer, Grest, J Chem Phys, 92, 5057 (1990).
diff --git a/doc/bond_fene_expand.html b/doc/bond_fene_expand.html
index da9b2e2da..a68e76f04 100644
--- a/doc/bond_fene_expand.html
+++ b/doc/bond_fene_expand.html
@@ -1,72 +1,98 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style fene/expand command
</H3>
+<H3>bond_style fene/expand/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style fene/expand
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style fene/expand
bond_coeff 1 30.0 1.5 1.0 1.0 0.5
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>fene/expand</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_fene_expand.jpg">
</CENTER>
<P>to define a finite extensible nonlinear elastic (FENE) potential
<A HREF = "#Kremer">(Kremer)</A>, used for bead-spring polymer models. The first
term is attractive, the 2nd Lennard-Jones term is repulsive.
</P>
<P>The <I>fene/expand</I> bond style is similar to <I>fene</I> except that an extra
shift factor of delta (positive or negative) is added to <I>r</I> to
effectively change the bead size of the bonded atoms. The first term
now extends to R0 + delta and the 2nd term is cutoff at 2^(1/6) sigma
+ delta.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/distance^2)
<LI>R0 (distance)
<LI>epsilon (energy)
<LI>sigma (distance)
<LI>delta (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P>You typically should specify <A HREF = "special_bonds.html"">special_bonds fene</A>
or <A HREF = "special_bonds.html">special_bonds lj/coul 0 1 1</A> to use this bond
style. LAMMPS will issue a warning it that's not the case.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Kremer"></A>
<P><B>(Kremer)</B> Kremer, Grest, J Chem Phys, 92, 5057 (1990).
</P>
</HTML>
diff --git a/doc/bond_fene_expand.txt b/doc/bond_fene_expand.txt
index 011d6321a..997921cd7 100644
--- a/doc/bond_fene_expand.txt
+++ b/doc/bond_fene_expand.txt
@@ -1,66 +1,91 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style fene/expand command :h3
+bond_style fene/expand/omp command :h3
[Syntax:]
bond_style fene/expand :pre
[Examples:]
bond_style fene/expand
bond_coeff 1 30.0 1.5 1.0 1.0 0.5 :pre
[Description:]
The {fene/expand} bond style uses the potential
:c,image(Eqs/bond_fene_expand.jpg)
to define a finite extensible nonlinear elastic (FENE) potential
"(Kremer)"_#Kremer, used for bead-spring polymer models. The first
term is attractive, the 2nd Lennard-Jones term is repulsive.
The {fene/expand} bond style is similar to {fene} except that an extra
shift factor of delta (positive or negative) is added to {r} to
effectively change the bead size of the bonded atoms. The first term
now extends to R0 + delta and the 2nd term is cutoff at 2^(1/6) sigma
+ delta.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/distance^2)
R0 (distance)
epsilon (energy)
sigma (distance)
delta (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
You typically should specify "special_bonds fene"_special_bonds.html"
or "special_bonds lj/coul 0 1 1"_special_bonds.html to use this bond
style. LAMMPS will issue a warning it that's not the case.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
:line
:link(Kremer)
[(Kremer)] Kremer, Grest, J Chem Phys, 92, 5057 (1990).
diff --git a/doc/bond_harmonic.html b/doc/bond_harmonic.html
index efb2d26ab..3fbe7041c 100644
--- a/doc/bond_harmonic.html
+++ b/doc/bond_harmonic.html
@@ -1,52 +1,78 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style harmonic command
</H3>
+<H3>bond_style harmonic/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style harmonic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style harmonic
bond_coeff 5 80.0 1.2
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_harmonic.jpg">
</CENTER>
<P>where r0 is the equilibrium bond distance. Note that the usual 1/2
factor is included in K.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/distance^2)
<LI>r0 (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_harmonic.txt b/doc/bond_harmonic.txt
index 658c87378..df5bdeeff 100644
--- a/doc/bond_harmonic.txt
+++ b/doc/bond_harmonic.txt
@@ -1,47 +1,72 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style harmonic command :h3
+bond_style harmonic/omp command :h3
[Syntax:]
bond_style harmonic :pre
[Examples:]
bond_style harmonic
bond_coeff 5 80.0 1.2 :pre
[Description:]
The {harmonic} bond style uses the potential
:c,image(Eqs/bond_harmonic.jpg)
where r0 is the equilibrium bond distance. Note that the usual 1/2
factor is included in K.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/distance^2)
r0 (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
diff --git a/doc/bond_harmonic_shift.html b/doc/bond_harmonic_shift.html
index 8394ebf85..0b9b3f6c1 100644
--- a/doc/bond_harmonic_shift.html
+++ b/doc/bond_harmonic_shift.html
@@ -1,58 +1,84 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style harmonic/shift command
</H3>
+<H3>bond_style harmonic/shift/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style harmonic/shift
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style harmonic/shift
bond_coeff 5 10.0 0.5 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic/shift</I> bond style is a shifted harmonic bond that uses
the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_harmonic_shift.jpg">
</CENTER>
<P>where r0 is the equilibrium bond distance, and rc the critical distance.
The potential is -Umin at r0 and zero at rc. The spring constant is
k = Umin / [ 2 (r0-rc)^2].
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>Umin (energy)
</UL>
<UL><LI>r0 (distance)
</UL>
<UL><LI>rc (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>,
<A HREF = "bond_harmonic.html">bond_harmonic</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_harmonic_shift.txt b/doc/bond_harmonic_shift.txt
index 4bef45dd1..0ca376089 100644
--- a/doc/bond_harmonic_shift.txt
+++ b/doc/bond_harmonic_shift.txt
@@ -1,51 +1,76 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style harmonic/shift command :h3
+bond_style harmonic/shift/omp command :h3
[Syntax:]
bond_style harmonic/shift :pre
[Examples:]
bond_style harmonic/shift
bond_coeff 5 10.0 0.5 1.0 :pre
[Description:]
The {harmonic/shift} bond style is a shifted harmonic bond that uses
the potential
:c,image(Eqs/bond_harmonic_shift.jpg)
where r0 is the equilibrium bond distance, and rc the critical distance.
The potential is -Umin at r0 and zero at rc. The spring constant is
k = Umin / \[ 2 (r0-rc)^2\].
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
Umin (energy) :ul
r0 (distance) :ul
rc (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html,
"bond_harmonic"_bond_harmonic.html
[Default:] none
diff --git a/doc/bond_harmonic_shift_cut.html b/doc/bond_harmonic_shift_cut.html
index 2142fc5f8..b7b8e3064 100644
--- a/doc/bond_harmonic_shift_cut.html
+++ b/doc/bond_harmonic_shift_cut.html
@@ -1,57 +1,83 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style harmonic/shift/cut command
</H3>
+<H3>bond_style harmonic/shift/cut/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style harmonic/shift/cut
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style harmonic/shift/cut
bond_coeff 5 10.0 0.5 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic/shift/cut</I> bond style is a shifted harmonic bond that
uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_harmonic_shift_cut.jpg">
</CENTER>
<P>where r0 is the equilibrium bond distance, and rc the critical distance.
The bond potential is zero for distances r > rc. The potential is -Umin
at r0 and zero at rc. The spring constant is k = Umin / [ 2 (r0-rc)^2].
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>Umin (energy)
<LI>r0 (distance)
<LI>rc (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>,
<A HREF = "bond_harmonic.html">bond_harmonic</A>,
<A HREF = "bond_harmonicshift.html">bond_harmonicshift</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_harmonic_shift_cut.txt b/doc/bond_harmonic_shift_cut.txt
index ea9de8e93..847a45541 100644
--- a/doc/bond_harmonic_shift_cut.txt
+++ b/doc/bond_harmonic_shift_cut.txt
@@ -1,52 +1,77 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style harmonic/shift/cut command :h3
+bond_style harmonic/shift/cut/omp command :h3
[Syntax:]
bond_style harmonic/shift/cut :pre
[Examples:]
bond_style harmonic/shift/cut
bond_coeff 5 10.0 0.5 1.0 :pre
[Description:]
The {harmonic/shift/cut} bond style is a shifted harmonic bond that
uses the potential
:c,image(Eqs/bond_harmonic_shift_cut.jpg)
where r0 is the equilibrium bond distance, and rc the critical distance.
The bond potential is zero for distances r > rc. The potential is -Umin
at r0 and zero at rc. The spring constant is k = Umin / \[ 2 (r0-rc)^2\].
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
Umin (energy)
r0 (distance)
rc (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html,
"bond_harmonic"_bond_harmonic.html,
"bond_harmonicshift"_bond_harmonicshift.html
[Default:] none
diff --git a/doc/bond_morse.html b/doc/bond_morse.html
index e82692404..3c6051438 100644
--- a/doc/bond_morse.html
+++ b/doc/bond_morse.html
@@ -1,53 +1,79 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style morse command
</H3>
+<H3>bond_style morse/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style morse
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style morse
bond_coeff 5 1.0 2.0 1.2
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>morse</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_morse.jpg">
</CENTER>
<P>where r0 is the equilibrium bond distance, alpha is a stiffness
parameter, and D determines the depth of the potential well.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>D (energy)
<LI>alpha (inverse distance)
<LI>r0 (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_morse.txt b/doc/bond_morse.txt
index be9c00665..b399b02e9 100644
--- a/doc/bond_morse.txt
+++ b/doc/bond_morse.txt
@@ -1,48 +1,73 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style morse command :h3
+bond_style morse/omp command :h3
[Syntax:]
bond_style morse :pre
[Examples:]
bond_style morse
bond_coeff 5 1.0 2.0 1.2 :pre
[Description:]
The {morse} bond style uses the potential
:c,image(Eqs/bond_morse.jpg)
where r0 is the equilibrium bond distance, alpha is a stiffness
parameter, and D determines the depth of the potential well.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
D (energy)
alpha (inverse distance)
r0 (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
diff --git a/doc/bond_nonlinear.html b/doc/bond_nonlinear.html
index 06fd7cb45..c511c2c95 100644
--- a/doc/bond_nonlinear.html
+++ b/doc/bond_nonlinear.html
@@ -1,59 +1,85 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style nonlinear command
</H3>
+<H3>bond_style nonlinear/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style nonlinear
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style nonlinear
bond_coeff 2 100.0 1.1 1.4
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>nonlinear</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_nonlinear.jpg">
</CENTER>
<P>to define an anharmonic spring <A HREF = "#Rector">(Rector)</A> of equilibrium
length r0 and maximum extension lamda.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>epsilon (energy)
<LI>r0 (distance)
<LI>lamda (distance)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Rector"></A>
<P><B>(Rector)</B> Rector, Van Swol, Henderson, Molecular Physics, 82, 1009 (1994).
</P>
</HTML>
diff --git a/doc/bond_nonlinear.txt b/doc/bond_nonlinear.txt
index 2cd41962e..e0cd987b6 100644
--- a/doc/bond_nonlinear.txt
+++ b/doc/bond_nonlinear.txt
@@ -1,53 +1,78 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style nonlinear command :h3
+bond_style nonlinear/omp command :h3
[Syntax:]
bond_style nonlinear :pre
[Examples:]
bond_style nonlinear
bond_coeff 2 100.0 1.1 1.4 :pre
[Description:]
The {nonlinear} bond style uses the potential
:c,image(Eqs/bond_nonlinear.jpg)
to define an anharmonic spring "(Rector)"_#Rector of equilibrium
length r0 and maximum extension lamda.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
epsilon (energy)
r0 (distance)
lamda (distance) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
:line
:link(Rector)
[(Rector)] Rector, Van Swol, Henderson, Molecular Physics, 82, 1009 (1994).
diff --git a/doc/bond_quartic.html b/doc/bond_quartic.html
index 824c46716..fc138a298 100644
--- a/doc/bond_quartic.html
+++ b/doc/bond_quartic.html
@@ -1,92 +1,118 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style quartic command
</H3>
+<H3>bond_style quartic/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style quartic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>bond_style quartic
bond_coeff 2 1200 -0.55 0.25 1.3 34.6878
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>quartic</I> bond style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/bond_quartic.jpg">
</CENTER>
<P>to define a bond that can be broken as the simulation proceeds (e.g.
due to a polymer being stretched). The sigma and epsilon used in the
LJ portion of the formula are both set equal to 1.0 by LAMMPS.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy/distance^2)
<LI>B1 (distance)
<LI>B2 (distance)
<LI>Rc (distance)
<LI>U0 (energy)
</UL>
<P>This potential was constructed to mimic the FENE bond potential for
coarse-grained polymer chains. When monomers with sigma = epsilon =
1.0 are used, the following choice of parameters gives a quartic
potential that looks nearly like the FENE potential: K = 1200, B1 =
-0.55, B2 = 0.25, Rc = 1.3, and U0 = 34.6878. Different parameters
can be specified using the <A HREF = "bond_coeff.html">bond_coeff</A> command, but
you will need to choose them carefully so they form a suitable bond
potential.
</P>
<P>Rc is the cutoff length at which the bond potential goes smoothly to a
local maximum. If a bond length ever becomes > Rc, LAMMPS "breaks"
the bond, which means two things. First, the bond potential is turned
off by setting its type to 0, and is no longer computed. Second, a
pairwise interaction between the two atoms is turned on, since they
are no longer bonded.
</P>
<P>LAMMPS does the second task via a computational sleight-of-hand. It
subtracts the pairwise interaction as part of the bond computation.
When the bond breaks, the subtraction stops. For this to work, the
pairwise interaction must always be computed by the
<A HREF = "pair_style.html">pair_style</A> command, whether the bond is broken or
not. This means that <A HREF = "special_bonds.html">special_bonds</A> must be set
to 1,1,1, as indicated as a restriction below.
</P>
<P>Note that when bonds are dumped to a file via the <A HREF = "dump.html">dump
local</A> command, bonds with type 0 are not included. The
<A HREF = "delete_bonds.html">delete_bonds</A> command can also be used to query the
status of broken bonds or permanently delete them, e.g.:
</P>
<PRE>delete_bonds all stats
delete_bonds all bond 0 remove
</PRE>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P>The <I>quartic</I> style requires that <A HREF = "special_bonds.html">special_bonds</A>
parameters be set to 1,1,1. Three- and four-body interactions (angle,
dihedral, etc) cannot be used with <I>quartic</I> bonds.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_quartic.txt b/doc/bond_quartic.txt
index 068defb54..b0a7ff4bc 100644
--- a/doc/bond_quartic.txt
+++ b/doc/bond_quartic.txt
@@ -1,87 +1,112 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style quartic command :h3
+bond_style quartic/omp command :h3
[Syntax:]
bond_style quartic :pre
[Examples:]
bond_style quartic
bond_coeff 2 1200 -0.55 0.25 1.3 34.6878 :pre
[Description:]
The {quartic} bond style uses the potential
:c,image(Eqs/bond_quartic.jpg)
to define a bond that can be broken as the simulation proceeds (e.g.
due to a polymer being stretched). The sigma and epsilon used in the
LJ portion of the formula are both set equal to 1.0 by LAMMPS.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy/distance^2)
B1 (distance)
B2 (distance)
Rc (distance)
U0 (energy) :ul
This potential was constructed to mimic the FENE bond potential for
coarse-grained polymer chains. When monomers with sigma = epsilon =
1.0 are used, the following choice of parameters gives a quartic
potential that looks nearly like the FENE potential: K = 1200, B1 =
-0.55, B2 = 0.25, Rc = 1.3, and U0 = 34.6878. Different parameters
can be specified using the "bond_coeff"_bond_coeff.html command, but
you will need to choose them carefully so they form a suitable bond
potential.
Rc is the cutoff length at which the bond potential goes smoothly to a
local maximum. If a bond length ever becomes > Rc, LAMMPS "breaks"
the bond, which means two things. First, the bond potential is turned
off by setting its type to 0, and is no longer computed. Second, a
pairwise interaction between the two atoms is turned on, since they
are no longer bonded.
LAMMPS does the second task via a computational sleight-of-hand. It
subtracts the pairwise interaction as part of the bond computation.
When the bond breaks, the subtraction stops. For this to work, the
pairwise interaction must always be computed by the
"pair_style"_pair_style.html command, whether the bond is broken or
not. This means that "special_bonds"_special_bonds.html must be set
to 1,1,1, as indicated as a restriction below.
Note that when bonds are dumped to a file via the "dump
local"_dump.html command, bonds with type 0 are not included. The
"delete_bonds"_delete_bonds.html command can also be used to query the
status of broken bonds or permanently delete them, e.g.:
delete_bonds all stats
delete_bonds all bond 0 remove :pre
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
The {quartic} style requires that "special_bonds"_special_bonds.html
parameters be set to 1,1,1. Three- and four-body interactions (angle,
dihedral, etc) cannot be used with {quartic} bonds.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
diff --git a/doc/bond_table.html b/doc/bond_table.html
index 29ec7bc94..d79c4b409 100644
--- a/doc/bond_table.html
+++ b/doc/bond_table.html
@@ -1,133 +1,159 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>bond_style table command
</H3>
+<H3>bond_style table/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>bond_style table style N
</PRE>
<UL><LI>style = <I>linear</I> or <I>spline</I> = method of interpolation
<LI>N = use N values in table
</UL>
<P><B>Examples:</B>
</P>
<PRE>bond_style table linear 1000
bond_coeff 1 file.table ENTRY1
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>table</I> creates interpolation tables of length <I>N</I> from bond
potential and force values listed in a file(s) as a function of bond
length. The files are read by the <A HREF = "bond_coeff.html">bond_coeff</A>
command.
</P>
<P>The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and force values at each of <I>N</I>
distances. During a simulation, these tables are used to interpolate
energy and force values as needed. The interpolation is done in one
of 2 styles: <I>linear</I> or <I>spline</I>.
</P>
<P>For the <I>linear</I> style, the bond length is used to find 2 surrounding
table values from which an energy or force is computed by linear
interpolation.
</P>
<P>For the <I>spline</I> style, a cubic spline coefficients are computed and
stored at each of the <I>N</I> values in the table. The bond length is
used to find the appropriate set of coefficients which are used to
evaluate a cubic polynomial which computes the energy or force.
</P>
<P>The following coefficients must be defined for each bond type via the
<A HREF = "bond_coeff.html">bond_coeff</A> command as in the example above.
</P>
<UL><LI>filename
<LI>keyword
</UL>
<P>The filename specifies a file containing tabulated energy and force
values. The keyword specifies a section of the file. The format of
this file is described below.
</P>
<HR>
<P>The format of a tabulated file is as follows (without the
parenthesized comments):
</P>
<PRE># Bond potential for harmonic (one or more comment or blank lines)
</PRE>
<PRE>HAM (keyword is the first text on line)
N 101 FP 0 0 EQ 0.5 (N, FP, EQ parameters)
(blank line)
1 0.00 338.0000 1352.0000 (index, bond-length, energy, force)
2 0.01 324.6152 1324.9600
...
101 1.00 338.0000 -1352.0000
</PRE>
<P>A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the
<A HREF = "bond_coeff.html">bond_coeff</A> command. The next line lists (in any
order) one or more parameters for the table. Each parameter is a
keyword followed by one or more numeric values.
</P>
<P>The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the <I>N</I>
specified in the <A HREF = "bond_style.html">bond_style table</A> command. Let
Ntable = <I>N</I> in the bond_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and force
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual bond lengths. This means that if you want the
interpolation tables of length Ntable to match exactly what is in the
tabulated file (with effectively no preliminary interpolation), you
should set Ntable = Nfile.
</P>
<P>The "FP" parameter is optional. If used, it is followed by two values
fplo and fphi, which are the derivatives of the force at the innermost
and outermost bond lengths. These values are needed by the spline
construction routines. If not specified by the "FP" parameter, they
are estimated (less accurately) by the first two and last two force
values in the table.
</P>
<P>The "EQ" parameter is also optional. If used, it is followed by a the
equilibrium bond length, which is used, for example, by the <A HREF = "fix_shake.html">fix
shake</A> command. If not used, the equilibrium bond
length is set to 0.0.
</P>
<P>Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
the bond length r (in distance units), the 3rd value is the energy (in
energy units), and the 4th is the force (in force units). The bond
lengths must range from a LO value to a HI value, and increase from
one line to the next. If the actual bond length is ever smaller than
the LO value or larger than the HI value, then the bond energy and
force is evaluated as if the bond were the LO or HI length.
</P>
<P>Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "delete_bonds.html">delete_bonds</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/bond_table.txt b/doc/bond_table.txt
index c02b71e86..be9060d59 100644
--- a/doc/bond_table.txt
+++ b/doc/bond_table.txt
@@ -1,128 +1,153 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
bond_style table command :h3
+bond_style table/omp command :h3
[Syntax:]
bond_style table style N :pre
style = {linear} or {spline} = method of interpolation
N = use N values in table :ul
[Examples:]
bond_style table linear 1000
bond_coeff 1 file.table ENTRY1 :pre
[Description:]
Style {table} creates interpolation tables of length {N} from bond
potential and force values listed in a file(s) as a function of bond
length. The files are read by the "bond_coeff"_bond_coeff.html
command.
The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and force values at each of {N}
distances. During a simulation, these tables are used to interpolate
energy and force values as needed. The interpolation is done in one
of 2 styles: {linear} or {spline}.
For the {linear} style, the bond length is used to find 2 surrounding
table values from which an energy or force is computed by linear
interpolation.
For the {spline} style, a cubic spline coefficients are computed and
stored at each of the {N} values in the table. The bond length is
used to find the appropriate set of coefficients which are used to
evaluate a cubic polynomial which computes the energy or force.
The following coefficients must be defined for each bond type via the
"bond_coeff"_bond_coeff.html command as in the example above.
filename
keyword :ul
The filename specifies a file containing tabulated energy and force
values. The keyword specifies a section of the file. The format of
this file is described below.
:line
The format of a tabulated file is as follows (without the
parenthesized comments):
# Bond potential for harmonic (one or more comment or blank lines) :pre
HAM (keyword is the first text on line)
N 101 FP 0 0 EQ 0.5 (N, FP, EQ parameters)
(blank line)
1 0.00 338.0000 1352.0000 (index, bond-length, energy, force)
2 0.01 324.6152 1324.9600
...
101 1.00 338.0000 -1352.0000 :pre
A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the
"bond_coeff"_bond_coeff.html command. The next line lists (in any
order) one or more parameters for the table. Each parameter is a
keyword followed by one or more numeric values.
The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the {N}
specified in the "bond_style table"_bond_style.html command. Let
Ntable = {N} in the bond_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and force
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual bond lengths. This means that if you want the
interpolation tables of length Ntable to match exactly what is in the
tabulated file (with effectively no preliminary interpolation), you
should set Ntable = Nfile.
The "FP" parameter is optional. If used, it is followed by two values
fplo and fphi, which are the derivatives of the force at the innermost
and outermost bond lengths. These values are needed by the spline
construction routines. If not specified by the "FP" parameter, they
are estimated (less accurately) by the first two and last two force
values in the table.
The "EQ" parameter is also optional. If used, it is followed by a the
equilibrium bond length, which is used, for example, by the "fix
shake"_fix_shake.html command. If not used, the equilibrium bond
length is set to 0.0.
Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
the bond length r (in distance units), the 3rd value is the energy (in
energy units), and the 4th is the force (in force units). The bond
lengths must range from a LO value to a HI value, and increase from
one line to the next. If the actual bond length is ever smaller than
the LO value or larger than the HI value, then the bond energy and
force is evaluated as if the bond were the LO or HI length.
Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This bond style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"bond_coeff"_bond_coeff.html, "delete_bonds"_delete_bonds.html
[Default:] none
diff --git a/doc/compute_ackland_atom.html b/doc/compute_ackland_atom.html
index 16ad975e8..d3445f2f5 100644
--- a/doc/compute_ackland_atom.html
+++ b/doc/compute_ackland_atom.html
@@ -1,80 +1,80 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ackland/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID ackland/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ackland/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ackland/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Defines a computation that calculates the local lattice structure
according to the formulation given in <A HREF = "#Ackland">(Ackland)</A>.
</P>
<P>In contrast to the <A HREF = "compute_centro_atom.html">centro-symmetry
parameter</A> this method is stable against
temperature boost, because it is based not on the distance between
particles but the angles. Therefore statistical fluctuations are
averaged out a little more. A comparison with the Common Neighbor
Analysis metric is made in the paper.
</P>
<P>The result is a number which is mapped to the following different
lattice structures:
</P>
<UL><LI>0 = UNKNOWN
<LI>1 = BCC
<LI>2 = FCC
<LI>3 = HCP
<LI>4 = ICO
</UL>
<P>The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of
which computes this quantity.-
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-MISC package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The per-atom vector values will be unitless since they are the
integers defined above.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_centro_atom.html">compute centro/atom</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Ackland"></A>
<P><B>(Ackland)</B> Ackland, Jones, Phys Rev B, 73, 054104 (2006).
</P>
</HTML>
diff --git a/doc/compute_ackland_atom.txt b/doc/compute_ackland_atom.txt
index 5a9dcebba..62fa81282 100644
--- a/doc/compute_ackland_atom.txt
+++ b/doc/compute_ackland_atom.txt
@@ -1,74 +1,74 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ackland/atom command :h3
[Syntax:]
compute ID group-ID ackland/atom :pre
ID, group-ID are documented in "compute"_compute.html command
ackland/atom = style name of this compute command :ul
[Examples:]
compute 1 all ackland/atom :pre
[Description:]
Defines a computation that calculates the local lattice structure
according to the formulation given in "(Ackland)"_#Ackland.
In contrast to the "centro-symmetry
parameter"_compute_centro_atom.html this method is stable against
temperature boost, because it is based not on the distance between
particles but the angles. Therefore statistical fluctuations are
averaged out a little more. A comparison with the Common Neighbor
Analysis metric is made in the paper.
The result is a number which is mapped to the following different
lattice structures:
0 = UNKNOWN
1 = BCC
2 = FCC
3 = HCP
4 = ICO :ul
The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of
which computes this quantity.-
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
[Restrictions:]
This compute is part of the USER-MISC package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The per-atom vector values will be unitless since they are the
integers defined above.
[Related commands:]
"compute centro/atom"_compute_centro_atom.html
[Default:] none
:line
:link(Ackland)
[(Ackland)] Ackland, Jones, Phys Rev B, 73, 054104 (2006).
diff --git a/doc/compute_centro_atom.html b/doc/compute_centro_atom.html
index 63c0c2b95..6b3c03710 100644
--- a/doc/compute_centro_atom.html
+++ b/doc/compute_centro_atom.html
@@ -1,126 +1,126 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute centro/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID centro/atom lattice
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>centro/atom = style name of this compute command
<LI>lattice = <I>fcc</I> or <I>bcc</I> or N = # of neighbors per atom to include
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all centro/atom fcc
</PRE>
<PRE>compute 1 all centro/atom 8
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the centro-symmetry parameter for
each atom in the group. In solid-state systems the centro-symmetry
parameter is a useful measure of the local lattice disorder around an
atom and can be used to characterize whether the atom is part of a
perfect lattice, a local defect (e.g. a dislocation or stacking
fault), or at a surface.
</P>
<P>The value of the centro-symmetry parameter will be 0.0 for atoms not
in the specified compute group.
</P>
<P>This parameter is computed using the following formula from
<A HREF = "#Kelchner">(Kelchner)</A>
</P>
<CENTER><IMG SRC = "Eqs/centro_symmetry.jpg">
</CENTER>
<P>where the <I>N</I> nearest neighbors or each atom are identified and Ri and
Ri+N/2 are vectors from the central atom to a particular pair of
nearest neighbors. There are N*(N-1)/2 possible neighbor pairs that
can contribute to this formula. The quantity in the sum is computed
for each, and the N/2 smallest are used. This will typically be for
pairs of atoms in symmetrically opposite positions with respect to the
central atom; hence the i+N/2 notation.
</P>
<P><I>N</I> is an input parameter, which should be set to correspond to the
number of nearest neighbors in the underlying lattice of atoms. If
the keyword <I>fcc</I> or <I>bcc</I> is used, <I>N</I> is set to 12 and 8
respectively. More generally, <I>N</I> can be set to a positive, even
integer.
</P>
<P>For an atom on a lattice site, surrounded by atoms on a perfect
lattice, the centro-symmetry parameter will be 0. It will be near 0
for small thermal perturbations of a perfect lattice. If a point
defect exists, the symmetry is broken, and the parameter will be a
larger positive value. An atom at a surface will have a large
positive parameter. If the atom does not have <I>N</I> neighbors (within
the potential cutoff), then its centro-symmetry parameter is set to
0.0.
</P>
<P>Only atoms within the cutoff of the pairwise neighbor list are
considered as possible neighbors. Atoms not in the compute group are
included in the <I>N</I> neighbors used in this calculation.
</P>
<P>The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (e.g. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each with a
<I>centro/atom</I> style.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values are unitless values >= 0.0. Their
magnitude depends on the lattice style due to the number of
contibuting neighbor pairs in the summation in the formula above. And
it depends on the local defects surrounding the central atom, as
described above.
</P>
<P>Here are typical centro-symmetry values, from a a nanoindentation
simulation into gold (FCC). These were provided by Jon Zimmerman
(Sandia):
</P>
<PRE>Bulk lattice = 0
Dislocation core ~ 1.0 (0.5 to 1.25)
Stacking faults ~ 5.0 (4.0 to 6.0)
Free surface ~ 23.0
</PRE>
<P>These values are *not* normalized by the square of the lattice
parameter. If they were, normalized values would be:
</P>
<PRE>Bulk lattice = 0
Dislocation core ~ 0.06 (0.03 to 0.075)
Stacking faults ~ 0.3 (0.24 to 0.36)
Free surface ~ 1.38
</PRE>
<P>For BCC materials, the values for dislocation cores and free surfaces
would be somewhat different, due to their being only 8 neighbors instead
of 12.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_cna_atom.html">compute cna/atom</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Kelchner"></A>
<P><B>(Kelchner)</B> Kelchner, Plimpton, Hamilton, Phys Rev B, 58, 11085 (1998).
</P>
</HTML>
diff --git a/doc/compute_centro_atom.txt b/doc/compute_centro_atom.txt
index a5a83a0c3..5a9faf909 100644
--- a/doc/compute_centro_atom.txt
+++ b/doc/compute_centro_atom.txt
@@ -1,119 +1,119 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute centro/atom command :h3
[Syntax:]
compute ID group-ID centro/atom lattice :pre
ID, group-ID are documented in "compute"_compute.html command
centro/atom = style name of this compute command
lattice = {fcc} or {bcc} or N = # of neighbors per atom to include :ul
[Examples:]
compute 1 all centro/atom fcc :pre
compute 1 all centro/atom 8 :pre
[Description:]
Define a computation that calculates the centro-symmetry parameter for
each atom in the group. In solid-state systems the centro-symmetry
parameter is a useful measure of the local lattice disorder around an
atom and can be used to characterize whether the atom is part of a
perfect lattice, a local defect (e.g. a dislocation or stacking
fault), or at a surface.
The value of the centro-symmetry parameter will be 0.0 for atoms not
in the specified compute group.
This parameter is computed using the following formula from
"(Kelchner)"_#Kelchner
:c,image(Eqs/centro_symmetry.jpg)
where the {N} nearest neighbors or each atom are identified and Ri and
Ri+N/2 are vectors from the central atom to a particular pair of
nearest neighbors. There are N*(N-1)/2 possible neighbor pairs that
can contribute to this formula. The quantity in the sum is computed
for each, and the N/2 smallest are used. This will typically be for
pairs of atoms in symmetrically opposite positions with respect to the
central atom; hence the i+N/2 notation.
{N} is an input parameter, which should be set to correspond to the
number of nearest neighbors in the underlying lattice of atoms. If
the keyword {fcc} or {bcc} is used, {N} is set to 12 and 8
respectively. More generally, {N} can be set to a positive, even
integer.
For an atom on a lattice site, surrounded by atoms on a perfect
lattice, the centro-symmetry parameter will be 0. It will be near 0
for small thermal perturbations of a perfect lattice. If a point
defect exists, the symmetry is broken, and the parameter will be a
larger positive value. An atom at a surface will have a large
positive parameter. If the atom does not have {N} neighbors (within
the potential cutoff), then its centro-symmetry parameter is set to
0.0.
Only atoms within the cutoff of the pairwise neighbor list are
considered as possible neighbors. Atoms not in the compute group are
included in the {N} neighbors used in this calculation.
The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (e.g. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each with a
{centro/atom} style.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values are unitless values >= 0.0. Their
magnitude depends on the lattice style due to the number of
contibuting neighbor pairs in the summation in the formula above. And
it depends on the local defects surrounding the central atom, as
described above.
Here are typical centro-symmetry values, from a a nanoindentation
simulation into gold (FCC). These were provided by Jon Zimmerman
(Sandia):
Bulk lattice = 0
Dislocation core ~ 1.0 (0.5 to 1.25)
Stacking faults ~ 5.0 (4.0 to 6.0)
Free surface ~ 23.0 :pre
These values are *not* normalized by the square of the lattice
parameter. If they were, normalized values would be:
Bulk lattice = 0
Dislocation core ~ 0.06 (0.03 to 0.075)
Stacking faults ~ 0.3 (0.24 to 0.36)
Free surface ~ 1.38 :pre
For BCC materials, the values for dislocation cores and free surfaces
would be somewhat different, due to their being only 8 neighbors instead
of 12.
[Restrictions:] none
[Related commands:]
"compute cna/atom"_compute_cna_atom.html
[Default:] none
:line
:link(Kelchner)
[(Kelchner)] Kelchner, Plimpton, Hamilton, Phys Rev B, 58, 11085 (1998).
diff --git a/doc/compute_cluster_atom.html b/doc/compute_cluster_atom.html
index b2f7b49fd..f972d2fae 100644
--- a/doc/compute_cluster_atom.html
+++ b/doc/compute_cluster_atom.html
@@ -1,62 +1,62 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute cluster/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID cluster/atom cutoff
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>cluster/atom = style name of this compute command
<LI>cutoff = distance within which to label atoms as part of same cluster (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all cluster/atom 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that assigns each atom a cluster ID.
</P>
<P>A cluster is defined as a set of atoms, each of which is within the
cutoff distance from one or more other atoms in the cluster. If an
atom has no neighbors within the cutoff distance, then it is a 1-atom
cluster. The ID of every atom in the cluster will be the smallest
atom ID of any atom in the cluster.
</P>
<P>Only atoms in the compute group are clustered and assigned cluster
IDs. Atoms not in the compute group are assigned a cluster ID = 0.
</P>
<P>The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of a
<I>clsuter/atom</I> style.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be an ID > 0, as explained above.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_coord_atom.html">compute coord/atom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_cluster_atom.txt b/doc/compute_cluster_atom.txt
index 3193331f9..eb4ba3294 100644
--- a/doc/compute_cluster_atom.txt
+++ b/doc/compute_cluster_atom.txt
@@ -1,57 +1,57 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute cluster/atom command :h3
[Syntax:]
compute ID group-ID cluster/atom cutoff :pre
ID, group-ID are documented in "compute"_compute.html command
cluster/atom = style name of this compute command
cutoff = distance within which to label atoms as part of same cluster (distance units) :ul
[Examples:]
compute 1 all cluster/atom 1.0 :pre
[Description:]
Define a computation that assigns each atom a cluster ID.
A cluster is defined as a set of atoms, each of which is within the
cutoff distance from one or more other atoms in the cluster. If an
atom has no neighbors within the cutoff distance, then it is a 1-atom
cluster. The ID of every atom in the cluster will be the smallest
atom ID of any atom in the cluster.
Only atoms in the compute group are clustered and assigned cluster
IDs. Atoms not in the compute group are assigned a cluster ID = 0.
The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of a
{clsuter/atom} style.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be an ID > 0, as explained above.
[Restrictions:] none
[Related commands:]
"compute coord/atom"_compute_coord_atom.html
[Default:] none
diff --git a/doc/compute_cna_atom.html b/doc/compute_cna_atom.html
index 7549fa7c6..191b8911c 100644
--- a/doc/compute_cna_atom.html
+++ b/doc/compute_cna_atom.html
@@ -1,104 +1,104 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute cna/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID cna/atom cutoff
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>cna/atom = style name of this compute command
<LI>cutoff = cutoff distance for nearest neighbors (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all cna/atom 3.08
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the CNA (Common Neighbor
Analysis) pattern for each atom in the group. In solid-state systems
the CNA pattern is a useful measure of the local crystal structure
around an atom. The CNA methodology is described in <A HREF = "#Faken">(Faken)</A>
and <A HREF = "#Tsuzuki">(Tsuzuki)</A>.
</P>
<P>Currently, there are five kinds of CNA patterns LAMMPS recognizes:
</P>
<UL><LI>fcc = 1
<LI>hcp = 2
<LI>bcc = 3
<LI>icosohedral = 4
<LI>unknown = 5
</UL>
<P>The value of the CNA pattern will be 0 for atoms not in the specified
compute group. Note that normally a CNA calculation should only be
performed on mono-component systems.
</P>
<P>The CNA calculation can be sensitive to the specified cutoff value.
You should insure the appropriate nearest neighbors of an atom are
found within the cutoff distance for the presumed crystal strucure.
E.g. 12 nearest neighbor for perfect FCC and HCP crystals, 14 nearest
neighbors for perfect BCC crystals. These formulas can be used to
obtain a good cutoff distance:
</P>
<CENTER><IMG SRC = "Eqs/cna_cutoff1.jpg">
</CENTER>
<P>where a is the lattice constant for the crystal structure concerned
and in the HCP case, x = (c/a) / 1.633, where 1.633 is the ideal c/a
for HCP crystals.
</P>
<P>Also note that since the CNA calculation in LAMMPS uses the neighbors
of an owned atom to find the nearest neighbors of a ghost atom, the
following relation should also be satisfied:
</P>
<CENTER><IMG SRC = "Eqs/cna_cutoff2.jpg">
</CENTER>
<P>where Rc is the cutoff distance of the potential, Rs is the skin
distance as specified by the <A HREF = "neighbor.html">neighbor</A> command, and
cutoff is the argument used with the compute cna/atom command. LAMMPS
will issue a warning if this is not the case.
</P>
<P>The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (e.g. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each with a
<I>cna/atom</I> style.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be a number from 0 to 5, as explained
above.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_centro_atom.html">compute centro/atom</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Faken"></A>
<P><B>(Faken)</B> Faken, Jonsson, Comput Mater Sci, 2, 279 (1994).
</P>
<A NAME = "Tsuzuki"></A>
<P><B>(Tsuzuki)</B> Tsuzuki, Branicio, Rino, Comput Phys Comm, 177, 518 (2007).
</P>
</HTML>
diff --git a/doc/compute_cna_atom.txt b/doc/compute_cna_atom.txt
index 63afcf9a8..7aafcaf80 100644
--- a/doc/compute_cna_atom.txt
+++ b/doc/compute_cna_atom.txt
@@ -1,97 +1,97 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute cna/atom command :h3
[Syntax:]
compute ID group-ID cna/atom cutoff :pre
ID, group-ID are documented in "compute"_compute.html command
cna/atom = style name of this compute command
cutoff = cutoff distance for nearest neighbors (distance units) :ul
[Examples:]
compute 1 all cna/atom 3.08 :pre
[Description:]
Define a computation that calculates the CNA (Common Neighbor
Analysis) pattern for each atom in the group. In solid-state systems
the CNA pattern is a useful measure of the local crystal structure
around an atom. The CNA methodology is described in "(Faken)"_#Faken
and "(Tsuzuki)"_#Tsuzuki.
Currently, there are five kinds of CNA patterns LAMMPS recognizes:
fcc = 1
hcp = 2
bcc = 3
icosohedral = 4
unknown = 5 :ul
The value of the CNA pattern will be 0 for atoms not in the specified
compute group. Note that normally a CNA calculation should only be
performed on mono-component systems.
The CNA calculation can be sensitive to the specified cutoff value.
You should insure the appropriate nearest neighbors of an atom are
found within the cutoff distance for the presumed crystal strucure.
E.g. 12 nearest neighbor for perfect FCC and HCP crystals, 14 nearest
neighbors for perfect BCC crystals. These formulas can be used to
obtain a good cutoff distance:
:c,image(Eqs/cna_cutoff1.jpg)
where a is the lattice constant for the crystal structure concerned
and in the HCP case, x = (c/a) / 1.633, where 1.633 is the ideal c/a
for HCP crystals.
Also note that since the CNA calculation in LAMMPS uses the neighbors
of an owned atom to find the nearest neighbors of a ghost atom, the
following relation should also be satisfied:
:c,image(Eqs/cna_cutoff2.jpg)
where Rc is the cutoff distance of the potential, Rs is the skin
distance as specified by the "neighbor"_neighbor.html command, and
cutoff is the argument used with the compute cna/atom command. LAMMPS
will issue a warning if this is not the case.
The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (e.g. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each with a
{cna/atom} style.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be a number from 0 to 5, as explained
above.
[Restrictions:] none
[Related commands:]
"compute centro/atom"_compute_centro_atom.html
[Default:] none
:line
:link(Faken)
[(Faken)] Faken, Jonsson, Comput Mater Sci, 2, 279 (1994).
:link(Tsuzuki)
[(Tsuzuki)] Tsuzuki, Branicio, Rino, Comput Phys Comm, 177, 518 (2007).
diff --git a/doc/compute_com_molecule.html b/doc/compute_com_molecule.html
index 957b3feca..c5337ec44 100644
--- a/doc/compute_com_molecule.html
+++ b/doc/compute_com_molecule.html
@@ -1,81 +1,81 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute com/molecule command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID com/molecule
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>com/molecule = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 fluid com/molecule
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the center-of-mass of individual
molecules. The calculation includes all effects due to atoms passing
thru periodic boundaries.
</P>
<P>The x,y,z coordinates of the center-of-mass for a particular molecule
are only computed if one or more of its atoms are in the specified
group. Normally all atoms in the molecule should be in the group,
however this is not required. LAMMPS will warn you if this is not the
case. Only atoms in the group contribute to the center-of-mass
calculation for the molecule.
</P>
<P>The ordering of per-molecule quantities produced by this compute is
consistent with the ordering produced by other compute commands that
generate per-molecule datums. Conceptually, them molecule IDs will be
in ascending order for any molecule with one or more of its atoms in
the specified group.
</P>
<P>IMPORTANT NOTE: The coordinates of an atom contribute to the
molecule's center-of-mass in "unwrapped" form, by using the image
flags associated with each atom. See the <A HREF = "dump.html">dump custom</A>
command for a discussion of "unwrapped" coordinates. See the Atoms
section of the <A HREF = "read_data.html">read_data</A> command for a discussion of
image flags and how they are set for each atom. You can reset the
image flags (e.g. to 0) before invoking this compute by using the <A HREF = "set.html">set
image</A> command.
</P>
<P>IMPORTANT NOTE: If an atom is part of a rigid body (see the <A HREF = "fix_rigid.html">fix
rigid</A> command), it's periodic image flags are altered,
and its contribution to the center-of-mass may not reflect its true
contribution. See the <A HREF = "fix_rigid.html">fix rigid</A> command for details.
Thus, to compute the center-of-mass of rigid bodies as they cross
periodic boundaries, you will need to post-process a <A HREF = "dump.html">dump
file</A> containing coordinates of the atoms in the bodies.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global array where the number of rows =
Nmolecules and the number of columns = 3 for the x,y,z center-of-mass
coordinates of each molecule. These values can be accessed by any
command that uses global array values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The array values are "intensive". The array values will be in
distance <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_com.html">compute com</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_com_molecule.txt b/doc/compute_com_molecule.txt
index accfd389c..29ef45413 100644
--- a/doc/compute_com_molecule.txt
+++ b/doc/compute_com_molecule.txt
@@ -1,76 +1,76 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute com/molecule command :h3
[Syntax:]
compute ID group-ID com/molecule :pre
ID, group-ID are documented in "compute"_compute.html command
com/molecule = style name of this compute command :ul
[Examples:]
compute 1 fluid com/molecule :pre
[Description:]
Define a computation that calculates the center-of-mass of individual
molecules. The calculation includes all effects due to atoms passing
thru periodic boundaries.
The x,y,z coordinates of the center-of-mass for a particular molecule
are only computed if one or more of its atoms are in the specified
group. Normally all atoms in the molecule should be in the group,
however this is not required. LAMMPS will warn you if this is not the
case. Only atoms in the group contribute to the center-of-mass
calculation for the molecule.
The ordering of per-molecule quantities produced by this compute is
consistent with the ordering produced by other compute commands that
generate per-molecule datums. Conceptually, them molecule IDs will be
in ascending order for any molecule with one or more of its atoms in
the specified group.
IMPORTANT NOTE: The coordinates of an atom contribute to the
molecule's center-of-mass in "unwrapped" form, by using the image
flags associated with each atom. See the "dump custom"_dump.html
command for a discussion of "unwrapped" coordinates. See the Atoms
section of the "read_data"_read_data.html command for a discussion of
image flags and how they are set for each atom. You can reset the
image flags (e.g. to 0) before invoking this compute by using the "set
image"_set.html command.
IMPORTANT NOTE: If an atom is part of a rigid body (see the "fix
rigid"_fix_rigid.html command), it's periodic image flags are altered,
and its contribution to the center-of-mass may not reflect its true
contribution. See the "fix rigid"_fix_rigid.html command for details.
Thus, to compute the center-of-mass of rigid bodies as they cross
periodic boundaries, you will need to post-process a "dump
file"_dump.html containing coordinates of the atoms in the bodies.
[Output info:]
This compute calculates a global array where the number of rows =
Nmolecules and the number of columns = 3 for the x,y,z center-of-mass
coordinates of each molecule. These values can be accessed by any
command that uses global array values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The array values are "intensive". The array values will be in
distance "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute com"_compute_com.html
[Default:] none
diff --git a/doc/compute_coord_atom.html b/doc/compute_coord_atom.html
index 57738b4f3..bd4c55d2c 100644
--- a/doc/compute_coord_atom.html
+++ b/doc/compute_coord_atom.html
@@ -1,63 +1,63 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute coord/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID coord/atom cutoff
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>coord/atom = style name of this compute command
<LI>cutoff = distance within which to count coordination neighbors (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all coord/atom 2.0
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the coordination number for each
atom in a group.
</P>
<P>The value of the coordination number will be 0.0 for atoms not in the
specified compute group.
</P>
<P>The coordination number is defined as the number of neighbor atoms
within the specified cutoff distance from the central atom. Atoms not
in the group are included in the coordination number of atoms in the
group.
</P>
<P>The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of a
<I>coord/atom</I> style.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be a number >= 0.0, as explained
above.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_cluster_atom.html">compute cluster/atom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_coord_atom.txt b/doc/compute_coord_atom.txt
index fc5f2c900..5fdbd9106 100644
--- a/doc/compute_coord_atom.txt
+++ b/doc/compute_coord_atom.txt
@@ -1,58 +1,58 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute coord/atom command :h3
[Syntax:]
compute ID group-ID coord/atom cutoff :pre
ID, group-ID are documented in "compute"_compute.html command
coord/atom = style name of this compute command
cutoff = distance within which to count coordination neighbors (distance units) :ul
[Examples:]
compute 1 all coord/atom 2.0 :pre
[Description:]
Define a computation that calculates the coordination number for each
atom in a group.
The value of the coordination number will be 0.0 for atoms not in the
specified compute group.
The coordination number is defined as the number of neighbor atoms
within the specified cutoff distance from the central atom. Atoms not
in the group are included in the coordination number of atoms in the
group.
The neighbor list needed to compute this quantity is constructed each
time the calculation is performed (i.e. each time a snapshot of atoms
is dumped). Thus it can be inefficient to compute/dump this quantity
too frequently or to have multiple compute/dump commands, each of a
{coord/atom} style.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be a number >= 0.0, as explained
above.
[Restrictions:] none
[Related commands:]
"compute cluster/atom"_compute_cluster_atom.html
[Default:] none
diff --git a/doc/compute_damage_atom.html b/doc/compute_damage_atom.html
index b5e0d03d8..0d0e378f5 100644
--- a/doc/compute_damage_atom.html
+++ b/doc/compute_damage_atom.html
@@ -1,58 +1,58 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute damage/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID damage/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>damage/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all damage/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom damage for each atom
in a group. Please see the <A HREF = "http://www.sandia.gov/~mlparks/papers/PDLAMMPS.pdf">PDLAMMPS user
guide</A> for a formal
definition of "damage" and more details about Peridynamics as it is
implemented in LAMMPS.
</P>
<P>The value of the damage will be 0.0 for atoms not in the specified
compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be a number >= 0.0, as explained
above.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the PERI package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_damage_atom.txt b/doc/compute_damage_atom.txt
index 104cf22b5..3c640d61e 100644
--- a/doc/compute_damage_atom.txt
+++ b/doc/compute_damage_atom.txt
@@ -1,53 +1,53 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute damage/atom command :h3
[Syntax:]
compute ID group-ID damage/atom :pre
ID, group-ID are documented in "compute"_compute.html command
damage/atom = style name of this compute command :ul
[Examples:]
compute 1 all damage/atom :pre
[Description:]
Define a computation that calculates the per-atom damage for each atom
in a group. Please see the "PDLAMMPS user
guide"_http://www.sandia.gov/~mlparks/papers/PDLAMMPS.pdf for a formal
definition of "damage" and more details about Peridynamics as it is
implemented in LAMMPS.
The value of the damage will be 0.0 for atoms not in the specified
compute group.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be a number >= 0.0, as explained
above.
[Restrictions:]
This compute is part of the PERI package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_displace_atom.html b/doc/compute_displace_atom.html
index 79dae1562..2070d896a 100644
--- a/doc/compute_displace_atom.html
+++ b/doc/compute_displace_atom.html
@@ -1,93 +1,94 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute displace/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID displace/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>displace/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all displace/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the current displacement of each
atom in the group from its original coordinates, including all effects
due to atoms passing thru periodic boundaries.
</P>
<P>A vector of four quantites per atom is calculated by this compute.
The first 3 elements of the vector are the dx,dy,dz displacements.
The 4th component is the total displacement, i.e. sqrt(dx*dx + dy*dy +
dz*dz).
</P>
<P>The displacement of an atom is from its original position at the time
the compute command was issued. To store the original coordinates,
the compute creates its own fix of style "store/state", as if this
command had been issued:
</P>
<PRE>fix compute-ID_store_state group-ID store/state xu yu zu
</PRE>
<P>See the <A HREF = "fix_store_state.html">fix store/state</A> command for details.
Note that the ID of the new fix is the compute-ID + underscore +
"store/state", and the group for the new fix is the same as the
compute group.
</P>
<P>The value of the displacement will be 0.0 for atoms not in the
specified compute group.
</P>
<P>IMPORTANT NOTE: Fix store/state stores the initial coordinates in
"unwrapped" form, by using the image flags associated with each atom.
See the <A HREF = "dump.html">dump custom</A> command for a discussion of
"unwrapped" coordinates. See the Atoms section of the
<A HREF = "read_data.html">read_data</A> command for a discussion of image flags and
how they are set for each atom. You can reset the image flags
(e.g. to 0) before invoking this compute by using the <A HREF = "set.html">set
image</A> command.
</P>
<P>IMPORTANT NOTE: If an atom is part of a rigid body (see the <A HREF = "fix_rigid.html">fix
rigid</A> command), it's periodic image flags are altered,
and the computed displacement may not reflect its true displacement.
See the <A HREF = "fix_rigid.html">fix rigid</A> command for details. Thus, to
compute the displacement of rigid bodies as they cross periodic
boundaries, you will need to post-process a <A HREF = "dump.html">dump file</A>
containing coordinates of the atoms in the bodies.
</P>
<P>IMPORTANT NOTE: If you want the quantities calculated by this compute
to be continuous when running from a <A HREF = "read_restart.html">restart file</A>,
then you should use the same ID for this compute, as in the original
run. This is so that the created fix will also have the same ID, and
thus be initialized correctly with atom coordinates from the restart
file.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom array with 4 columns, which can be
accessed by indices 1-4 by any command that uses per-atom values from
-a compute as input. See <A HREF = "Section_howto.html#howto_15">this section</A>
-for an overview of LAMMPS output options.
+a compute as input. See <A HREF = "Section_howto.html#howto_15">Section_howto
+15</A> for an overview of LAMMPS output
+options.
</P>
<P>The per-atom array values will be in distance <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_msd.html">compute msd</A>, <A HREF = "dump.html">dump custom</A>, <A HREF = "fix_store_state.html">fix
store/state</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_displace_atom.txt b/doc/compute_displace_atom.txt
index ecbdf22b3..5b7363db9 100644
--- a/doc/compute_displace_atom.txt
+++ b/doc/compute_displace_atom.txt
@@ -1,88 +1,89 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute displace/atom command :h3
[Syntax:]
compute ID group-ID displace/atom :pre
ID, group-ID are documented in "compute"_compute.html command
displace/atom = style name of this compute command :ul
[Examples:]
compute 1 all displace/atom :pre
[Description:]
Define a computation that calculates the current displacement of each
atom in the group from its original coordinates, including all effects
due to atoms passing thru periodic boundaries.
A vector of four quantites per atom is calculated by this compute.
The first 3 elements of the vector are the dx,dy,dz displacements.
The 4th component is the total displacement, i.e. sqrt(dx*dx + dy*dy +
dz*dz).
The displacement of an atom is from its original position at the time
the compute command was issued. To store the original coordinates,
the compute creates its own fix of style "store/state", as if this
command had been issued:
fix compute-ID_store_state group-ID store/state xu yu zu :pre
See the "fix store/state"_fix_store_state.html command for details.
Note that the ID of the new fix is the compute-ID + underscore +
"store/state", and the group for the new fix is the same as the
compute group.
The value of the displacement will be 0.0 for atoms not in the
specified compute group.
IMPORTANT NOTE: Fix store/state stores the initial coordinates in
"unwrapped" form, by using the image flags associated with each atom.
See the "dump custom"_dump.html command for a discussion of
"unwrapped" coordinates. See the Atoms section of the
"read_data"_read_data.html command for a discussion of image flags and
how they are set for each atom. You can reset the image flags
(e.g. to 0) before invoking this compute by using the "set
image"_set.html command.
IMPORTANT NOTE: If an atom is part of a rigid body (see the "fix
rigid"_fix_rigid.html command), it's periodic image flags are altered,
and the computed displacement may not reflect its true displacement.
See the "fix rigid"_fix_rigid.html command for details. Thus, to
compute the displacement of rigid bodies as they cross periodic
boundaries, you will need to post-process a "dump file"_dump.html
containing coordinates of the atoms in the bodies.
IMPORTANT NOTE: If you want the quantities calculated by this compute
to be continuous when running from a "restart file"_read_restart.html,
then you should use the same ID for this compute, as in the original
run. This is so that the created fix will also have the same ID, and
thus be initialized correctly with atom coordinates from the restart
file.
[Output info:]
This compute calculates a per-atom array with 4 columns, which can be
accessed by indices 1-4 by any command that uses per-atom values from
-a compute as input. See "this section"_Section_howto.html#howto_15
-for an overview of LAMMPS output options.
+a compute as input. See "Section_howto
+15"_Section_howto.html#howto_15 for an overview of LAMMPS output
+options.
The per-atom array values will be in distance "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute msd"_compute_msd.html, "dump custom"_dump.html, "fix
store/state"_fix_store_state.html
[Default:] none
diff --git a/doc/compute_erotate_asphere.html b/doc/compute_erotate_asphere.html
index 161aef27c..8ea9a4e1d 100644
--- a/doc/compute_erotate_asphere.html
+++ b/doc/compute_erotate_asphere.html
@@ -1,75 +1,75 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute erotate/asphere command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID erotate/asphere
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>erotate/asphere = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all erotate/asphere
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the rotational kinetic energy of
a group of aspherical particles. The aspherical particles can be
ellipsoids, or line segments, or triangles. See the
<A HREF = "atom_style.html">atom_style</A> and <A HREF = "read_data.html">read_data</A> commands
for descriptions of these options.
</P>
<P>For all 3 types of particles, the rotational kinetic energy is
computed as 1/2 I w^2, where I is the inertia tensor for the
aspherical particle and w is its angular velocity, which is computed
from its angular momentum if needed.
</P>
<P>IMPORTANT NOTE: For <A HREF = "dimension.html">2d models</A>, ellipsoidal particles
are treated as ellipsoids, not ellipses, meaning their moments of
inertia will be the same as in 3d.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "extensive". The
scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute requires that ellipsoidal particles atoms store a shape
and quaternion orientation and angular momentum as defined by the
<A HREF = "atom_style.html">atom_style ellipsoid</A> command.
</P>
<P>This compute requires that line segment particles atoms store a length
and orientation and angular velocity as defined by the <A HREF = "atom_style.html">atom_style
line</A> command.
</P>
<P>This compute requires that triangular particles atoms store a size and
shape and quaternion orientation and angular momentum as defined by
the <A HREF = "atom_style.html">atom_style tri</A> command.
</P>
<P>All particles in the group must be finite-size. They cannot be point
particles.
</P>
<P><B>Related commands:</B> none
</P>
<P><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_erotate_asphere.txt b/doc/compute_erotate_asphere.txt
index 39aded0ed..a6a14cfa0 100644
--- a/doc/compute_erotate_asphere.txt
+++ b/doc/compute_erotate_asphere.txt
@@ -1,70 +1,70 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute erotate/asphere command :h3
[Syntax:]
compute ID group-ID erotate/asphere :pre
ID, group-ID are documented in "compute"_compute.html command
erotate/asphere = style name of this compute command :ul
[Examples:]
compute 1 all erotate/asphere :pre
[Description:]
Define a computation that calculates the rotational kinetic energy of
a group of aspherical particles. The aspherical particles can be
ellipsoids, or line segments, or triangles. See the
"atom_style"_atom_style.html and "read_data"_read_data.html commands
for descriptions of these options.
For all 3 types of particles, the rotational kinetic energy is
computed as 1/2 I w^2, where I is the inertia tensor for the
aspherical particle and w is its angular velocity, which is computed
from its angular momentum if needed.
IMPORTANT NOTE: For "2d models"_dimension.html, ellipsoidal particles
are treated as ellipsoids, not ellipses, meaning their moments of
inertia will be the same as in 3d.
[Output info:]
This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "extensive". The
scalar value will be in energy "units"_units.html.
[Restrictions:]
This compute requires that ellipsoidal particles atoms store a shape
and quaternion orientation and angular momentum as defined by the
"atom_style ellipsoid"_atom_style.html command.
This compute requires that line segment particles atoms store a length
and orientation and angular velocity as defined by the "atom_style
line"_atom_style.html command.
This compute requires that triangular particles atoms store a size and
shape and quaternion orientation and angular momentum as defined by
the "atom_style tri"_atom_style.html command.
All particles in the group must be finite-size. They cannot be point
particles.
[Related commands:] none
"compute erotate/sphere"_compute_erotate_sphere.html
[Default:] none
diff --git a/doc/compute_erotate_sphere.html b/doc/compute_erotate_sphere.html
index d9e328364..eb6662b13 100644
--- a/doc/compute_erotate_sphere.html
+++ b/doc/compute_erotate_sphere.html
@@ -1,62 +1,62 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute erotate/sphere command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID erotate/sphere
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>erotate/sphere = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all erotate/sphere
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the rotational kinetic energy of
a group of spherical particles.
</P>
<P>The rotational energy is computed as 1/2 I w^2, where I is the moment
of inertia for a sphere and w is the particle's angular velocity.
</P>
<P>IMPORTANT NOTE: For <A HREF = "dimension.html">2d models</A>, particles are treated
as spheres, not disks, meaning their moment of inertia will be the
same as in 3d.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "extensive". The
scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute requires that atoms store a radius and angular velocity
(omega) as defined by the <A HREF = "atom_style.html">atom_style sphere</A> command.
</P>
<P>All particles in the group must be finite-size spheres or point
particles. They cannot be aspherical. Point particles will not
contribute to the rotational energy.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_erotate_asphere.html">compute erotate/asphere</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_erotate_sphere.txt b/doc/compute_erotate_sphere.txt
index 7e480a281..eaf2eede1 100644
--- a/doc/compute_erotate_sphere.txt
+++ b/doc/compute_erotate_sphere.txt
@@ -1,57 +1,57 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute erotate/sphere command :h3
[Syntax:]
compute ID group-ID erotate/sphere :pre
ID, group-ID are documented in "compute"_compute.html command
erotate/sphere = style name of this compute command :ul
[Examples:]
compute 1 all erotate/sphere :pre
[Description:]
Define a computation that calculates the rotational kinetic energy of
a group of spherical particles.
The rotational energy is computed as 1/2 I w^2, where I is the moment
of inertia for a sphere and w is the particle's angular velocity.
IMPORTANT NOTE: For "2d models"_dimension.html, particles are treated
as spheres, not disks, meaning their moment of inertia will be the
same as in 3d.
[Output info:]
This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "extensive". The
scalar value will be in energy "units"_units.html.
[Restrictions:]
This compute requires that atoms store a radius and angular velocity
(omega) as defined by the "atom_style sphere"_atom_style.html command.
All particles in the group must be finite-size spheres or point
particles. They cannot be aspherical. Point particles will not
contribute to the rotational energy.
[Related commands:]
"compute erotate/asphere"_compute_erotate_asphere.html
[Default:] none
diff --git a/doc/compute_event_displace.html b/doc/compute_event_displace.html
index ae63a96bb..8efff145a 100644
--- a/doc/compute_event_displace.html
+++ b/doc/compute_event_displace.html
@@ -1,67 +1,67 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute event/displace command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID event/displace threshold
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>event/displace = style name of this compute command
<LI>threshold = minimum distance anyparticle must move to trigger an event (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all event/displace 0.5
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that flags an "event" if any particle in the
group has moved a distance greater than the specified threshold
distance when compared to a previously stored reference state
(i.e. the previous event). This compute is typically used in
conjunction with the <A HREF = "prd.html">prd</A> and <A HREF = "tad.html">tad</A> commands,
to detect if a transition
to a new minimum energy basin has occurred.
</P>
<P>This value calculated by the compute is equal to 0 if no particle has
moved far enough, and equal to 1 if one or more particles have moved
further than the threshold distance.
</P>
<P>NOTE: If the system is undergoing significant center-of-mass motion,
due to thermal motion, an external force, or an initial net momentum,
then this compute will not be able to distinguish that motion from
local atom displacements and may generate "false postives."
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the flag). This value can be
used by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "intensive". The
scalar value will be a 0 or 1 as explained above.
</P>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "prd.html">prd</A>, <A HREF = "tad.html">tad</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_event_displace.txt b/doc/compute_event_displace.txt
index 7b26d3120..4d638c74f 100644
--- a/doc/compute_event_displace.txt
+++ b/doc/compute_event_displace.txt
@@ -1,62 +1,62 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute event/displace command :h3
[Syntax:]
compute ID group-ID event/displace threshold :pre
ID, group-ID are documented in "compute"_compute.html command
event/displace = style name of this compute command
threshold = minimum distance anyparticle must move to trigger an event (distance units) :ul
[Examples:]
compute 1 all event/displace 0.5 :pre
[Description:]
Define a computation that flags an "event" if any particle in the
group has moved a distance greater than the specified threshold
distance when compared to a previously stored reference state
(i.e. the previous event). This compute is typically used in
conjunction with the "prd"_prd.html and "tad"_tad.html commands,
to detect if a transition
to a new minimum energy basin has occurred.
This value calculated by the compute is equal to 0 if no particle has
moved far enough, and equal to 1 if one or more particles have moved
further than the threshold distance.
NOTE: If the system is undergoing significant center-of-mass motion,
due to thermal motion, an external force, or an initial net momentum,
then this compute will not be able to distinguish that motion from
local atom displacements and may generate "false postives."
[Output info:]
This compute calculates a global scalar (the flag). This value can be
used by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "intensive". The
scalar value will be a 0 or 1 as explained above.
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"prd"_prd.html, "tad"_tad.html
[Default:] none
diff --git a/doc/compute_gyration.html b/doc/compute_gyration.html
index 1d8b8389c..79994c6df 100644
--- a/doc/compute_gyration.html
+++ b/doc/compute_gyration.html
@@ -1,66 +1,66 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute gyration command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID gyration
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>gyration = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 molecule gyration
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the radius of gyration Rg of the
group of atoms, including all effects due to atoms passing thru
periodic boundaries.
</P>
<P>Rg is a measure of the size of the group of atoms, and is computed by
this formula
</P>
<CENTER><IMG SRC = "Eqs/compute_gyration.jpg">
</CENTER>
<P>where M is the total mass of the group, Rcm is the center-of-mass
position of the group, and the sum is over all atoms in the group.
</P>
<P>IMPORTANT NOTE: The coordinates of an atom contribute to Rg in
"unwrapped" form, by using the image flags associated with each atom.
See the <A HREF = "dump.html">dump custom</A> command for a discussion of
"unwrapped" coordinates. See the Atoms section of the
<A HREF = "read_data.html">read_data</A> command for a discussion of image flags and
how they are set for each atom. You can reset the image flags
(e.g. to 0) before invoking this compute by using the <A HREF = "set.html">set
image</A> command.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (Rg). This value can be used
by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "intensive". The
scalar value will be in distance <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_gyration_molecule.html">compute gyration/molecule</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_gyration.txt b/doc/compute_gyration.txt
index 867669d0a..2cc818c5f 100644
--- a/doc/compute_gyration.txt
+++ b/doc/compute_gyration.txt
@@ -1,61 +1,61 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute gyration command :h3
[Syntax:]
compute ID group-ID gyration :pre
ID, group-ID are documented in "compute"_compute.html command
gyration = style name of this compute command :ul
[Examples:]
compute 1 molecule gyration :pre
[Description:]
Define a computation that calculates the radius of gyration Rg of the
group of atoms, including all effects due to atoms passing thru
periodic boundaries.
Rg is a measure of the size of the group of atoms, and is computed by
this formula
:c,image(Eqs/compute_gyration.jpg)
where M is the total mass of the group, Rcm is the center-of-mass
position of the group, and the sum is over all atoms in the group.
IMPORTANT NOTE: The coordinates of an atom contribute to Rg in
"unwrapped" form, by using the image flags associated with each atom.
See the "dump custom"_dump.html command for a discussion of
"unwrapped" coordinates. See the Atoms section of the
"read_data"_read_data.html command for a discussion of image flags and
how they are set for each atom. You can reset the image flags
(e.g. to 0) before invoking this compute by using the "set
image"_set.html command.
[Output info:]
This compute calculates a global scalar (Rg). This value can be used
by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "intensive". The
scalar value will be in distance "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute gyration/molecule"_compute_gyration_molecule.html
[Default:] none
diff --git a/doc/compute_ke.html b/doc/compute_ke.html
index 12769e0f5..b71d9e306 100644
--- a/doc/compute_ke.html
+++ b/doc/compute_ke.html
@@ -1,64 +1,64 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ke command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID ke
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ke = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ke
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the translational kinetic energy
of a group of particles.
</P>
<P>The kinetic energy or each particle is computed as 1/2 m v^2, where m
and v are the mass and velocity of the particle.
</P>
<P>There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the <I>ke</I> or <I>etotal</I>
keyword used in thermodynamic output, as specified by the
<A HREF = "thermo_style.html">thermo_style</A> command. For this compute, kinetic
energy is "translational" kinetic energy, calculated by the simple
formula above. For thermodynamic output, the <I>ke</I> keyword infers
kinetic energy from the temperature of the system with 1/2 Kb T of
energy for each degree of freedom. For the default temperature
computation via the <A HREF = "compute_temp.html">compute temp</A> command, these
are the same. But different computes that calculate temperature can
subtract out different non-thermal components of velocity and/or
include different degrees of freedom (translational, rotational, etc).
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "extensive". The
scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_ke.txt b/doc/compute_ke.txt
index 003332c07..cd84381d3 100644
--- a/doc/compute_ke.txt
+++ b/doc/compute_ke.txt
@@ -1,59 +1,59 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ke command :h3
[Syntax:]
compute ID group-ID ke :pre
ID, group-ID are documented in "compute"_compute.html command
ke = style name of this compute command :ul
[Examples:]
compute 1 all ke :pre
[Description:]
Define a computation that calculates the translational kinetic energy
of a group of particles.
The kinetic energy or each particle is computed as 1/2 m v^2, where m
and v are the mass and velocity of the particle.
There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the {ke} or {etotal}
keyword used in thermodynamic output, as specified by the
"thermo_style"_thermo_style.html command. For this compute, kinetic
energy is "translational" kinetic energy, calculated by the simple
formula above. For thermodynamic output, the {ke} keyword infers
kinetic energy from the temperature of the system with 1/2 Kb T of
energy for each degree of freedom. For the default temperature
computation via the "compute temp"_compute_temp.html command, these
are the same. But different computes that calculate temperature can
subtract out different non-thermal components of velocity and/or
include different degrees of freedom (translational, rotational, etc).
[Output info:]
This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "extensive". The
scalar value will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute erotate/sphere"_compute_erotate_sphere.html
[Default:] none
diff --git a/doc/compute_ke_atom.html b/doc/compute_ke_atom.html
index 434718e6a..fdf97f197 100644
--- a/doc/compute_ke_atom.html
+++ b/doc/compute_ke_atom.html
@@ -1,53 +1,53 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ke/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID ke/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ke/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ke/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom translational
kinetic energy for each atom in a group.
</P>
<P>The kinetic energy is simply 1/2 m v^2, where m is the mass and v is
the velocity of each atom.
</P>
<P>The value of the kinetic energy will be 0.0 for atoms not in the
specified compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_ke_atom.txt b/doc/compute_ke_atom.txt
index fd4265130..66abf81a5 100644
--- a/doc/compute_ke_atom.txt
+++ b/doc/compute_ke_atom.txt
@@ -1,48 +1,48 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ke/atom command :h3
[Syntax:]
compute ID group-ID ke/atom :pre
ID, group-ID are documented in "compute"_compute.html command
ke/atom = style name of this compute command :ul
[Examples:]
compute 1 all ke/atom :pre
[Description:]
Define a computation that calculates the per-atom translational
kinetic energy for each atom in a group.
The kinetic energy is simply 1/2 m v^2, where m is the mass and v is
the velocity of each atom.
The value of the kinetic energy will be 0.0 for atoms not in the
specified compute group.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_ke_atom_eff.html b/doc/compute_ke_atom_eff.html
index 19ffb3f77..d305890bb 100644
--- a/doc/compute_ke_atom_eff.html
+++ b/doc/compute_ke_atom_eff.html
@@ -1,82 +1,82 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ke/atom/eff command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID ke/atom/eff
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ke/atom/eff = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ke/atom/eff
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom translational
(nuclei and electrons) and radial kinetic energy (electron only) in a
group. The particles are assumed to be nuclei and electrons modeled
with the <A HREF = "pair_eff.html">electronic force field</A>.
</P>
<P>The kinetic energy for each nucleus is computed as 1/2 m v^2, where m
corresponds to the corresponding nuclear mass, and the kinetic energy
for each electron is computed as 1/2 (me v^2 + 3/4 me s^2), where me
and v correspond to the mass and translational velocity of each
electron, and s to its radial velocity, respectively.
</P>
<P>There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the <I>ke</I> or <I>etotal</I>
keyword used in thermodynamic output, as specified by the
<A HREF = "thermo_style.html">thermo_style</A> command. For this compute, kinetic
energy is "translational" plus electronic "radial" kinetic energy,
calculated by the simple formula above. For thermodynamic output, the
<I>ke</I> keyword infers kinetic energy from the temperature of the system
with 1/2 Kb T of energy for each (nuclear-only) degree of freedom in
eFF.
</P>
<P>IMPORTANT NOTE: The temperature in eFF should be monitored via the
<A HREF = "compute_temp_eff.html">compute temp/eff</A> command, which can be printed
with thermodynamic output by using the
<A HREF = "thermo_modify.html">thermo_modify</A> command, as shown in the following
example:
</P>
<PRE>compute effTemp all temp/eff
thermo_style custom step etotal pe ke temp press
thermo_modify temp effTemp
</PRE>
<P>The value of the kinetic energy will be 0.0 for atoms (nuclei or
electrons) not in the specified compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a scalar quantity for each atom, which can be
accessed by any command that uses per-atom computes as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-EFF package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_ke_atom_eff.txt b/doc/compute_ke_atom_eff.txt
index 00c32be62..736c38677 100644
--- a/doc/compute_ke_atom_eff.txt
+++ b/doc/compute_ke_atom_eff.txt
@@ -1,77 +1,77 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ke/atom/eff command :h3
[Syntax:]
compute ID group-ID ke/atom/eff :pre
ID, group-ID are documented in "compute"_compute.html command
ke/atom/eff = style name of this compute command :ul
[Examples:]
compute 1 all ke/atom/eff :pre
[Description:]
Define a computation that calculates the per-atom translational
(nuclei and electrons) and radial kinetic energy (electron only) in a
group. The particles are assumed to be nuclei and electrons modeled
with the "electronic force field"_pair_eff.html.
The kinetic energy for each nucleus is computed as 1/2 m v^2, where m
corresponds to the corresponding nuclear mass, and the kinetic energy
for each electron is computed as 1/2 (me v^2 + 3/4 me s^2), where me
and v correspond to the mass and translational velocity of each
electron, and s to its radial velocity, respectively.
There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the {ke} or {etotal}
keyword used in thermodynamic output, as specified by the
"thermo_style"_thermo_style.html command. For this compute, kinetic
energy is "translational" plus electronic "radial" kinetic energy,
calculated by the simple formula above. For thermodynamic output, the
{ke} keyword infers kinetic energy from the temperature of the system
with 1/2 Kb T of energy for each (nuclear-only) degree of freedom in
eFF.
IMPORTANT NOTE: The temperature in eFF should be monitored via the
"compute temp/eff"_compute_temp_eff.html command, which can be printed
with thermodynamic output by using the
"thermo_modify"_thermo_modify.html command, as shown in the following
example:
compute effTemp all temp/eff
thermo_style custom step etotal pe ke temp press
thermo_modify temp effTemp :pre
The value of the kinetic energy will be 0.0 for atoms (nuclei or
electrons) not in the specified compute group.
[Output info:]
This compute calculates a scalar quantity for each atom, which can be
accessed by any command that uses per-atom computes as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in energy "units"_units.html.
[Restrictions:]
This compute is part of the USER-EFF package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_ke_eff.html b/doc/compute_ke_eff.html
index 2fa318f8a..7c476b9aa 100644
--- a/doc/compute_ke_eff.html
+++ b/doc/compute_ke_eff.html
@@ -1,83 +1,83 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ke/eff command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID ke/eff
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ke/eff = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ke/eff
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the kinetic energy of motion of a
group of eFF particles (nuclei and electrons), as modeled with the
<A HREF = "pair_eff.html">electronic force field</A>.
</P>
<P>The kinetic energy for each nucleus is computed as 1/2 m v^2 and the
kinetic energy for each electron is computed as 1/2(me v^2 + 3/4 me
s^2), where m corresponds to the nuclear mass, me to the electron
mass, v to the translational velocity of each particle, and s to the
radial velocity of the electron, respectively.
</P>
<P>There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the <I>ke</I> or <I>etotal</I>
keyword used in thermodynamic output, as specified by the
<A HREF = "thermo_style.html">thermo_style</A> command. For this compute, kinetic
energy is "translational" and "radial" (only for electrons) kinetic
energy, calculated by the simple formula above. For thermodynamic
output, the <I>ke</I> keyword infers kinetic energy from the temperature of
the system with 1/2 Kb T of energy for each degree of freedom. For
the eFF temperature computation via the <A HREF = "compute_temp_eff.html">compute
temp_eff</A> command, these are the same. But
different computes that calculate temperature can subtract out
different non-thermal components of velocity and/or include other
degrees of freedom.
</P>
<P>IMPRORTANT NOTE: The temperature in eFF models should be monitored via
the <A HREF = "compute_temp_eff.html">compute temp/eff</A> command, which can be
printed with thermodynamic output by using the
<A HREF = "thermo_modify.html">thermo_modify</A> command, as shown in the following
example:
</P>
<PRE>compute effTemp all temp/eff
thermo_style custom step etotal pe ke temp press
thermo_modify temp effTemp
</PRE>
<P>See <A HREF = "compute_temp_eff.html">compute temp/eff</A>.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See <A HREF = "Section_howto.html#howto_15">this section</A> for an overview
-of LAMMPS output options.
+input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an
+overview of LAMMPS output options.
</P>
<P>The scalar value calculated by this compute is "extensive". The
scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-EFF package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B> none
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_ke_eff.txt b/doc/compute_ke_eff.txt
index 2ebe435df..61c46d337 100644
--- a/doc/compute_ke_eff.txt
+++ b/doc/compute_ke_eff.txt
@@ -1,78 +1,78 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ke/eff command :h3
[Syntax:]
compute ID group-ID ke/eff :pre
ID, group-ID are documented in "compute"_compute.html command
ke/eff = style name of this compute command :ul
[Examples:]
compute 1 all ke/eff :pre
[Description:]
Define a computation that calculates the kinetic energy of motion of a
group of eFF particles (nuclei and electrons), as modeled with the
"electronic force field"_pair_eff.html.
The kinetic energy for each nucleus is computed as 1/2 m v^2 and the
kinetic energy for each electron is computed as 1/2(me v^2 + 3/4 me
s^2), where m corresponds to the nuclear mass, me to the electron
mass, v to the translational velocity of each particle, and s to the
radial velocity of the electron, respectively.
There is a subtle difference between the quantity calculated by this
compute and the kinetic energy calculated by the {ke} or {etotal}
keyword used in thermodynamic output, as specified by the
"thermo_style"_thermo_style.html command. For this compute, kinetic
energy is "translational" and "radial" (only for electrons) kinetic
energy, calculated by the simple formula above. For thermodynamic
output, the {ke} keyword infers kinetic energy from the temperature of
the system with 1/2 Kb T of energy for each degree of freedom. For
the eFF temperature computation via the "compute
temp_eff"_compute_temp_eff.html command, these are the same. But
different computes that calculate temperature can subtract out
different non-thermal components of velocity and/or include other
degrees of freedom.
IMPRORTANT NOTE: The temperature in eFF models should be monitored via
the "compute temp/eff"_compute_temp_eff.html command, which can be
printed with thermodynamic output by using the
"thermo_modify"_thermo_modify.html command, as shown in the following
example:
compute effTemp all temp/eff
thermo_style custom step etotal pe ke temp press
thermo_modify temp effTemp :pre
See "compute temp/eff"_compute_temp_eff.html.
[Output info:]
This compute calculates a global scalar (the KE). This value can be
used by any command that uses a global scalar value from a compute as
-input. See "this section"_Section_howto.html#howto_15 for an overview
-of LAMMPS output options.
+input. See "Section_howto 15"_Section_howto.html#howto_15 for an
+overview of LAMMPS output options.
The scalar value calculated by this compute is "extensive". The
scalar value will be in energy "units"_units.html.
[Restrictions:]
This compute is part of the USER-EFF package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:] none
[Default:] none
diff --git a/doc/compute_meso_e_atom.html b/doc/compute_meso_e_atom.html
index 69d903799..3350eb300 100644
--- a/doc/compute_meso_e_atom.html
+++ b/doc/compute_meso_e_atom.html
@@ -1,61 +1,61 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute meso_e/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID meso_e/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>meso_e/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all meso_e/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom internal energy
for each atom in a group.
</P>
<P>The internal energy is the energy associated with the internal degrees
of freedom of a mesoscopic particles, e.g. a Smooth-Particle
Hydrodynamics particle.
</P>
<P>See <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">this PDF guide</A> to using SPH in
LAMMPS.
</P>
<P>The value of the internal energy will be 0.0 for atoms not in the
specified compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#4_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_meso_e_atom.txt b/doc/compute_meso_e_atom.txt
index b85115da4..0cf93ef6e 100644
--- a/doc/compute_meso_e_atom.txt
+++ b/doc/compute_meso_e_atom.txt
@@ -1,56 +1,56 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute meso_e/atom command :h3
[Syntax:]
compute ID group-ID meso_e/atom :pre
ID, group-ID are documented in "compute"_compute.html command
meso_e/atom = style name of this compute command :ul
[Examples:]
compute 1 all meso_e/atom :pre
[Description:]
Define a computation that calculates the per-atom internal energy
for each atom in a group.
The internal energy is the energy associated with the internal degrees
of freedom of a mesoscopic particles, e.g. a Smooth-Particle
Hydrodynamics particle.
See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
LAMMPS.
The value of the internal energy will be 0.0 for atoms not in the
specified compute group.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#4_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in energy "units"_units.html.
[Restrictions:]
This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_meso_rho_atom.html b/doc/compute_meso_rho_atom.html
index 202be3573..790e2f900 100644
--- a/doc/compute_meso_rho_atom.html
+++ b/doc/compute_meso_rho_atom.html
@@ -1,61 +1,61 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute meso_rho/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID meso_rho/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>meso_rho/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all meso_rho/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom mesoscopic density
for each atom in a group.
</P>
<P>The mesoscopic density is the mass density of a mesoscopic particle,
calculated by kernel function interpolation using "pair style
sph/rhosum".
</P>
<P>See <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">this PDF guide</A> to using SPH in
LAMMPS.
</P>
<P>The value of the mesoscopic density will be 0.0 for atoms not in the
specified compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#4_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in mass/volume <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_meso_rho_atom.txt b/doc/compute_meso_rho_atom.txt
index c09581864..5ed9ec86d 100644
--- a/doc/compute_meso_rho_atom.txt
+++ b/doc/compute_meso_rho_atom.txt
@@ -1,56 +1,56 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute meso_rho/atom command :h3
[Syntax:]
compute ID group-ID meso_rho/atom :pre
ID, group-ID are documented in "compute"_compute.html command
meso_rho/atom = style name of this compute command :ul
[Examples:]
compute 1 all meso_rho/atom :pre
[Description:]
Define a computation that calculates the per-atom mesoscopic density
for each atom in a group.
The mesoscopic density is the mass density of a mesoscopic particle,
calculated by kernel function interpolation using "pair style
sph/rhosum".
See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
LAMMPS.
The value of the mesoscopic density will be 0.0 for atoms not in the
specified compute group.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#4_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in mass/volume "units"_units.html.
[Restrictions:]
This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_meso_t_atom.html b/doc/compute_meso_t_atom.html
index dc41ea8d3..39b21ccff 100644
--- a/doc/compute_meso_t_atom.html
+++ b/doc/compute_meso_t_atom.html
@@ -1,63 +1,63 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute meso_t/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID meso_t/atom
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>meso_t/atom = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all meso_t/atom
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the per-atom internal temperature
for each atom in a group.
</P>
<P>The internal temperature is the ratio of internal energy over the heat
capacity associated with the internal degrees of freedom of a mesoscopic
particles, e.g. a Smooth-Particle Hydrodynamics particle.
</P>
<P>T_<I>int</I> = E_<I>int</I> / C_<I>V, int</I>
</P>
<P>See <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">this PDF guide</A> to using SPH in
LAMMPS.
</P>
<P>The value of the internal energy will be 0.0 for atoms not in the
specified compute group.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#4_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in temperature <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump custom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_meso_t_atom.txt b/doc/compute_meso_t_atom.txt
index 1d1a3a12a..cfdd78755 100644
--- a/doc/compute_meso_t_atom.txt
+++ b/doc/compute_meso_t_atom.txt
@@ -1,58 +1,58 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute meso_t/atom command :h3
[Syntax:]
compute ID group-ID meso_t/atom :pre
ID, group-ID are documented in "compute"_compute.html command
meso_t/atom = style name of this compute command :ul
[Examples:]
compute 1 all meso_t/atom :pre
[Description:]
Define a computation that calculates the per-atom internal temperature
for each atom in a group.
The internal temperature is the ratio of internal energy over the heat
capacity associated with the internal degrees of freedom of a mesoscopic
particles, e.g. a Smooth-Particle Hydrodynamics particle.
T_{int} = E_{int} / C_{V, int}
See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
LAMMPS.
The value of the internal energy will be 0.0 for atoms not in the
specified compute group.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#4_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in temperature "units"_units.html.
[Restrictions:]
This compute is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"dump custom"_dump.html
[Default:] none
diff --git a/doc/compute_pair_local.html b/doc/compute_pair_local.html
index 49a9d3780..41cf2f92e 100644
--- a/doc/compute_pair_local.html
+++ b/doc/compute_pair_local.html
@@ -1,100 +1,122 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute pair/local command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID pair/local input1 input2 ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>pair/local = style name of this compute command
<LI>zero or more keywords may be appended
-<LI>keyword = <I>dist</I> or <I>eng</I> or <I>force</I>
+<LI>keyword = <I>dist</I> or <I>eng</I> or <I>force</I> or <I>fx</I> or <I>fy</I> or <I>fz</I> or <I>fN</I>
-<PRE> <I>dist</I> = tabulate pairwise distances
- <I>eng</I> = tablutate pairwise energies
- <I>force</I> = tablutate pairwise forces
+<PRE> <I>dist</I> = pairwise distance
+ <I>eng</I> = pairwise energy
+ <I>force</I> = pairwise force
+ <I>fx</I>,<I>fy</I>,<I>fz</I> = components of pairwise force
+ <I>pN</I> = pair style specific quantities for allowed N values
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all pair/local eng
-compute 1 all pair/local dist eng force
+compute 1 all pair/local dist eng force
+compute 1 all pair/local dist eng fx fy fz
+compute 1 all pair/local dist fx fy fz p1 p2 p3
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates properties of individual pairwise
interactions. The number of datums generated, aggregated across all
processors, equals the number of pairwise interactions in the system.
</P>
<P>The local data stored by this command is generated by looping over the
pairwise neighbor list. Info about an individual pairwise interaction
will only be included if both atoms in the pair are in the specified
compute group, and if the current pairwise distance is less than the
force cutoff distance for that interaction, as defined by the
<A HREF = "pair_style.html">pair_style</A> and <A HREF = "pair_coeff.html">pair_coeff</A>
commands.
</P>
+<P>The output <I>dist</I> is the distance bewteen the pair of atoms.
+</P>
+<P>The output <I>eng</I> is the interaction energy for the pair of atoms.
+</P>
+<P>The output <I>force</I> is the force acting between the pair of atoms,
+which is positive for a repulsive force and negative for an attractive
+force. The outputs <I>fx</I>, <I>fy</I>, and <I>fz</I> are the xyz components of
+<I>force</I> on atom I.
+</P>
+<P>A pair style may define additional pairwise quantities which can be
+accessed as <I>p1</I> to <I>pN</I>, where N is defined by the pair style. Most
+pair styles do not define any additional quantities, so N = 0. An
+example of ones that do are the <A HREF = "pair_gran.html">granular pair styles</A>
+which calculate the tangential force between two particles and return
+its components and magnitude acting on atom I for N = 1,2,3,4. See
+individual pair styles for detils.
+</P>
<P>The output <I>dist</I> will be in distance <A HREF = "units.html">units</A>. The output
-<I>eng</I> will be in energy <A HREF = "units.html">units</A>. The output <I>force</I> will
-be in force <A HREF = "units.html">units</A>.
+<I>eng</I> will be in energy <A HREF = "units.html">units</A>. The outputs <I>force</I>,
+<I>fx</I>, <I>fy</I>, and <I>fz</I> will be in force <A HREF = "units.html">units</A>. The output
+<I>pN</I> will be in whatever units the pair style defines.
</P>
<P>Note that as atoms migrate from processor to processor, there will be
no consistent ordering of the entries within the local vector or array
from one timestep to the next. The only consistency that is
guaranteed is that the ordering on a particular timestep will be the
same for local vectors or arrays generated by other compute commands.
For example, pair output from the <A HREF = "compute_property_local.html">compute
property/local</A> command can be combined
with data from this command and output by the <A HREF = "dump.html">dump local</A>
command in a consistent way.
</P>
<P>IMPORTANT NOTE: For pairs, if two atoms I,J are involved in 1-2, 1-3,
1-4 interactions within the molecular topology, their pairwise
interaction may be turned off, and thus they may not appear in the
neighbor list, and will not be part of the local data created by this
command. More specifically, this may be true of I,J pairs with a
weighting factor of 0.0; pairs with a non-zero weighting factor are
included. The weighting factors for 1-2, 1-3, and 1-4 pairwise
interactions are set by the <A HREF = "special_bonds.html">special_bonds</A>
command.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a local vector or local array depending on the
number of keywords. The length of the vector or number of rows in the
array is the number of pairs. If a single keyword is specified, a
local vector is produced. If two or more keywords are specified, a
local array is produced where the number of columns = the number of
keywords. The vector or array can be accessed by any command that
uses local values from a compute as input. See <A HREF = "Section_howto.html#howto_15">this
section</A> for an overview of LAMMPS output
options.
</P>
<P>The output for <I>dist</I> will be in distance <A HREF = "units.html">units</A>. The
output for <I>eng</I> will be in energy <A HREF = "units.html">units</A>. The output for
<I>force</I> will be in force <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump local</A>, <A HREF = "compute_property_local.html">compute
property/local</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_pair_local.txt b/doc/compute_pair_local.txt
index 7f9f0cb4e..e7b5520ac 100644
--- a/doc/compute_pair_local.txt
+++ b/doc/compute_pair_local.txt
@@ -1,90 +1,112 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute pair/local command :h3
[Syntax:]
compute ID group-ID pair/local input1 input2 ... :pre
ID, group-ID are documented in "compute"_compute.html command :ulb,l
pair/local = style name of this compute command :l
zero or more keywords may be appended :l
-keyword = {dist} or {eng} or {force} :l
- {dist} = tabulate pairwise distances
- {eng} = tablutate pairwise energies
- {force} = tablutate pairwise forces :pre
+keyword = {dist} or {eng} or {force} or {fx} or {fy} or {fz} or {fN} :l
+ {dist} = pairwise distance
+ {eng} = pairwise energy
+ {force} = pairwise force
+ {fx},{fy},{fz} = components of pairwise force
+ {pN} = pair style specific quantities for allowed N values :pre
:ule
[Examples:]
compute 1 all pair/local eng
-compute 1 all pair/local dist eng force :pre
+compute 1 all pair/local dist eng force
+compute 1 all pair/local dist eng fx fy fz
+compute 1 all pair/local dist fx fy fz p1 p2 p3 :pre
[Description:]
Define a computation that calculates properties of individual pairwise
interactions. The number of datums generated, aggregated across all
processors, equals the number of pairwise interactions in the system.
The local data stored by this command is generated by looping over the
pairwise neighbor list. Info about an individual pairwise interaction
will only be included if both atoms in the pair are in the specified
compute group, and if the current pairwise distance is less than the
force cutoff distance for that interaction, as defined by the
"pair_style"_pair_style.html and "pair_coeff"_pair_coeff.html
commands.
+The output {dist} is the distance bewteen the pair of atoms.
+
+The output {eng} is the interaction energy for the pair of atoms.
+
+The output {force} is the force acting between the pair of atoms,
+which is positive for a repulsive force and negative for an attractive
+force. The outputs {fx}, {fy}, and {fz} are the xyz components of
+{force} on atom I.
+
+A pair style may define additional pairwise quantities which can be
+accessed as {p1} to {pN}, where N is defined by the pair style. Most
+pair styles do not define any additional quantities, so N = 0. An
+example of ones that do are the "granular pair styles"_pair_gran.html
+which calculate the tangential force between two particles and return
+its components and magnitude acting on atom I for N = 1,2,3,4. See
+individual pair styles for detils.
+
The output {dist} will be in distance "units"_units.html. The output
-{eng} will be in energy "units"_units.html. The output {force} will
-be in force "units"_units.html.
+{eng} will be in energy "units"_units.html. The outputs {force},
+{fx}, {fy}, and {fz} will be in force "units"_units.html. The output
+{pN} will be in whatever units the pair style defines.
Note that as atoms migrate from processor to processor, there will be
no consistent ordering of the entries within the local vector or array
from one timestep to the next. The only consistency that is
guaranteed is that the ordering on a particular timestep will be the
same for local vectors or arrays generated by other compute commands.
For example, pair output from the "compute
property/local"_compute_property_local.html command can be combined
with data from this command and output by the "dump local"_dump.html
command in a consistent way.
IMPORTANT NOTE: For pairs, if two atoms I,J are involved in 1-2, 1-3,
1-4 interactions within the molecular topology, their pairwise
interaction may be turned off, and thus they may not appear in the
neighbor list, and will not be part of the local data created by this
command. More specifically, this may be true of I,J pairs with a
weighting factor of 0.0; pairs with a non-zero weighting factor are
included. The weighting factors for 1-2, 1-3, and 1-4 pairwise
interactions are set by the "special_bonds"_special_bonds.html
command.
[Output info:]
This compute calculates a local vector or local array depending on the
number of keywords. The length of the vector or number of rows in the
array is the number of pairs. If a single keyword is specified, a
local vector is produced. If two or more keywords are specified, a
local array is produced where the number of columns = the number of
keywords. The vector or array can be accessed by any command that
uses local values from a compute as input. See "this
section"_Section_howto.html#howto_15 for an overview of LAMMPS output
options.
The output for {dist} will be in distance "units"_units.html. The
output for {eng} will be in energy "units"_units.html. The output for
{force} will be in force "units"_units.html.
[Restrictions:] none
[Related commands:]
"dump local"_dump.html, "compute
property/local"_compute_property_local.html
[Default:] none
diff --git a/doc/compute_pe.html b/doc/compute_pe.html
index 96a25eb42..75f44af57 100644
--- a/doc/compute_pe.html
+++ b/doc/compute_pe.html
@@ -1,100 +1,101 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute pe command
</H3>
<H3>compute pe/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID pe keyword ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>pe = style name of this compute command
<LI>zero or more keywords may be appended
<LI>keyword = <I>pair</I> or <I>bond</I> or <I>angle</I> or <I>dihedral</I> or <I>improper</I> or <I>kspace</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all pe
compute molPE all pe bond angle dihedral improper
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the potential energy of the
entire system of atoms. The specified group must be "all". See the
<A HREF = "compute_pe_atom.html">compute pe/atom</A> command if you want per-atom
energies. These per-atom values could be summed for a group of atoms
via the <A HREF = "compute_reduce.html">compute reduce</A> command.
</P>
<P>The energy is calculated by the various pair, bond, etc potentials
defined for the simulation. If no extra keywords are listed, then the
potential energy is the sum of pair, bond, angle, dihedral, improper,
and kspace (long-range) energy. If any extra keywords are listed,
then only those components are summed to compute the potential energy.
</P>
<P>Various fixes can contribute to the total potential energy of the
system. See the doc pages for <A HREF = "fix.html">individual fixes</A> for
details. The <I>thermo</I> option of the
<A HREF = "compute_modify.html">compute_modify</A> command determines whether these
contributions are added into the computed potential energy. If no
keywords are specified the default is <I>yes</I>. If any keywords are
specified, the default is <I>no</I>.
</P>
<P>A compute of this style with the ID of "thermo_pe" is created when
LAMMPS starts up, as if this command were in the input script:
</P>
<PRE>compute thermo_pe all pe
</PRE>
<P>See the "thermo_style" command for more details.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the potential energy). This
value can be used by any command that uses a global scalar value from
-a compute as input. See <A HREF = "Section_howto.html#howto_15">this section</A>
-for an overview of LAMMPS output options.
+a compute as input. See <A HREF = "Section_howto.html#howto_15">Section_howto
+15</A> for an overview of LAMMPS output
+options.
</P>
<P>The scalar value calculated by this compute is "extensive". The
scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_pe_atom.html">compute pe/atom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_pe.txt b/doc/compute_pe.txt
index 46d54268e..e09ad02b3 100644
--- a/doc/compute_pe.txt
+++ b/doc/compute_pe.txt
@@ -1,94 +1,95 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute pe command :h3
compute pe/cuda command :h3
[Syntax:]
compute ID group-ID pe keyword ... :pre
ID, group-ID are documented in "compute"_compute.html command
pe = style name of this compute command
zero or more keywords may be appended
keyword = {pair} or {bond} or {angle} or {dihedral} or {improper} or {kspace} :ul
[Examples:]
compute 1 all pe
compute molPE all pe bond angle dihedral improper :pre
[Description:]
Define a computation that calculates the potential energy of the
entire system of atoms. The specified group must be "all". See the
"compute pe/atom"_compute_pe_atom.html command if you want per-atom
energies. These per-atom values could be summed for a group of atoms
via the "compute reduce"_compute_reduce.html command.
The energy is calculated by the various pair, bond, etc potentials
defined for the simulation. If no extra keywords are listed, then the
potential energy is the sum of pair, bond, angle, dihedral, improper,
and kspace (long-range) energy. If any extra keywords are listed,
then only those components are summed to compute the potential energy.
Various fixes can contribute to the total potential energy of the
system. See the doc pages for "individual fixes"_fix.html for
details. The {thermo} option of the
"compute_modify"_compute_modify.html command determines whether these
contributions are added into the computed potential energy. If no
keywords are specified the default is {yes}. If any keywords are
specified, the default is {no}.
A compute of this style with the ID of "thermo_pe" is created when
LAMMPS starts up, as if this command were in the input script:
compute thermo_pe all pe :pre
See the "thermo_style" command for more details.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Output info:]
This compute calculates a global scalar (the potential energy). This
value can be used by any command that uses a global scalar value from
-a compute as input. See "this section"_Section_howto.html#howto_15
-for an overview of LAMMPS output options.
+a compute as input. See "Section_howto
+15"_Section_howto.html#howto_15 for an overview of LAMMPS output
+options.
The scalar value calculated by this compute is "extensive". The
scalar value will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute pe/atom"_compute_pe_atom.html
[Default:] none
diff --git a/doc/compute_pe_atom.html b/doc/compute_pe_atom.html
index af5f158fc..3e7bc51f4 100644
--- a/doc/compute_pe_atom.html
+++ b/doc/compute_pe_atom.html
@@ -1,87 +1,87 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute pe/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID pe/atom keyword ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>pe/atom = style name of this compute command
<LI>zero or more keywords may be appended
<LI>keyword = <I>pair</I> or <I>bond</I> or <I>angle</I> or <I>dihedral</I> or <I>improper</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all pe/atom
compute 1 all pe/atom pair
compute 1 all pe/atom pair bond
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that computes the per-atom potential energy for
each atom in a group. See the <A HREF = "compute_pe.html">compute pe</A> command if
you want the potential energy of the entire system.
</P>
<P>The per-atom energy is calculated by the various pair, bond, etc
potentials defined for the simulation. If no extra keywords are
listed, then the potential energy is the sum of pair, bond, angle,
dihedral, and improper energy. If any extra keywords are listed, then
only those components are summed to compute the potential energy.
</P>
<P>Note that the energy of each atom is due to its interaction with all
other atoms in the simulation, not just with other atoms in the group.
</P>
<P>For an energy contribution produced by a small set of atoms (e.g. 4
atoms in a dihedral or 3 atoms in a Tersoff 3-body interaction), that
energy is assigned in equal portions to each atom in the set.
E.g. 1/4 of the dihedral energy to each of the 4 atoms.
</P>
<P>The <A HREF = "dihedral_charmm.html">dihedral_style charmm</A> style calculates
pairwise interactions between 1-4 atoms. The energy contribution of
these terms is included in the pair energy, not the dihedral energy.
</P>
<P>As an example of per-atom potential energy compared to total potential
energy, these lines in an input script should yield the same result
in the last 2 columns of thermo output:
</P>
<PRE>compute peratom all pe/atom
compute pe all reduce sum c_peratom
thermo_style custom step temp etotal press pe c_pe
</PRE>
<P>IMPORTANT NOTE: The per-atom energy does NOT include contributions due
to long-range Coulombic interactions (via the
<A HREF = "kspace_style.html">kspace_style</A> command). It's not clear this
contribution can easily be computed. It also does not include any
Lennard-Jones tail corrections invoked by the <A HREF = "pair_modify.html">pair_modify tail
yes</A> command, since those are global contributions to
the system energy.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The per-atom vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_pe.html">compute pe</A>, <A HREF = "compute_stress_atom.html">compute
stress/atom</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_pe_atom.txt b/doc/compute_pe_atom.txt
index c71dceec4..3b3d2a331 100644
--- a/doc/compute_pe_atom.txt
+++ b/doc/compute_pe_atom.txt
@@ -1,82 +1,82 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute pe/atom command :h3
[Syntax:]
compute ID group-ID pe/atom keyword ... :pre
ID, group-ID are documented in "compute"_compute.html command
pe/atom = style name of this compute command
zero or more keywords may be appended
keyword = {pair} or {bond} or {angle} or {dihedral} or {improper} :ul
[Examples:]
compute 1 all pe/atom
compute 1 all pe/atom pair
compute 1 all pe/atom pair bond :pre
[Description:]
Define a computation that computes the per-atom potential energy for
each atom in a group. See the "compute pe"_compute_pe.html command if
you want the potential energy of the entire system.
The per-atom energy is calculated by the various pair, bond, etc
potentials defined for the simulation. If no extra keywords are
listed, then the potential energy is the sum of pair, bond, angle,
dihedral, and improper energy. If any extra keywords are listed, then
only those components are summed to compute the potential energy.
Note that the energy of each atom is due to its interaction with all
other atoms in the simulation, not just with other atoms in the group.
For an energy contribution produced by a small set of atoms (e.g. 4
atoms in a dihedral or 3 atoms in a Tersoff 3-body interaction), that
energy is assigned in equal portions to each atom in the set.
E.g. 1/4 of the dihedral energy to each of the 4 atoms.
The "dihedral_style charmm"_dihedral_charmm.html style calculates
pairwise interactions between 1-4 atoms. The energy contribution of
these terms is included in the pair energy, not the dihedral energy.
As an example of per-atom potential energy compared to total potential
energy, these lines in an input script should yield the same result
in the last 2 columns of thermo output:
compute peratom all pe/atom
compute pe all reduce sum c_peratom
thermo_style custom step temp etotal press pe c_pe :pre
IMPORTANT NOTE: The per-atom energy does NOT include contributions due
to long-range Coulombic interactions (via the
"kspace_style"_kspace_style.html command). It's not clear this
contribution can easily be computed. It also does not include any
Lennard-Jones tail corrections invoked by the "pair_modify tail
yes"_pair_modify.html command, since those are global contributions to
the system energy.
[Output info:]
This compute calculates a per-atom vector, which can be accessed by
any command that uses per-atom values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The per-atom vector values will be in energy "units"_units.html.
[Restrictions:]
[Related commands:]
"compute pe"_compute_pe.html, "compute
stress/atom"_compute_stress_atom.html
[Default:] none
diff --git a/doc/compute_pressure.html b/doc/compute_pressure.html
index 53cc3132c..f5e729b51 100644
--- a/doc/compute_pressure.html
+++ b/doc/compute_pressure.html
@@ -1,135 +1,135 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute pressure command
</H3>
<H3>compute pressure/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID pressure temp-ID keyword ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>pressure = style name of this compute command
<LI>temp-ID = ID of compute that calculates temperature
<LI>zero or more keywords may be appended
<LI>keyword = <I>ke</I> or <I>pair</I> or <I>bond</I> or <I>angle</I> or <I>dihedral</I> or <I>improper</I> or <I>kspace</I> or <I>fix</I> or <I>virial</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all pressure myTemp
compute 1 all pressure thermo_temp pair bond
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the pressure of the entire system
of atoms. The specified group must be "all". See the <A HREF = "compute_stress_atom.html">compute
stress/atom</A> command if you want per-atom
pressure (stress). These per-atom values could be summed for a group
of atoms via the <A HREF = "compute_reduce.html">compute reduce</A> command.
</P>
<P>The pressure is computed by the formula
</P>
<CENTER><IMG SRC = "Eqs/pressure.jpg">
</CENTER>
<P>where N is the number of atoms in the system (see discussion of DOF
below), Kb is the Boltzmann constant, T is the temperature, d is the
dimensionality of the system (2 or 3 for 2d/3d), V is the system
volume (or area in 2d), and the second term is the virial, computed
within LAMMPS for all pairwise as well as 2-body, 3-body, and 4-body,
and long-range interactions. <A HREF = "fix.html">Fixes</A> that impose constraints
(e.g. the <A HREF = "fix_shake.html">fix shake</A> command) also contribute to the
virial term.
</P>
<P>A symmetric pressure tensor, stored as a 6-element vector, is also
calculated by this compute. The 6 components of the vector are
ordered xx, yy, zz, xy, xz, yz. The equation for the I,J components
(where I and J = x,y,z) is similar to the above formula, except that
the first term uses components of the kinetic energy tensor and the
second term uses components of the virial tensor:
</P>
<CENTER><IMG SRC = "Eqs/pressure_tensor.jpg">
</CENTER>
<P>If no extra keywords are listed, the entire equations above are
calculated which include a kinetic energy (temperature) term and the
virial as the sum of pair, bond, angle, dihedral, improper, kspace
(long-range), and fix contributions to the force on each atom. If any
extra keywords are listed, then only those components are summed to
compute temperature or ke and/or the virial. The <I>virial</I> keyword
means include all terms except the kinetic energy <I>ke</I>.
</P>
<P>The temperature and kinetic energy tensor is not calculated by this
compute, but rather by the temperature compute specified with the
command. Normally this compute should calculate the temperature of
all atoms for consistency with the virial term, but any compute style
that calculates temperature can be used, e.g. one that excludes frozen
atoms or other degrees of freedom.
</P>
<P>Note that the N in the first formula above is really
degrees-of-freedom divided by d = dimensionality, where the DOF value
is calcluated by the temperature compute. See the various <A HREF = "compute.html">compute
temperature</A> styles for details.
</P>
<P>A compute of this style with the ID of "thermo_press" is created when
LAMMPS starts up, as if this command were in the input script:
</P>
<PRE>compute thermo_press all pressure thermo_temp
</PRE>
<P>where "thermo_temp" is the ID of a similarly defined compute of style
"temp". See the "thermo_style" command for more details.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the pressure) and a global
vector of length 6 (pressure tensor), which can be accessed by indices
1-6. These values can be used by any command that uses global scalar
or vector values from a compute as input. See <A HREF = "Section_howto.html#howto_15">this
section</A> for an overview of LAMMPS output
options.
</P>
<P>The scalar and vector values calculated by this compute are
"intensive". The scalar and vector values will be in pressure
<A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_temp.html">compute temp</A>, <A HREF = "compute_stress_atom.html">compute
stress/atom</A>,
<A HREF = "thermo_style.html">thermo_style</A>,
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_pressure.txt b/doc/compute_pressure.txt
index 28d77dd17..0e4270948 100644
--- a/doc/compute_pressure.txt
+++ b/doc/compute_pressure.txt
@@ -1,129 +1,129 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute pressure command :h3
compute pressure/cuda command :h3
[Syntax:]
compute ID group-ID pressure temp-ID keyword ... :pre
ID, group-ID are documented in "compute"_compute.html command
pressure = style name of this compute command
temp-ID = ID of compute that calculates temperature
zero or more keywords may be appended
keyword = {ke} or {pair} or {bond} or {angle} or {dihedral} or {improper} or {kspace} or {fix} or {virial} :ul
[Examples:]
compute 1 all pressure myTemp
compute 1 all pressure thermo_temp pair bond :pre
[Description:]
Define a computation that calculates the pressure of the entire system
of atoms. The specified group must be "all". See the "compute
stress/atom"_compute_stress_atom.html command if you want per-atom
pressure (stress). These per-atom values could be summed for a group
of atoms via the "compute reduce"_compute_reduce.html command.
The pressure is computed by the formula
:c,image(Eqs/pressure.jpg)
where N is the number of atoms in the system (see discussion of DOF
below), Kb is the Boltzmann constant, T is the temperature, d is the
dimensionality of the system (2 or 3 for 2d/3d), V is the system
volume (or area in 2d), and the second term is the virial, computed
within LAMMPS for all pairwise as well as 2-body, 3-body, and 4-body,
and long-range interactions. "Fixes"_fix.html that impose constraints
(e.g. the "fix shake"_fix_shake.html command) also contribute to the
virial term.
A symmetric pressure tensor, stored as a 6-element vector, is also
calculated by this compute. The 6 components of the vector are
ordered xx, yy, zz, xy, xz, yz. The equation for the I,J components
(where I and J = x,y,z) is similar to the above formula, except that
the first term uses components of the kinetic energy tensor and the
second term uses components of the virial tensor:
:c,image(Eqs/pressure_tensor.jpg)
If no extra keywords are listed, the entire equations above are
calculated which include a kinetic energy (temperature) term and the
virial as the sum of pair, bond, angle, dihedral, improper, kspace
(long-range), and fix contributions to the force on each atom. If any
extra keywords are listed, then only those components are summed to
compute temperature or ke and/or the virial. The {virial} keyword
means include all terms except the kinetic energy {ke}.
The temperature and kinetic energy tensor is not calculated by this
compute, but rather by the temperature compute specified with the
command. Normally this compute should calculate the temperature of
all atoms for consistency with the virial term, but any compute style
that calculates temperature can be used, e.g. one that excludes frozen
atoms or other degrees of freedom.
Note that the N in the first formula above is really
degrees-of-freedom divided by d = dimensionality, where the DOF value
is calcluated by the temperature compute. See the various "compute
temperature"_compute.html styles for details.
A compute of this style with the ID of "thermo_press" is created when
LAMMPS starts up, as if this command were in the input script:
compute thermo_press all pressure thermo_temp :pre
where "thermo_temp" is the ID of a similarly defined compute of style
"temp". See the "thermo_style" command for more details.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Output info:]
This compute calculates a global scalar (the pressure) and a global
vector of length 6 (pressure tensor), which can be accessed by indices
1-6. These values can be used by any command that uses global scalar
or vector values from a compute as input. See "this
section"_Section_howto.html#howto_15 for an overview of LAMMPS output
options.
The scalar and vector values calculated by this compute are
"intensive". The scalar and vector values will be in pressure
"units"_units.html.
[Restrictions:] none
[Related commands:]
"compute temp"_compute_temp.html, "compute
stress/atom"_compute_stress_atom.html,
"thermo_style"_thermo_style.html,
[Default:] none
diff --git a/doc/compute_rdf.html b/doc/compute_rdf.html
index ae66e375b..50bb94428 100644
--- a/doc/compute_rdf.html
+++ b/doc/compute_rdf.html
@@ -1,130 +1,130 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute rdf command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID rdf Nbin itype1 jtype1 itype2 jtype2 ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>rdf = style name of this compute command
<LI>Nbin = number of RDF bins
<LI>itypeN = central atom type for Nth RDF histogram (see asterisk form below)
<LI>jtypeN = distribution atom type for Nth RDF histogram (see asterisk form below)
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all rdf 100
compute 1 all rdf 100 1 1
compute 1 all rdf 100 * 3
compute 1 fluid rdf 500 1 1 1 2 2 1 2 2
compute 1 fluid rdf 500 1*3 2 5 *10
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the radial distribution function
(RDF), also called g(r), and the coordination number for a group of
particles. Both are calculated in histogram form by binning pairwise
distances into <I>Nbin</I> bins from 0.0 to the maximum force cutoff
defined by the <A HREF = "pair_style.html">pair_style</A> command. The bins are of
uniform size in radial distance. Thus a single bin encompasses a thin
shell of distances in 3d and a thin ring of distances in 2d.
</P>
<P>The <I>itypeN</I> and <I>jtypeN</I> arguments are optional. These arguments
must come in pairs. If no pairs are listed, then a single histogram
is computed for g(r) between all atom types. If one or more pairs are
listed, then a separate histogram is generated for each
<I>itype</I>,<I>jtype</I> pair.
</P>
<P>The <I>itypeN</I> and <I>jtypeN</I> settings can be specified in one of two
ways. An explicit numeric value can be used, as in the 4th example
above. Or a wild-card asterisk can be used 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).
</P>
<P>If both <I>itypeN</I> and <I>jtypeN</I> are single values, as in the 4th example
above, this means that a g(r) is computed where atoms of type <I>itypeN</I>
are the central atom, and atoms of type <I>jtypeN</I> are the distribution
atom. If either <I>itypeN</I> and <I>jtypeN</I> represent a range of values via
the wild-card asterisk, as in the 5th example above, this means that a
g(r) is computed where atoms of any of the range of types represented
by <I>itypeN</I> are the central atom, and atoms of any of the range of
types represented by <I>jtypeN</I> are the distribution atom.
</P>
<P>Pairwise distances are generated by looping over a pairwise neighbor
list, just as they would be in a <A HREF = "pair_style.html">pair_style</A>
computation. The distance between two atoms I and J is included in
a specific histogram if the following criteria are met:
</P>
<UL><LI>atoms I,J are both in the specified compute group
<LI>the distance between atoms I,J is less than the maximum force cutoff
<LI>the type of the I atom matches itypeN (one or a range of types)
<LI>the type of the J atom matches jtypeN (one or a range of types)
</UL>
<P>It is OK if a particular pairwise distance is included in more than
one individual histogram, due to the way the <I>itypeN</I> and <I>jtypeN</I>
arguments are specified.
</P>
<P>The g(r) value for a bin is calculated from the histogram count by
scaling it by the idealized number of how many counts there would be
if atoms of type <I>jtypeN</I> were uniformly distributed. Thus it
involves the count of <I>itypeN</I> atoms, the count of <I>jtypeN</I> atoms, the
volume of the entire simulation box, and the volume of the bin's thin
shell in 3d (or the area of the bin's thin ring in 2d).
</P>
<P>A coordination number coord(r) is also calculated, which is the sum of
g(r) values for all bins up to and including the current bin.
</P>
<P>The simplest way to output the results of the compute rdf calculation
to a file is to use the <A HREF = "fix_ave_time.html">fix ave/time</A> command, for
example:
</P>
<PRE>compute myRDF all rdf 50
fix 1 all ave/time 100 1 100 c_myRDF file tmp.rdf mode vector
</PRE>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global array with the number of rows =
<I>Nbins</I>, and the number of columns = 1 + 2*Npairs, where Npairs is the
number of I,J pairings specified. The first column has the bin
coordinate (center of the bin), Each successive set of 2 columns has
the g(r) and coord(r) values for a specific set of <I>itypeN</I> versus
<I>jtypeN</I> interactions, as described above. These values can be used
by any command that uses a global values from a compute as input. See
-<A HREF = "Section_howto.html#howto_15">this section</A> for an overview of LAMMPS
-output options.
+<A HREF = "Section_howto.html#howto_15">Section_howto 15</A> for an overview of
+LAMMPS output options.
</P>
<P>The array values calculated by this compute are all "intensive".
</P>
<P>The first column of array values will be in distance
<A HREF = "units.html">units</A>. The g(r) columns of array values are normalized
numbers >= 0.0. The coordination number columns of array values are
also numbers >= 0.0.
</P>
<P><B>Restrictions:</B>
</P>
<P>The RDF is not computed for distances longer than the force cutoff,
since processors (in parallel) don't know about atom coordinates for
atoms further away than that distance. If you want an RDF for larger
distances, you'll need to post-process a dump file.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_ave_time.html">fix ave/time</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_rdf.txt b/doc/compute_rdf.txt
index 83e835ff3..afda1a28b 100644
--- a/doc/compute_rdf.txt
+++ b/doc/compute_rdf.txt
@@ -1,125 +1,125 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute rdf command :h3
[Syntax:]
compute ID group-ID rdf Nbin itype1 jtype1 itype2 jtype2 ... :pre
ID, group-ID are documented in "compute"_compute.html command
rdf = style name of this compute command
Nbin = number of RDF bins
itypeN = central atom type for Nth RDF histogram (see asterisk form below)
jtypeN = distribution atom type for Nth RDF histogram (see asterisk form below) :ul
[Examples:]
compute 1 all rdf 100
compute 1 all rdf 100 1 1
compute 1 all rdf 100 * 3
compute 1 fluid rdf 500 1 1 1 2 2 1 2 2
compute 1 fluid rdf 500 1*3 2 5 *10 :pre
[Description:]
Define a computation that calculates the radial distribution function
(RDF), also called g(r), and the coordination number for a group of
particles. Both are calculated in histogram form by binning pairwise
distances into {Nbin} bins from 0.0 to the maximum force cutoff
defined by the "pair_style"_pair_style.html command. The bins are of
uniform size in radial distance. Thus a single bin encompasses a thin
shell of distances in 3d and a thin ring of distances in 2d.
The {itypeN} and {jtypeN} arguments are optional. These arguments
must come in pairs. If no pairs are listed, then a single histogram
is computed for g(r) between all atom types. If one or more pairs are
listed, then a separate histogram is generated for each
{itype},{jtype} pair.
The {itypeN} and {jtypeN} settings can be specified in one of two
ways. An explicit numeric value can be used, as in the 4th example
above. Or a wild-card asterisk can be used 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).
If both {itypeN} and {jtypeN} are single values, as in the 4th example
above, this means that a g(r) is computed where atoms of type {itypeN}
are the central atom, and atoms of type {jtypeN} are the distribution
atom. If either {itypeN} and {jtypeN} represent a range of values via
the wild-card asterisk, as in the 5th example above, this means that a
g(r) is computed where atoms of any of the range of types represented
by {itypeN} are the central atom, and atoms of any of the range of
types represented by {jtypeN} are the distribution atom.
Pairwise distances are generated by looping over a pairwise neighbor
list, just as they would be in a "pair_style"_pair_style.html
computation. The distance between two atoms I and J is included in
a specific histogram if the following criteria are met:
atoms I,J are both in the specified compute group
the distance between atoms I,J is less than the maximum force cutoff
the type of the I atom matches itypeN (one or a range of types)
the type of the J atom matches jtypeN (one or a range of types) :ul
It is OK if a particular pairwise distance is included in more than
one individual histogram, due to the way the {itypeN} and {jtypeN}
arguments are specified.
The g(r) value for a bin is calculated from the histogram count by
scaling it by the idealized number of how many counts there would be
if atoms of type {jtypeN} were uniformly distributed. Thus it
involves the count of {itypeN} atoms, the count of {jtypeN} atoms, the
volume of the entire simulation box, and the volume of the bin's thin
shell in 3d (or the area of the bin's thin ring in 2d).
A coordination number coord(r) is also calculated, which is the sum of
g(r) values for all bins up to and including the current bin.
The simplest way to output the results of the compute rdf calculation
to a file is to use the "fix ave/time"_fix_ave_time.html command, for
example:
compute myRDF all rdf 50
fix 1 all ave/time 100 1 100 c_myRDF file tmp.rdf mode vector :pre
[Output info:]
This compute calculates a global array with the number of rows =
{Nbins}, and the number of columns = 1 + 2*Npairs, where Npairs is the
number of I,J pairings specified. The first column has the bin
coordinate (center of the bin), Each successive set of 2 columns has
the g(r) and coord(r) values for a specific set of {itypeN} versus
{jtypeN} interactions, as described above. These values can be used
by any command that uses a global values from a compute as input. See
-"this section"_Section_howto.html#howto_15 for an overview of LAMMPS
-output options.
+"Section_howto 15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
The array values calculated by this compute are all "intensive".
The first column of array values will be in distance
"units"_units.html. The g(r) columns of array values are normalized
numbers >= 0.0. The coordination number columns of array values are
also numbers >= 0.0.
[Restrictions:]
The RDF is not computed for distances longer than the force cutoff,
since processors (in parallel) don't know about atom coordinates for
atoms further away than that distance. If you want an RDF for larger
distances, you'll need to post-process a dump file.
[Related commands:]
"fix ave/time"_fix_ave_time.html
[Default:] none
diff --git a/doc/compute_reduce.html b/doc/compute_reduce.html
index f5533307e..74dbbdd9d 100644
--- a/doc/compute_reduce.html
+++ b/doc/compute_reduce.html
@@ -1,194 +1,194 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute reduce command
</H3>
<H3>compute reduce/region command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID style arg mode input1 input2 ... keyword args ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>style = <I>reduce</I> or <I>reduce/region</I>
<PRE> <I>reduce</I> arg = none
<I>reduce/region</I> arg = region-ID
region-ID = ID of region to use for choosing atoms
</PRE>
<LI>mode = <I>sum</I> or <I>min</I> or <I>max</I> or <I>ave</I>
<LI>one or more inputs can be listed
<LI>input = x, y, z, vx, vy, vz, fx, fy, fz, c_ID, c_ID[N], f_ID, f_ID[N], v_name
<PRE> x,y,z,vx,vy,vz,fx,fy,fz = atom attribute (position, velocity, force component)
c_ID = per-atom or local vector calculated by a compute with ID
c_ID[I] = Ith column of per-atom or local array calculated by a compute with ID
f_ID = per-atom or local vector calculated by a fix with ID
f_ID[I] = Ith column of per-atom or local array calculated by a fix with ID
v_name = per-atom vector calculated by an atom-style variable with name
</PRE>
<LI>zero or more keyword/args pairs may be appended
<LI>keyword = <I>replace</I>
<PRE> <I>replace</I> args = vec1 vec2
vec1 = reduced value from this input vector will be replaced
vec2 = replace it with vec1[N] where N is index of max/min value from vec2
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all reduce sum c_force
compute 1 all reduce/region subbox sum c_force
compute 2 all reduce min c_press<B>2</B> f_ave v_myKE
compute 3 fluid reduce max c_index<B>1</B> c_index<B>2</B> c_dist replace 1 3 replace 2 3
</PRE>
<P><B>Description:</B>
</P>
<P>Define a calculation that "reduces" one or more vector inputs into
scalar values, one per listed input. The inputs can be per-atom or
local quantities; they cannot be global quantities. Atom attributes
are per-atom quantities, <A HREF = "compute.html">computes</A> and <A HREF = "fix.html">fixes</A>
may generate any of the three kinds of quantities, and <A HREF = "variable.html">atom-style
variables</A> generate per-atom quantities. See the
<A HREF = "variable">variable</A> command and its special functions which can
perform the same operations as the compute reduce command on global
vectors.
</P>
<P>The reduction operation is specified by the <I>mode</I> setting. The <I>sum</I>
option adds the values in the vector into a global total. The <I>min</I>
or <I>max</I> options find the minimum or maximum value across all vector
values. The <I>ave</I> setting adds the vector values into a global total,
then divides by the number of values in the vector.
</P>
<P>Each listed input is operated on independently. For per-atom inputs,
the group specified with this command means only atoms within the
group contribute to the result. For per-atom inputs, if the compute
reduce/region command is used, the atoms must also currently be within
the region. Note that an input that produces per-atom quantities may
define its own group which affects the quantities it returns. For
example, if a compute is used as an input which generates a per-atom
vector, it will generate values of 0.0 for atoms that are not in the
group specified for that compute.
</P>
<P>Each listed input can be an atom attribute (position, velocity, force
component) or can be the result of a <A HREF = "compute.html">compute</A> or
<A HREF = "fix.html">fix</A> or the evaluation of an atom-style
<A HREF = "variable.html">variable</A>.
</P>
<P>The atom attribute values (x,y,z,vx,vy,vz,fx,fy,fz) are
self-explanatory. Note that other atom attributes can be used as
inputs to this fix by using the <A HREF = "compute_property_atom.html">compute
property/atom</A> command and then specifying
an input value from that compute.
</P>
<P>If a value begins with "c_", a compute ID must follow which has been
previously defined in the input script. Computes can generate
per-atom or local quantities. See the individual
<A HREF = "compute.html">compute</A> doc page for details. If no bracketed integer
is appended, the vector calculated by the compute is used. If a
bracketed interger is appended, the Ith column of the array calculated
by the compute is used. Users can also write code for their own
compute styles and <A HREF = "Section_modify.html">add them to LAMMPS</A>.
</P>
<P>If a value begins with "f_", a fix ID must follow which has been
previously defined in the input script. Fixes can generate per-atom
or local quantities. See the individual <A HREF = "fix.html">fix</A> doc page for
details. Note that some fixes only produce their values on certain
timesteps, which must be compatible with when compute reduce
references the values, else an error results. If no bracketed integer
is appended, the vector calculated by the fix is used. If a bracketed
integer is appended, the Ith column of the array calculated by the fix
is used. Users can also write code for their own fix style and <A HREF = "Section_modify.html">add
them to LAMMPS</A>.
</P>
<P>If a value begins with "v_", a variable name must follow which has
been previously defined in the input script. It must be an
<A HREF = "variable.html">atom-style variable</A>. Atom-style variables can
reference thermodynamic keywords and various per-atom attributes, or
invoke other computes, fixes, or variables when they are evaluated, so
this is a very general means of generating per-atom quantities to
reduce.
</P>
<HR>
<P>If the <I>replace</I> keyword is used, two indices <I>vec1</I> and <I>vec2</I> are
specified, where each index ranges from 1 to the # of input values.
The replace keyword can only be used if the <I>mode</I> is <I>min</I> or <I>max</I>.
It works as follows. A min/max is computed as usual on the <I>vec2</I>
input vector. The index N of that value within <I>vec2</I> is also stored.
Then, instead of performing a min/max on the <I>vec1</I> input vector, the
stored index is used to select the Nth element of the <I>vec1</I> vector.
</P>
<P>Thus, for example, if you wish to use this compute to find the bond
with maximum stretch, you can do it as follows:
</P>
<PRE>compute 1 all property/local batom1 batom2
compute 2 all bond/local dist
compute 3 all reduce max c_1[1] c_1[2] c_2 replace 1 3 replace 2 3
thermo_style custom step temp c_3[1] c_3[2] c_3[3]
</PRE>
<P>The first two input values in the compute reduce command are vectors
with the IDs of the 2 atoms in each bond, using the <A HREF = "compute_property_local.html">compute
property/local</A> command. The last input
value is bond distance, using the <A HREF = "compute_bond_local.html">compute
bond/local</A> command. Instead of taking the
max of the two atom ID vectors, which does not yield useful
information in this context, the <I>replace</I> keywords will extract the
atom IDs for the two atoms in the bond of maximum stretch. These atom
IDs and the bond stretch will be printed with thermodynamic output.
</P>
<HR>
<P>If a single input is specified this compute produces a global scalar
value. If multiple inputs are specified, this compute produces a
global vector of values, the length of which is equal to the number of
inputs specified.
</P>
<P>As discussed below, for <I>sum</I> mode, the value(s) produced by this
compute are all "extensive", meaning their value scales linearly with
the number of atoms involved. If normalized values are desired, this
compute can be accessed by the <A HREF = "thermo_style.html">thermo_style custom</A>
command with <A HREF = "thermo_modify.html">thermo_modify norm yes</A> set as an
option. Or it can be accessed by a <A HREF = "variable.html">variable</A> that
divides by the appropriate atom count.
</P>
<HR>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar if a single input value is
specified or a global vector of length N where N is the number of
inputs, and which can be accessed by indices 1 to N. These values can
be used by any command that uses global scalar or vector values from a
-compute as input. See <A HREF = "Section_howto.html#howto_15">this section</A> for
-an overview of LAMMPS output options.
+compute as input. See <A HREF = "Section_howto.html#howto_15">Section_howto 15</A>
+for an overview of LAMMPS output options.
</P>
<P>All the scalar or vector values calculated by this compute are
"intensive", except when the <I>sum</I> mode is used on per-atom or local
vectors, in which case the calculated values are "extensive".
</P>
<P>The scalar or vector values will be in whatever <A HREF = "units.html">units</A> the
quantities being reduced are in.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute.html">compute</A>, <A HREF = "fix.html">fix</A>, <A HREF = "variable.html">variable</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_reduce.txt b/doc/compute_reduce.txt
index 135f83eef..be542b8d8 100644
--- a/doc/compute_reduce.txt
+++ b/doc/compute_reduce.txt
@@ -1,179 +1,179 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute reduce command :h3
compute reduce/region command :h3
[Syntax:]
compute ID group-ID style arg mode input1 input2 ... keyword args ... :pre
ID, group-ID are documented in "compute"_compute.html command :ulb,l
style = {reduce} or {reduce/region} :l
{reduce} arg = none
{reduce/region} arg = region-ID
region-ID = ID of region to use for choosing atoms :pre
mode = {sum} or {min} or {max} or {ave} :l
one or more inputs can be listed :l
input = x, y, z, vx, vy, vz, fx, fy, fz, c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :l
x,y,z,vx,vy,vz,fx,fy,fz = atom attribute (position, velocity, force component)
c_ID = per-atom or local vector calculated by a compute with ID
c_ID\[I\] = Ith column of per-atom or local array calculated by a compute with ID
f_ID = per-atom or local vector calculated by a fix with ID
f_ID\[I\] = Ith column of per-atom or local array calculated by a fix with ID
v_name = per-atom vector calculated by an atom-style variable with name :pre
zero or more keyword/args pairs may be appended :l
keyword = {replace} :l
{replace} args = vec1 vec2
vec1 = reduced value from this input vector will be replaced
vec2 = replace it with vec1\[N\] where N is index of max/min value from vec2 :pre
:ule
[Examples:]
compute 1 all reduce sum c_force
compute 1 all reduce/region subbox sum c_force
compute 2 all reduce min c_press[2] f_ave v_myKE
compute 3 fluid reduce max c_index[1] c_index[2] c_dist replace 1 3 replace 2 3 :pre
[Description:]
Define a calculation that "reduces" one or more vector inputs into
scalar values, one per listed input. The inputs can be per-atom or
local quantities; they cannot be global quantities. Atom attributes
are per-atom quantities, "computes"_compute.html and "fixes"_fix.html
may generate any of the three kinds of quantities, and "atom-style
variables"_variable.html generate per-atom quantities. See the
"variable"_variable command and its special functions which can
perform the same operations as the compute reduce command on global
vectors.
The reduction operation is specified by the {mode} setting. The {sum}
option adds the values in the vector into a global total. The {min}
or {max} options find the minimum or maximum value across all vector
values. The {ave} setting adds the vector values into a global total,
then divides by the number of values in the vector.
Each listed input is operated on independently. For per-atom inputs,
the group specified with this command means only atoms within the
group contribute to the result. For per-atom inputs, if the compute
reduce/region command is used, the atoms must also currently be within
the region. Note that an input that produces per-atom quantities may
define its own group which affects the quantities it returns. For
example, if a compute is used as an input which generates a per-atom
vector, it will generate values of 0.0 for atoms that are not in the
group specified for that compute.
Each listed input can be an atom attribute (position, velocity, force
component) or can be the result of a "compute"_compute.html or
"fix"_fix.html or the evaluation of an atom-style
"variable"_variable.html.
The atom attribute values (x,y,z,vx,vy,vz,fx,fy,fz) are
self-explanatory. Note that other atom attributes can be used as
inputs to this fix by using the "compute
property/atom"_compute_property_atom.html command and then specifying
an input value from that compute.
If a value begins with "c_", a compute ID must follow which has been
previously defined in the input script. Computes can generate
per-atom or local quantities. See the individual
"compute"_compute.html doc page for details. If no bracketed integer
is appended, the vector calculated by the compute is used. If a
bracketed interger is appended, the Ith column of the array calculated
by the compute is used. Users can also write code for their own
compute styles and "add them to LAMMPS"_Section_modify.html.
If a value begins with "f_", a fix ID must follow which has been
previously defined in the input script. Fixes can generate per-atom
or local quantities. See the individual "fix"_fix.html doc page for
details. Note that some fixes only produce their values on certain
timesteps, which must be compatible with when compute reduce
references the values, else an error results. If no bracketed integer
is appended, the vector calculated by the fix is used. If a bracketed
integer is appended, the Ith column of the array calculated by the fix
is used. Users can also write code for their own fix style and "add
them to LAMMPS"_Section_modify.html.
If a value begins with "v_", a variable name must follow which has
been previously defined in the input script. It must be an
"atom-style variable"_variable.html. Atom-style variables can
reference thermodynamic keywords and various per-atom attributes, or
invoke other computes, fixes, or variables when they are evaluated, so
this is a very general means of generating per-atom quantities to
reduce.
:line
If the {replace} keyword is used, two indices {vec1} and {vec2} are
specified, where each index ranges from 1 to the # of input values.
The replace keyword can only be used if the {mode} is {min} or {max}.
It works as follows. A min/max is computed as usual on the {vec2}
input vector. The index N of that value within {vec2} is also stored.
Then, instead of performing a min/max on the {vec1} input vector, the
stored index is used to select the Nth element of the {vec1} vector.
Thus, for example, if you wish to use this compute to find the bond
with maximum stretch, you can do it as follows:
compute 1 all property/local batom1 batom2
compute 2 all bond/local dist
compute 3 all reduce max c_1\[1\] c_1\[2\] c_2 replace 1 3 replace 2 3
thermo_style custom step temp c_3\[1\] c_3\[2\] c_3\[3\] :pre
The first two input values in the compute reduce command are vectors
with the IDs of the 2 atoms in each bond, using the "compute
property/local"_compute_property_local.html command. The last input
value is bond distance, using the "compute
bond/local"_compute_bond_local.html command. Instead of taking the
max of the two atom ID vectors, which does not yield useful
information in this context, the {replace} keywords will extract the
atom IDs for the two atoms in the bond of maximum stretch. These atom
IDs and the bond stretch will be printed with thermodynamic output.
:line
If a single input is specified this compute produces a global scalar
value. If multiple inputs are specified, this compute produces a
global vector of values, the length of which is equal to the number of
inputs specified.
As discussed below, for {sum} mode, the value(s) produced by this
compute are all "extensive", meaning their value scales linearly with
the number of atoms involved. If normalized values are desired, this
compute can be accessed by the "thermo_style custom"_thermo_style.html
command with "thermo_modify norm yes"_thermo_modify.html set as an
option. Or it can be accessed by a "variable"_variable.html that
divides by the appropriate atom count.
:line
[Output info:]
This compute calculates a global scalar if a single input value is
specified or a global vector of length N where N is the number of
inputs, and which can be accessed by indices 1 to N. These values can
be used by any command that uses global scalar or vector values from a
-compute as input. See "this section"_Section_howto.html#howto_15 for
-an overview of LAMMPS output options.
+compute as input. See "Section_howto 15"_Section_howto.html#howto_15
+for an overview of LAMMPS output options.
All the scalar or vector values calculated by this compute are
"intensive", except when the {sum} mode is used on per-atom or local
vectors, in which case the calculated values are "extensive".
The scalar or vector values will be in whatever "units"_units.html the
quantities being reduced are in.
[Restrictions:] none
[Related commands:]
"compute"_compute.html, "fix"_fix.html, "variable"_variable.html
[Default:] none
diff --git a/doc/compute_stress_atom.html b/doc/compute_stress_atom.html
index f39d75300..fb9a8634b 100644
--- a/doc/compute_stress_atom.html
+++ b/doc/compute_stress_atom.html
@@ -1,119 +1,120 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute stress/atom command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID stress/atom keyword ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>stress/atom = style name of this compute command
<LI>zero or more keywords may be appended
<LI>keyword = <I>ke</I> or <I>pair</I> or <I>bond</I> or <I>angle</I> or <I>dihedral</I> or <I>improper</I> or <I>fix</I> or <I>virial</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 mobile stress/atom
compute 1 all stress/atom pair bond
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that computes the symmetric per-atom stress
tensor for each atom in a group. The tensor for each atom has 6
components and is stored as a 6-element vector in the following order:
xx, yy, zz, xy, xz, yz. See the <A HREF = "compute_pressure.html">compute
pressure</A> command if you want the stress tensor
(pressure) of the entire system.
</P>
<P>The stress tensor for atom <I>I</I> is given by the following formula,
where <I>a</I> and <I>b</I> take on values x,y,z to generate the 6 components of
the symmetric tensor:
</P>
<CENTER><IMG SRC = "Eqs/stress_tensor.jpg">
</CENTER>
<P>The first term is a kinetic energy contribution for atom <I>I</I>. The
second term is a pairwise energy contribution where <I>n</I> loops over the
<I>Np</I> neighbors of atom <I>I</I>, <I>r1</I> and <I>r2</I> are the positions of the 2
atoms in the pairwise interaction, and <I>F1</I> and <I>F2</I> are the forces on
the 2 atoms resulting from the pairwise interaction. The third term
is a bond contribution of similar form for the <I>Nb</I> bonds which atom
<I>I</I> is part of. There are similar terms for the <I>Na</I> angle, <I>Nd</I>
dihedral, and <I>Ni</I> improper interactions atom <I>I</I> is part of.
Finally, there is a term for the <I>Nf</I> <A HREF = "fix.html">fixes</A> that apply
internal constraint forces to atom <I>I</I>. Currently, only the <A HREF = "fix_shake.html">fix
shake</A> and <A HREF = "fix_rigid.html">fix rigid</A> commands
contribute to this term.
</P>
<P>As the coefficients in the formula imply, a virial contribution
produced by a small set of atoms (e.g. 4 atoms in a dihedral or 3
atoms in a Tersoff 3-body interaction) is assigned in equal portions
to each atom in the set. E.g. 1/4 of the dihedral virial to each of
the 4 atoms, or 1/3 of the fix virial due to SHAKE constraints applied
to atoms in a a water molecule via the <A HREF = "fix_shake.html">fix shake</A>
command.
</P>
<P>If no extra keywords are listed, all of the terms in this formula are
included in the per-atom stress tensor. If any extra keywords are
listed, only those terms are summed to compute the tensor. The
<I>virial</I> keyword means include all terms except the kinetic energy
<I>ke</I>.
</P>
<P>Note that the stress for each atom is due to its interaction with all
other atoms in the simulation, not just with other atoms in the group.
</P>
<P>The <A HREF = "dihedral_charmm.html">dihedral_style charmm</A> style calculates
pairwise interactions between 1-4 atoms. The virial contribution of
these terms is included in the pair virial, not the dihedral virial.
</P>
<P>Note that as defined in the formula, per-atom stress is the negative
of the per-atom pressure tensor. It is also really a stress*volume
formulation, meaning the computed quantity is in units of
pressure*volume. It would need to be divided by a per-atom volume to
have units of stress (pressure), but an individual atom's volume is
not well defined or easy to compute in a deformed solid or a liquid.
Thus, if the diagonal components of the per-atom stress tensor are
summed for all atoms in the system and the sum is divided by dV, where
d = dimension and V is the volume of the system, the result should be
-P, where P is the total pressure of the system.
</P>
<P>These lines in an input script for a 3d system should yield that
result. I.e. the last 2 columns of thermo output will be the same:
</P>
<PRE>compute peratom all stress/atom
compute p all reduce sum c_peratom[1] c_peratom[2] c_peratom[3]
variable press equal -(c_p[1]+c_p[2]+c_p[3])/(3*vol)
thermo_style custom step temp etotal press v_press
</PRE>
<P>IMPORTANT NOTE: The per-atom stress does NOT include contributions due
to long-range Coulombic interactions (via the
<A HREF = "kspace_style.html">kspace_style</A> command). It's not clear this
contribution can easily be computed.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a per-atom array with 6 columns, which can be
accessed by indices 1-6 by any command that uses per-atom values from
-a compute as input. See <A HREF = "Section_howto.html#howto_15">this section</A>
-for an overview of LAMMPS output options.
+a compute as input. See <A HREF = "Section_howto.html#howto_15">Section_howto
+15</A> for an overview of LAMMPS output
+options.
</P>
<P>The per-atom array values will be in pressure*volume
<A HREF = "units.html">units</A> as discussed above.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_pe.html">compute pe</A>, <A HREF = "compute_pressure.html">compute pressure</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_stress_atom.txt b/doc/compute_stress_atom.txt
index f8d073397..6cdd4b028 100644
--- a/doc/compute_stress_atom.txt
+++ b/doc/compute_stress_atom.txt
@@ -1,114 +1,115 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute stress/atom command :h3
[Syntax:]
compute ID group-ID stress/atom keyword ... :pre
ID, group-ID are documented in "compute"_compute.html command
stress/atom = style name of this compute command
zero or more keywords may be appended
keyword = {ke} or {pair} or {bond} or {angle} or {dihedral} or {improper} or {fix} or {virial} :ul
[Examples:]
compute 1 mobile stress/atom
compute 1 all stress/atom pair bond :pre
[Description:]
Define a computation that computes the symmetric per-atom stress
tensor for each atom in a group. The tensor for each atom has 6
components and is stored as a 6-element vector in the following order:
xx, yy, zz, xy, xz, yz. See the "compute
pressure"_compute_pressure.html command if you want the stress tensor
(pressure) of the entire system.
The stress tensor for atom {I} is given by the following formula,
where {a} and {b} take on values x,y,z to generate the 6 components of
the symmetric tensor:
:c,image(Eqs/stress_tensor.jpg)
The first term is a kinetic energy contribution for atom {I}. The
second term is a pairwise energy contribution where {n} loops over the
{Np} neighbors of atom {I}, {r1} and {r2} are the positions of the 2
atoms in the pairwise interaction, and {F1} and {F2} are the forces on
the 2 atoms resulting from the pairwise interaction. The third term
is a bond contribution of similar form for the {Nb} bonds which atom
{I} is part of. There are similar terms for the {Na} angle, {Nd}
dihedral, and {Ni} improper interactions atom {I} is part of.
Finally, there is a term for the {Nf} "fixes"_fix.html that apply
internal constraint forces to atom {I}. Currently, only the "fix
shake"_fix_shake.html and "fix rigid"_fix_rigid.html commands
contribute to this term.
As the coefficients in the formula imply, a virial contribution
produced by a small set of atoms (e.g. 4 atoms in a dihedral or 3
atoms in a Tersoff 3-body interaction) is assigned in equal portions
to each atom in the set. E.g. 1/4 of the dihedral virial to each of
the 4 atoms, or 1/3 of the fix virial due to SHAKE constraints applied
to atoms in a a water molecule via the "fix shake"_fix_shake.html
command.
If no extra keywords are listed, all of the terms in this formula are
included in the per-atom stress tensor. If any extra keywords are
listed, only those terms are summed to compute the tensor. The
{virial} keyword means include all terms except the kinetic energy
{ke}.
Note that the stress for each atom is due to its interaction with all
other atoms in the simulation, not just with other atoms in the group.
The "dihedral_style charmm"_dihedral_charmm.html style calculates
pairwise interactions between 1-4 atoms. The virial contribution of
these terms is included in the pair virial, not the dihedral virial.
Note that as defined in the formula, per-atom stress is the negative
of the per-atom pressure tensor. It is also really a stress*volume
formulation, meaning the computed quantity is in units of
pressure*volume. It would need to be divided by a per-atom volume to
have units of stress (pressure), but an individual atom's volume is
not well defined or easy to compute in a deformed solid or a liquid.
Thus, if the diagonal components of the per-atom stress tensor are
summed for all atoms in the system and the sum is divided by dV, where
d = dimension and V is the volume of the system, the result should be
-P, where P is the total pressure of the system.
These lines in an input script for a 3d system should yield that
result. I.e. the last 2 columns of thermo output will be the same:
compute peratom all stress/atom
compute p all reduce sum c_peratom\[1\] c_peratom\[2\] c_peratom\[3\]
variable press equal -(c_p\[1\]+c_p\[2\]+c_p\[3\])/(3*vol)
thermo_style custom step temp etotal press v_press :pre
IMPORTANT NOTE: The per-atom stress does NOT include contributions due
to long-range Coulombic interactions (via the
"kspace_style"_kspace_style.html command). It's not clear this
contribution can easily be computed.
[Output info:]
This compute calculates a per-atom array with 6 columns, which can be
accessed by indices 1-6 by any command that uses per-atom values from
-a compute as input. See "this section"_Section_howto.html#howto_15
-for an overview of LAMMPS output options.
+a compute as input. See "Section_howto
+15"_Section_howto.html#howto_15 for an overview of LAMMPS output
+options.
The per-atom array values will be in pressure*volume
"units"_units.html as discussed above.
[Restrictions:] none
[Related commands:]
"compute pe"_compute_pe.html, "compute pressure"_compute_pressure.html
[Default:] none
diff --git a/doc/compute_temp.html b/doc/compute_temp.html
index 6005da58d..bf7a2615c 100644
--- a/doc/compute_temp.html
+++ b/doc/compute_temp.html
@@ -1,117 +1,117 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute temp command
</H3>
<H3>compute temp/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID temp
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>temp = style name of this compute command
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all temp
compute myTemp mobile temp
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the temperature of a group of
atoms. A compute of this style can be used by any command that
computes a temperature, e.g. <A HREF = "thermo_modify.html">thermo_modify</A>, <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A>, <A HREF = "fix_nh.html">fix npt</A>, etc.
</P>
<P>The temperature is calculated by the formula KE = dim/2 N k T, where
KE = total kinetic energy of the group of atoms (sum of 1/2 m v^2),
dim = 2 or 3 = dimensionality of the simulation, N = number of atoms
in the group, k = Boltzmann constant, and T = temperature.
</P>
<P>A kinetic energy tensor, stored as a 6-element vector, is also
calculated by this compute for use in the computation of a pressure
tensor. The formula for the components of the tensor is the same as
the above formula, except that v^2 is replaced by vx*vy for the xy
component, etc. The 6 components of the vector are ordered xx, yy,
zz, xy, xz, yz.
</P>
<P>The number of atoms contributing to the temperature is assumed to be
constant for the duration of the run; use the <I>dynamic</I> option of the
<A HREF = "compute_modify.html">compute_modify</A> command if this is not the case.
</P>
<P>This compute subtracts out degrees-of-freedom due to fixes that
constrain molecular motion, such as <A HREF = "fix_shake.html">fix shake</A> and
<A HREF = "fix_rigid.html">fix rigid</A>. This means the temperature of groups of
atoms that include these constraints will be computed correctly. If
needed, the subtracted degrees-of-freedom can be altered using the
<I>extra</I> option of the <A HREF = "compute_modify.html">compute_modify</A> command.
</P>
<P>A compute of this style with the ID of "thermo_temp" is created when
LAMMPS starts up, as if this command were in the input script:
</P>
<PRE>compute thermo_temp all temp
</PRE>
<P>See the "thermo_style" command for more details.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the temperature) and a global
vector of length 6 (KE tensor), which can be accessed by indices 1-6.
These values can be used by any command that uses global scalar or
vector values from a compute as input. See <A HREF = "Section_howto.html#howto_15">this
section</A> for an overview of LAMMPS output
options.
</P>
<P>The scalar value calculated by this compute is "intensive". The
vector are "extensive".
</P>
<P>The scalar value will be in temperature <A HREF = "units.html">units</A>. The
vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_temp_partial.html">compute temp/partial</A>, <A HREF = "compute_temp_region.html">compute
temp/region</A>, <A HREF = "compute_pressure.html">compute
pressure</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_temp.txt b/doc/compute_temp.txt
index 7915e8683..d31b05bd2 100644
--- a/doc/compute_temp.txt
+++ b/doc/compute_temp.txt
@@ -1,111 +1,111 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute temp command :h3
compute temp/cuda command :h3
[Syntax:]
compute ID group-ID temp :pre
ID, group-ID are documented in "compute"_compute.html command
temp = style name of this compute command :ul
[Examples:]
compute 1 all temp
compute myTemp mobile temp :pre
[Description:]
Define a computation that calculates the temperature of a group of
atoms. A compute of this style can be used by any command that
computes a temperature, e.g. "thermo_modify"_thermo_modify.html, "fix
temp/rescale"_fix_temp_rescale.html, "fix npt"_fix_nh.html, etc.
The temperature is calculated by the formula KE = dim/2 N k T, where
KE = total kinetic energy of the group of atoms (sum of 1/2 m v^2),
dim = 2 or 3 = dimensionality of the simulation, N = number of atoms
in the group, k = Boltzmann constant, and T = temperature.
A kinetic energy tensor, stored as a 6-element vector, is also
calculated by this compute for use in the computation of a pressure
tensor. The formula for the components of the tensor is the same as
the above formula, except that v^2 is replaced by vx*vy for the xy
component, etc. The 6 components of the vector are ordered xx, yy,
zz, xy, xz, yz.
The number of atoms contributing to the temperature is assumed to be
constant for the duration of the run; use the {dynamic} option of the
"compute_modify"_compute_modify.html command if this is not the case.
This compute subtracts out degrees-of-freedom due to fixes that
constrain molecular motion, such as "fix shake"_fix_shake.html and
"fix rigid"_fix_rigid.html. This means the temperature of groups of
atoms that include these constraints will be computed correctly. If
needed, the subtracted degrees-of-freedom can be altered using the
{extra} option of the "compute_modify"_compute_modify.html command.
A compute of this style with the ID of "thermo_temp" is created when
LAMMPS starts up, as if this command were in the input script:
compute thermo_temp all temp :pre
See the "thermo_style" command for more details.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Output info:]
This compute calculates a global scalar (the temperature) and a global
vector of length 6 (KE tensor), which can be accessed by indices 1-6.
These values can be used by any command that uses global scalar or
vector values from a compute as input. See "this
section"_Section_howto.html#howto_15 for an overview of LAMMPS output
options.
The scalar value calculated by this compute is "intensive". The
vector are "extensive".
The scalar value will be in temperature "units"_units.html. The
vector values will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute temp/partial"_compute_temp_partial.html, "compute
temp/region"_compute_temp_region.html, "compute
pressure"_compute_pressure.html
[Default:] none
diff --git a/doc/compute_temp_partial.html b/doc/compute_temp_partial.html
index c076a2be5..c6b841c2b 100644
--- a/doc/compute_temp_partial.html
+++ b/doc/compute_temp_partial.html
@@ -1,125 +1,125 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute temp/partial command
</H3>
<H3>compute temp/partial/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group-ID temp/partial xflag yflag zflag
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>temp/partial = style name of this compute command
<LI>xflag,yflag,zflag = 0/1 for whether to exclude/include this dimension
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute newT flow temp/partial 1 1 0
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the temperature of a group of
atoms, after excluding one or more velocity components. A compute of
this style can be used by any command that computes a temperature,
e.g. <A HREF = "thermo_modify.html">thermo_modify</A>, <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A>, <A HREF = "fix_nh.html">fix npt</A>, etc.
</P>
<P>The temperature is calculated by the formula KE = dim/2 N k T, where
KE = total kinetic energy of the group of atoms (sum of 1/2 m v^2),
dim = dimensionality of the simulation, N = number of atoms in the
group, k = Boltzmann constant, and T = temperature. The calculation
of KE excludes the x, y, or z dimensions if xflag, yflag, or zflag =
0. The dim parameter is adjusted to give the correct number of
degrees of freedom.
</P>
<P>A kinetic energy tensor, stored as a 6-element vector, is also
calculated by this compute for use in the calculation of a pressure
tensor. The formula for the components of the tensor is the same as
the above formula, except that v^2 is replaced by vx*vy for the xy
component, etc. The 6 components of the vector are ordered xx, yy,
zz, xy, xz, yz.
</P>
<P>The number of atoms contributing to the temperature is assumed to be
constant for the duration of the run; use the <I>dynamic</I> option of the
<A HREF = "compute_modify.html">compute_modify</A> command if this is not the case.
</P>
<P>The removal of velocity components by this fix is essentially
computing the temperature after a "bias" has been removed from the
velocity of the atoms. If this compute is used with a fix command
that performs thermostatting then this bias will be subtracted from
each atom, thermostatting of the remaining thermal velocity will be
performed, and the bias will be added back in. Thermostatting fixes
that work in this way include <A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A>, <A HREF = "fix_temp_berendsen.html">fix
temp/berendsen</A>, and <A HREF = "fix_langevin.html">fix
langevin</A>.
</P>
<P>This compute subtracts out degrees-of-freedom due to fixes that
constrain molecular motion, such as <A HREF = "fix_shake.html">fix shake</A> and
<A HREF = "fix_rigid.html">fix rigid</A>. This means the temperature of groups of
atoms that include these constraints will be computed correctly. If
needed, the subtracted degrees-of-freedom can be altered using the
<I>extra</I> option of the <A HREF = "compute_modify.html">compute_modify</A> command.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar (the temperature) and a global
vector of length 6 (KE tensor), which can be accessed by indices 1-6.
These values can be used by any command that uses global scalar or
vector values from a compute as input. See <A HREF = "Section_howto.html#howto_15">this
section</A> for an overview of LAMMPS output
options.
</P>
<P>The scalar value calculated by this compute is "intensive". The
vector values are "extensive".
</P>
<P>The scalar value will be in temperature <A HREF = "units.html">units</A>. The
vector values will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_temp.html">compute temp</A>, <A HREF = "compute_temp_region.html">compute
temp/region</A>, <A HREF = "compute_pressure.html">compute
pressure</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/compute_temp_partial.txt b/doc/compute_temp_partial.txt
index ab5d42f9d..525ab972a 100644
--- a/doc/compute_temp_partial.txt
+++ b/doc/compute_temp_partial.txt
@@ -1,119 +1,119 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute temp/partial command :h3
compute temp/partial/cuda command :h3
[Syntax:]
compute ID group-ID temp/partial xflag yflag zflag :pre
ID, group-ID are documented in "compute"_compute.html command
temp/partial = style name of this compute command
xflag,yflag,zflag = 0/1 for whether to exclude/include this dimension :ul
[Examples:]
compute newT flow temp/partial 1 1 0 :pre
[Description:]
Define a computation that calculates the temperature of a group of
atoms, after excluding one or more velocity components. A compute of
this style can be used by any command that computes a temperature,
e.g. "thermo_modify"_thermo_modify.html, "fix
temp/rescale"_fix_temp_rescale.html, "fix npt"_fix_nh.html, etc.
The temperature is calculated by the formula KE = dim/2 N k T, where
KE = total kinetic energy of the group of atoms (sum of 1/2 m v^2),
dim = dimensionality of the simulation, N = number of atoms in the
group, k = Boltzmann constant, and T = temperature. The calculation
of KE excludes the x, y, or z dimensions if xflag, yflag, or zflag =
0. The dim parameter is adjusted to give the correct number of
degrees of freedom.
A kinetic energy tensor, stored as a 6-element vector, is also
calculated by this compute for use in the calculation of a pressure
tensor. The formula for the components of the tensor is the same as
the above formula, except that v^2 is replaced by vx*vy for the xy
component, etc. The 6 components of the vector are ordered xx, yy,
zz, xy, xz, yz.
The number of atoms contributing to the temperature is assumed to be
constant for the duration of the run; use the {dynamic} option of the
"compute_modify"_compute_modify.html command if this is not the case.
The removal of velocity components by this fix is essentially
computing the temperature after a "bias" has been removed from the
velocity of the atoms. If this compute is used with a fix command
that performs thermostatting then this bias will be subtracted from
each atom, thermostatting of the remaining thermal velocity will be
performed, and the bias will be added back in. Thermostatting fixes
that work in this way include "fix nvt"_fix_nh.html, "fix
temp/rescale"_fix_temp_rescale.html, "fix
temp/berendsen"_fix_temp_berendsen.html, and "fix
langevin"_fix_langevin.html.
This compute subtracts out degrees-of-freedom due to fixes that
constrain molecular motion, such as "fix shake"_fix_shake.html and
"fix rigid"_fix_rigid.html. This means the temperature of groups of
atoms that include these constraints will be computed correctly. If
needed, the subtracted degrees-of-freedom can be altered using the
{extra} option of the "compute_modify"_compute_modify.html command.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Output info:]
This compute calculates a global scalar (the temperature) and a global
vector of length 6 (KE tensor), which can be accessed by indices 1-6.
These values can be used by any command that uses global scalar or
vector values from a compute as input. See "this
section"_Section_howto.html#howto_15 for an overview of LAMMPS output
options.
The scalar value calculated by this compute is "intensive". The
vector values are "extensive".
The scalar value will be in temperature "units"_units.html. The
vector values will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"compute temp"_compute_temp.html, "compute
temp/region"_compute_temp_region.html, "compute
pressure"_compute_pressure.html
[Default:] none
diff --git a/doc/compute_ti.html b/doc/compute_ti.html
index 4e997fb1c..b3e7c6358 100644
--- a/doc/compute_ti.html
+++ b/doc/compute_ti.html
@@ -1,124 +1,125 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>compute ti command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>compute ID group ti keyword args ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "compute.html">compute</A> command
<LI>ti = style name of this compute command
<LI>one or more attribute/arg pairs may be appended
<LI>keyword = pair style (lj/cut, gauss, born, etc) or <I>tail</I> or <I>kspace</I>
<PRE> pair style args = v_name1 v_name2
v_name1 = variable with name1 that is energy scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda
<I>tail</I> args = v_name1 v_name2
v_name1 = variable with name1 that is energy tail correction scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda
<I>kspace</I> args = v_name1 v_name2
v_name1 = variable with name1 that is K-Space scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>compute 1 all ti lj/cut v_lj v_dlj coul/long v_c v_dc kspace v_ks v_dks
</PRE>
<P><B>Description:</B>
</P>
<P>Define a computation that calculates the derivative of the interaction
potential with respect to <I>lambda</I>, the coupling parameter used in a
thermodynamic integration. This derivative can be used to infer a
free energy difference resulting from an alchemical simulation, as
described in <A HREF = "#Eike">Eike</A>.
</P>
<P>Typically this compute will be used in conjunction with the <A HREF = "fix_adapt.html">fix
adapt</A> command which can perform alchemical
transformations by adusting the strength of an interaction potential
as a simulation runs, as defined by one or more
<A HREF = "pair_style.html">pair_style</A> or <A HREF = "kspace_style.html">kspace_style</A>
commands. This scaling is done via a prefactor on the energy, forces,
virial calculated by the pair or K-Space style. The prefactor is
often a function of a <I>lambda</I> parameter which may be adjusted from 0
to 1 (or vice versa) over the course of a <A HREF = "run.html">run</A>. The
time-dependent adjustment is what the <A HREF = "fix_adapt.html">fix adapt</A>
command does.
</P>
<P>Assume that the unscaled energy of a pair_style or kspace_style is
given by U. Then the scaled energy is
</P>
<PRE>Us = f(lambda) U
</PRE>
<P>where f() is some function of lambda. What this compute calculates is
</P>
<PRE>dUs / d(lambda) = U df(lambda)/dlambda = Us / f(lambda) df(lambda)/dlambda
</PRE>
<P>which is the derivative of the system's scaled potential energy Us
with respect to <I>lambda</I>.
</P>
<P>To do this calculation, you provide two functions, as <A HREF = "variable.html">equal-style
variables</A>. The first is specified as <I>v_name1</I>, where
<I>name1</I> is the name of the variable, and is f(lambda) in the notation
above. The second is specified as <I>v_name2</I>, where <I>name2</I> is the
name of the variable, and is df(lambda) / dlambda in the notation
above. I.e. it is the analytic derivative of f() with respect to
lambda. Note that the <I>name1</I> variable is also typically given as an
argument to the <A HREF = "fix_adapt.html">fix adapt</A> command.
</P>
<P>An alchemical simulation may use several pair potentials together,
invoked via the <A HREF = "pair_hybrid.html">pair_style hybrid or hybrid/overlay</A>
command. The total dUs/dlambda for the overall system is calculated
as the sum of each contributing term as listed by the keywords in the
compute ti command. Individual pair potentials can be listed, which
will be sub-styles in the hybrid case. You can also include a K-space
term via the <I>kspace</I> keyword. You can also include a pairwise
long-range tail correction to the energy via the <I>tail</I> keyword.
</P>
<P>For each term you can specify a different (or the same) scale factor
by the two variables that you list. Again, these will typically
correspond toe the scale factors applied to these various potentials
and the K-Space contribution via the <A HREF = "fix_adapt.html">fix_adapt</A>
command.
</P>
<P>More details about the exact functional forms for the computation of
du/dl can be found in the paper by <A HREF = "#Eike">Eike</A>.
</P>
<P><B>Output info:</B>
</P>
<P>This compute calculates a global scalar, namely dUs/dlambda. This
value can be used by any command that uses a global scalar value from
-a compute as input. See <A HREF = "Section_howto.html#howto_15">this section</A>
-for an overview of LAMMPS output options.
+a compute as input. See <A HREF = "Section_howto.html#howto_15">Section_howto
+15</A> for an overview of LAMMPS output
+options.
</P>
<P>The scalar value calculated by this compute is "extensive".
</P>
<P>The scalar value will be in energy <A HREF = "units.html">units</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_adapt.html">fix adapt</A>
</P>
<P><B>Default:</B> none
</P>
<A NAME = "Eike"></A>
<P><B>(Eike)</B> Eike and Maginn, Journal of Chemical Physics, 124, 164503 (2006).
</P>
</HTML>
diff --git a/doc/compute_ti.txt b/doc/compute_ti.txt
index 1d8041ae9..11888ddb1 100644
--- a/doc/compute_ti.txt
+++ b/doc/compute_ti.txt
@@ -1,113 +1,114 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
compute ti command :h3
[Syntax:]
compute ID group ti keyword args ... :pre
ID, group-ID are documented in "compute"_compute.html command :ulb,l
ti = style name of this compute command :l
one or more attribute/arg pairs may be appended :l
keyword = pair style (lj/cut, gauss, born, etc) or {tail} or {kspace} :l
pair style args = v_name1 v_name2
v_name1 = variable with name1 that is energy scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda
{tail} args = v_name1 v_name2
v_name1 = variable with name1 that is energy tail correction scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda
{kspace} args = v_name1 v_name2
v_name1 = variable with name1 that is K-Space scale factor and function of lambda
v_name2 = variable with name2 that is derivative of v_name1 with respect to lambda :pre
:ule
[Examples:]
compute 1 all ti lj/cut v_lj v_dlj coul/long v_c v_dc kspace v_ks v_dks :pre
[Description:]
Define a computation that calculates the derivative of the interaction
potential with respect to {lambda}, the coupling parameter used in a
thermodynamic integration. This derivative can be used to infer a
free energy difference resulting from an alchemical simulation, as
described in "Eike"_#Eike.
Typically this compute will be used in conjunction with the "fix
adapt"_fix_adapt.html command which can perform alchemical
transformations by adusting the strength of an interaction potential
as a simulation runs, as defined by one or more
"pair_style"_pair_style.html or "kspace_style"_kspace_style.html
commands. This scaling is done via a prefactor on the energy, forces,
virial calculated by the pair or K-Space style. The prefactor is
often a function of a {lambda} parameter which may be adjusted from 0
to 1 (or vice versa) over the course of a "run"_run.html. The
time-dependent adjustment is what the "fix adapt"_fix_adapt.html
command does.
Assume that the unscaled energy of a pair_style or kspace_style is
given by U. Then the scaled energy is
Us = f(lambda) U :pre
where f() is some function of lambda. What this compute calculates is
dUs / d(lambda) = U df(lambda)/dlambda = Us / f(lambda) df(lambda)/dlambda :pre
which is the derivative of the system's scaled potential energy Us
with respect to {lambda}.
To do this calculation, you provide two functions, as "equal-style
variables"_variable.html. The first is specified as {v_name1}, where
{name1} is the name of the variable, and is f(lambda) in the notation
above. The second is specified as {v_name2}, where {name2} is the
name of the variable, and is df(lambda) / dlambda in the notation
above. I.e. it is the analytic derivative of f() with respect to
lambda. Note that the {name1} variable is also typically given as an
argument to the "fix adapt"_fix_adapt.html command.
An alchemical simulation may use several pair potentials together,
invoked via the "pair_style hybrid or hybrid/overlay"_pair_hybrid.html
command. The total dUs/dlambda for the overall system is calculated
as the sum of each contributing term as listed by the keywords in the
compute ti command. Individual pair potentials can be listed, which
will be sub-styles in the hybrid case. You can also include a K-space
term via the {kspace} keyword. You can also include a pairwise
long-range tail correction to the energy via the {tail} keyword.
For each term you can specify a different (or the same) scale factor
by the two variables that you list. Again, these will typically
correspond toe the scale factors applied to these various potentials
and the K-Space contribution via the "fix_adapt"_fix_adapt.html
command.
More details about the exact functional forms for the computation of
du/dl can be found in the paper by "Eike"_#Eike.
[Output info:]
This compute calculates a global scalar, namely dUs/dlambda. This
value can be used by any command that uses a global scalar value from
-a compute as input. See "this section"_Section_howto.html#howto_15
-for an overview of LAMMPS output options.
+a compute as input. See "Section_howto
+15"_Section_howto.html#howto_15 for an overview of LAMMPS output
+options.
The scalar value calculated by this compute is "extensive".
The scalar value will be in energy "units"_units.html.
[Restrictions:] none
[Related commands:]
"fix adapt"_fix_adapt.html
[Default:] none
:link(Eike)
[(Eike)] Eike and Maginn, Journal of Chemical Physics, 124, 164503 (2006).
diff --git a/doc/create_box.html b/doc/create_box.html
index 974af9ee3..235e2bc3f 100644
--- a/doc/create_box.html
+++ b/doc/create_box.html
@@ -1,98 +1,98 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>create_box command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>create_box N region-ID
</PRE>
<UL><LI>N = # of atom types to use in this simulation
<LI>region-ID = ID of region to use as simulation domain
</UL>
<P><B>Examples:</B>
</P>
<PRE>create_box 2 mybox
</PRE>
<P><B>Description:</B>
</P>
<P>This command creates a simulation box based on the specified region.
Thus a <A HREF = "region.html">region</A> command must first be used to define a
geometric domain.
</P>
<P>The argument N is the number of atom types that will be used in the
simulation.
</P>
<P>If the region is not of style <I>prism</I>, then LAMMPS encloses the region
(block, sphere, etc) with an axis-aligned orthogonal bounding box
which becomes the simulation domain.
</P>
<P>If the region is of style <I>prism</I>, LAMMPS creates a non-orthogonal
simulation domain shaped as a parallelepiped with triclinic symmetry.
As defined by the <A HREF = "region.html">region prism</A> command, the
parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by 3
edge vectors starting from the origin given by A = (xhi-xlo,0,0); B =
(xy,yhi-ylo,0); C = (xz,yz,zhi-zlo). <I>Xy,xz,yz</I> can be 0.0 or
positive or negative values and are called "tilt factors" because they
are the amount of displacement applied to faces of an originally
orthogonal box to transform it into the parallelipiped.
</P>
<P>A <I>prism</I> region used with the create_box command must have tilt
factors (xy,xz,yz) that do not skew the box more than half the
distance of the parallel box length. For example, if xlo = 2 and xhi
= 12, then the x box length is 10 and the xy tilt factor must be
between -5 and 5. Similarly, both xz and yz must be between
-(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation,
since if the maximum tilt factor is 5 (as in this example), then
configurations with tilt = ..., -15, -5, 5, 15, 25, ... are all
geometrically equivalent.
</P>
-<P>See <A HREF = "Section_howto.html#howto_12">this section</A> of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+<P>See <A HREF = "Section_howto.html#howto_12">Section_howto 12</A> of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
</P>
<P>When a prism region is used, the simulation domain must be periodic in
any dimensions with a non-zero tilt factor, as defined by the
<A HREF = "boundary.html">boundary</A> command. I.e. if the xy tilt factor is
non-zero, then both the x and y dimensions must be periodic.
Similarly, x and z must be periodic if xz is non-zero and y and z must
be periodic if yz is non-zero. Also note that if your simulation will
tilt the box, e.g. via the <A HREF = "fix_deform.html">fix deform</A> command, the
simulation box must be defined as triclinic, even if the tilt factors
are initially 0.0.
</P>
<P>IMPORTANT NOTE: If the system is non-periodic (in a dimension), then
you should not make the lo/hi box dimensions (as defined in your
<A HREF = "region.html">region</A> command) radically smaller/larger than the extent
of the atoms you eventually plan to create, e.g. via the
<A HREF = "create_atoms.html">create_atoms</A> command. For example, if your atoms
extend from 0 to 50, you should not specify the box bounds as -10000
and 10000. This is because LAMMPS uses the specified box size to
layout the 3d grid of processors. A huge (mostly empty) box will be
sub-optimal for performance when using "fixed" boundary conditions
(see the <A HREF = "boundary.html">boundary</A> command). When using "shrink-wrap"
boundary conditions (see the <A HREF = "boundary.html">boundary</A> command), a huge
(mostly empty) box may cause a parallel simulation to lose atoms the
first time that LAMMPS shrink-wraps the box around the atoms.
</P>
<P><B>Restrictions:</B>
</P>
<P>An <A HREF = "atom_style.html">atom_style</A> and <A HREF = "region.html">region</A> must have
been previously defined to use this command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "create_atoms.html">create_atoms</A>, <A HREF = "region.html">region</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/create_box.txt b/doc/create_box.txt
index 247486503..08fce9e6b 100644
--- a/doc/create_box.txt
+++ b/doc/create_box.txt
@@ -1,93 +1,93 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
create_box command :h3
[Syntax:]
create_box N region-ID :pre
N = # of atom types to use in this simulation
region-ID = ID of region to use as simulation domain :ul
[Examples:]
create_box 2 mybox :pre
[Description:]
This command creates a simulation box based on the specified region.
Thus a "region"_region.html command must first be used to define a
geometric domain.
The argument N is the number of atom types that will be used in the
simulation.
If the region is not of style {prism}, then LAMMPS encloses the region
(block, sphere, etc) with an axis-aligned orthogonal bounding box
which becomes the simulation domain.
If the region is of style {prism}, LAMMPS creates a non-orthogonal
simulation domain shaped as a parallelepiped with triclinic symmetry.
As defined by the "region prism"_region.html command, the
parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by 3
edge vectors starting from the origin given by A = (xhi-xlo,0,0); B =
(xy,yhi-ylo,0); C = (xz,yz,zhi-zlo). {Xy,xz,yz} can be 0.0 or
positive or negative values and are called "tilt factors" because they
are the amount of displacement applied to faces of an originally
orthogonal box to transform it into the parallelipiped.
A {prism} region used with the create_box command must have tilt
factors (xy,xz,yz) that do not skew the box more than half the
distance of the parallel box length. For example, if xlo = 2 and xhi
= 12, then the x box length is 10 and the xy tilt factor must be
between -5 and 5. Similarly, both xz and yz must be between
-(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation,
since if the maximum tilt factor is 5 (as in this example), then
configurations with tilt = ..., -15, -5, 5, 15, 25, ... are all
geometrically equivalent.
-See "this section"_Section_howto.html#howto_12 of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+See "Section_howto 12"_Section_howto.html#howto_12 of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
When a prism region is used, the simulation domain must be periodic in
any dimensions with a non-zero tilt factor, as defined by the
"boundary"_boundary.html command. I.e. if the xy tilt factor is
non-zero, then both the x and y dimensions must be periodic.
Similarly, x and z must be periodic if xz is non-zero and y and z must
be periodic if yz is non-zero. Also note that if your simulation will
tilt the box, e.g. via the "fix deform"_fix_deform.html command, the
simulation box must be defined as triclinic, even if the tilt factors
are initially 0.0.
IMPORTANT NOTE: If the system is non-periodic (in a dimension), then
you should not make the lo/hi box dimensions (as defined in your
"region"_region.html command) radically smaller/larger than the extent
of the atoms you eventually plan to create, e.g. via the
"create_atoms"_create_atoms.html command. For example, if your atoms
extend from 0 to 50, you should not specify the box bounds as -10000
and 10000. This is because LAMMPS uses the specified box size to
layout the 3d grid of processors. A huge (mostly empty) box will be
sub-optimal for performance when using "fixed" boundary conditions
(see the "boundary"_boundary.html command). When using "shrink-wrap"
boundary conditions (see the "boundary"_boundary.html command), a huge
(mostly empty) box may cause a parallel simulation to lose atoms the
first time that LAMMPS shrink-wraps the box around the atoms.
[Restrictions:]
An "atom_style"_atom_style.html and "region"_region.html must have
been previously defined to use this command.
[Related commands:]
"create_atoms"_create_atoms.html, "region"_region.html
[Default:] none
diff --git a/doc/dihedral_charmm.html b/doc/dihedral_charmm.html
index 6c3104c6e..37f910922 100644
--- a/doc/dihedral_charmm.html
+++ b/doc/dihedral_charmm.html
@@ -1,120 +1,120 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style charmm command
</H3>
<H3>dihedral_style charmm/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style charmm
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style charmm
dihedral_coeff 1 120.0 1 60 0.5
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>charmm</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_charmm.jpg">
</CENTER>
<P>See <A HREF = "#MacKerell">(MacKerell)</A> for a description of the CHARMM force
field. This dihedral style can also be used for the AMBER force field
(see comment on weighting factors below). See <A HREF = "#Cornell">(Cornell)</A>
for a description of the AMBER force field.
</P>
<P>The following coefficients must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy)
<LI>n (integer >= 0)
<LI>d (integer value of degrees)
<LI>weighting factor (0.0 to 1.0)
</UL>
<P>The weighting factor is applied to pairwise interaction between the
1st and 4th atoms in the dihedral, which are computed by a CHARMM
<A HREF = "pair_charmm.html">pair_style</A> with epsilon and sigma values specified
with a <A HREF = "pair_charmm.html">pair_coeff</A> command. Note that this
weighting factor is unrelated to the weighting factor specified by the
<A HREF = "special_bonds.html">special bonds</A> command which applies to all 1-4
interactions in the system.
</P>
<P>For CHARMM force fields, the special_bonds 1-4 weighting factor should
be set to 0.0. This is because the pair styles that contain "charmm"
(e.g. <A HREF = "pair_charmm.html">pair_style lj/charmm/coul/long</A>) define extra
1-4 interaction coefficients that are used by this dihedral style to
compute those interactions explicitly. This means that if any of the
weighting factors defined as dihedral coefficients (4th coeff above)
are non-zero, then you must use a charmm pair style. Note that if you
do not set the special_bonds 1-4 weighting factor to 0.0 (which is the
default) then 1-4 interactions in dihedrals will be computed twice,
once by the pair routine and once by the dihedral routine, which is
probably not what you want.
</P>
<P>For AMBER force fields, the special_bonds 1-4 weighting factor should
be set to the AMBER defaults (1/2 and 5/6) and all the dihedral
weighting factors (4th coeff above) should be set to 0.0. In this
case, you can use any pair style you wish, since the dihedral does not
need any 1-4 information.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Cornell"></A>
<P><B>(Cornell)</B> Cornell, Cieplak, Bayly, Gould, Merz, Ferguson,
Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995).
</P>
<A NAME = "MacKerell"></A>
<P><B>(MacKerell)</B> MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem B, 102, 3586 (1998).
</P>
</HTML>
diff --git a/doc/dihedral_charmm.txt b/doc/dihedral_charmm.txt
index c0b959ffb..712967358 100644
--- a/doc/dihedral_charmm.txt
+++ b/doc/dihedral_charmm.txt
@@ -1,112 +1,112 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style charmm command :h3
dihedral_style charmm/omp command :h3
[Syntax:]
dihedral_style charmm :pre
[Examples:]
dihedral_style charmm
dihedral_coeff 1 120.0 1 60 0.5 :pre
[Description:]
The {charmm} dihedral style uses the potential
:c,image(Eqs/dihedral_charmm.jpg)
See "(MacKerell)"_#MacKerell for a description of the CHARMM force
field. This dihedral style can also be used for the AMBER force field
(see comment on weighting factors below). See "(Cornell)"_#Cornell
for a description of the AMBER force field.
The following coefficients must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy)
n (integer >= 0)
d (integer value of degrees)
weighting factor (0.0 to 1.0) :ul
The weighting factor is applied to pairwise interaction between the
1st and 4th atoms in the dihedral, which are computed by a CHARMM
"pair_style"_pair_charmm.html with epsilon and sigma values specified
with a "pair_coeff"_pair_charmm.html command. Note that this
weighting factor is unrelated to the weighting factor specified by the
"special bonds"_special_bonds.html command which applies to all 1-4
interactions in the system.
For CHARMM force fields, the special_bonds 1-4 weighting factor should
be set to 0.0. This is because the pair styles that contain "charmm"
(e.g. "pair_style lj/charmm/coul/long"_pair_charmm.html) define extra
1-4 interaction coefficients that are used by this dihedral style to
compute those interactions explicitly. This means that if any of the
weighting factors defined as dihedral coefficients (4th coeff above)
are non-zero, then you must use a charmm pair style. Note that if you
do not set the special_bonds 1-4 weighting factor to 0.0 (which is the
default) then 1-4 interactions in dihedrals will be computed twice,
once by the pair routine and once by the dihedral routine, which is
probably not what you want.
For AMBER force fields, the special_bonds 1-4 weighting factor should
be set to the AMBER defaults (1/2 and 5/6) and all the dihedral
weighting factors (4th coeff above) should be set to 0.0. In this
case, you can use any pair style you wish, since the dihedral does not
need any 1-4 information.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
:line
:link(Cornell)
[(Cornell)] Cornell, Cieplak, Bayly, Gould, Merz, Ferguson,
Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995).
:link(MacKerell)
[(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem B, 102, 3586 (1998).
diff --git a/doc/dihedral_class2.html b/doc/dihedral_class2.html
index 79e7b47d9..dcc8e8343 100644
--- a/doc/dihedral_class2.html
+++ b/doc/dihedral_class2.html
@@ -1,184 +1,184 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style class2 command
</H3>
<H3>dihedral_style class2/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style class2
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style class2
dihedral_coeff 1 100 75 100 70 80 60
dihedral_coeff * mbt 3.5945 0.1704 -0.5490 1.5228
dihedral_coeff * ebt 0.3417 0.3264 -0.9036 0.1368 0.0 -0.8080 1.0119 1.1010
dihedral_coeff 2 at 0.0 -0.1850 -0.7963 -2.0220 0.0 -0.3991 110.2453 105.1270
dihedral_coeff * aat -13.5271 110.2453 105.1270
dihedral_coeff * bb13 0.0 1.0119 1.1010
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>class2</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_class2.jpg">
</CENTER>
<P>where Ed is the dihedral term, Embt is a middle-bond-torsion term,
Eebt is an end-bond-torsion term, Eat is an angle-torsion term, Eaat
is an angle-angle-torsion term, and Ebb13 is a bond-bond-13 term.
</P>
<P>Theta1 and theta2 are equilibrium angles and r1 r2 r3 are equilibrium
bond lengths.
</P>
<P>See <A HREF = "#Sun">(Sun)</A> for a description of the COMPASS class2 force field.
</P>
<P>Coefficients for the Ed, Embt, Eebt, Eat, Eaat, and Ebb13 formulas
must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above,
or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands.
</P>
<P>These are the 6 coefficients for the Ed formula:
</P>
<UL><LI>K1 (energy)
<LI>phi1 (degrees)
<LI>K2 (energy)
<LI>phi2 (degrees)
<LI>K3 (energy)
<LI>phi3 (degrees)
</UL>
<P>For the Embt formula, each line in a
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script lists
5 coefficients, the first of which is "mbt" to indicate they are
MiddleBondTorsion coefficients. In a data file, these coefficients
should be listed under a "MiddleBondTorsion Coeffs" heading and you
must leave out the "mbt", i.e. only list 4 coefficients after the
dihedral type.
</P>
<UL><LI>mbt
<LI>A1 (energy/distance)
<LI>A2 (energy/distance)
<LI>A3 (energy/distance)
<LI>r2 (distance)
</UL>
<P>For the Eebt formula, each line in a
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script lists
9 coefficients, the first of which is "ebt" to indicate they are
EndBondTorsion coefficients. In a data file, these coefficients
should be listed under a "EndBondTorsion Coeffs" heading and you must
leave out the "ebt", i.e. only list 8 coefficients after the dihedral
type.
</P>
<UL><LI>ebt
<LI>B1 (energy/distance)
<LI>B2 (energy/distance)
<LI>B3 (energy/distance)
<LI>C1 (energy/distance)
<LI>C2 (energy/distance)
<LI>C3 (energy/distance)
<LI>r1 (distance)
<LI>r3 (distance)
</UL>
<P>For the Eat formula, each line in a
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script lists
9 coefficients, the first of which is "at" to indicate they are
AngleTorsion coefficients. In a data file, these coefficients should
be listed under a "AngleTorsion Coeffs" heading and you must leave out
the "at", i.e. only list 8 coefficients after the dihedral type.
</P>
<UL><LI>at
<LI>D1 (energy/radian)
<LI>D2 (energy/radian)
<LI>D3 (energy/radian)
<LI>E1 (energy/radian)
<LI>E2 (energy/radian)
<LI>E3 (energy/radian)
<LI>theta1 (degrees)
<LI>theta2 (degrees)
</UL>
<P>Theta1 and theta2 are specified in degrees, but LAMMPS converts them
to radians internally; hence the units of D and E are in
energy/radian.
</P>
<P>For the Eaat formula, each line in a
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script lists
4 coefficients, the first of which is "aat" to indicate they are
AngleAngleTorsion coefficients. In a data file, these coefficients
should be listed under a "AngleAngleTorsion Coeffs" heading and you
must leave out the "aat", i.e. only list 3 coefficients after the
dihedral type.
</P>
<UL><LI>aat
<LI>M (energy/radian^2)
<LI>theta1 (degrees)
<LI>theta2 (degrees)
</UL>
<P>Theta1 and theta2 are specified in degrees, but LAMMPS converts them
to radians internally; hence the units of M are in energy/radian^2.
</P>
<P>For the Ebb13 formula, each line in a
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script lists
4 coefficients, the first of which is "bb13" to indicate they are
BondBond13 coefficients. In a data file, these coefficients should be
listed under a "BondBond13 Coeffs" heading and you must leave out the
"bb13", i.e. only list 3 coefficients after the dihedral type.
</P>
<UL><LI>bb13
<LI>N (energy/distance^2)
<LI>r1 (distance)
<LI>r3 (distance)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
CLASS2 package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Sun"></A>
<P><B>(Sun)</B> Sun, J Phys Chem B 102, 7338-7364 (1998).
</P>
</HTML>
diff --git a/doc/dihedral_class2.txt b/doc/dihedral_class2.txt
index ab60aa381..391facf94 100644
--- a/doc/dihedral_class2.txt
+++ b/doc/dihedral_class2.txt
@@ -1,177 +1,177 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style class2 command :h3
dihedral_style class2/omp command :h3
[Syntax:]
dihedral_style class2 :pre
[Examples:]
dihedral_style class2
dihedral_coeff 1 100 75 100 70 80 60
dihedral_coeff * mbt 3.5945 0.1704 -0.5490 1.5228
dihedral_coeff * ebt 0.3417 0.3264 -0.9036 0.1368 0.0 -0.8080 1.0119 1.1010
dihedral_coeff 2 at 0.0 -0.1850 -0.7963 -2.0220 0.0 -0.3991 110.2453 105.1270
dihedral_coeff * aat -13.5271 110.2453 105.1270
dihedral_coeff * bb13 0.0 1.0119 1.1010 :pre
[Description:]
The {class2} dihedral style uses the potential
:c,image(Eqs/dihedral_class2.jpg)
where Ed is the dihedral term, Embt is a middle-bond-torsion term,
Eebt is an end-bond-torsion term, Eat is an angle-torsion term, Eaat
is an angle-angle-torsion term, and Ebb13 is a bond-bond-13 term.
Theta1 and theta2 are equilibrium angles and r1 r2 r3 are equilibrium
bond lengths.
See "(Sun)"_#Sun for a description of the COMPASS class2 force field.
Coefficients for the Ed, Embt, Eebt, Eat, Eaat, and Ebb13 formulas
must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above,
or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands.
These are the 6 coefficients for the Ed formula:
K1 (energy)
phi1 (degrees)
K2 (energy)
phi2 (degrees)
K3 (energy)
phi3 (degrees) :ul
For the Embt formula, each line in a
"dihedral_coeff"_dihedral_coeff.html command in the input script lists
5 coefficients, the first of which is "mbt" to indicate they are
MiddleBondTorsion coefficients. In a data file, these coefficients
should be listed under a "MiddleBondTorsion Coeffs" heading and you
must leave out the "mbt", i.e. only list 4 coefficients after the
dihedral type.
mbt
A1 (energy/distance)
A2 (energy/distance)
A3 (energy/distance)
r2 (distance) :ul
For the Eebt formula, each line in a
"dihedral_coeff"_dihedral_coeff.html command in the input script lists
9 coefficients, the first of which is "ebt" to indicate they are
EndBondTorsion coefficients. In a data file, these coefficients
should be listed under a "EndBondTorsion Coeffs" heading and you must
leave out the "ebt", i.e. only list 8 coefficients after the dihedral
type.
ebt
B1 (energy/distance)
B2 (energy/distance)
B3 (energy/distance)
C1 (energy/distance)
C2 (energy/distance)
C3 (energy/distance)
r1 (distance)
r3 (distance) :ul
For the Eat formula, each line in a
"dihedral_coeff"_dihedral_coeff.html command in the input script lists
9 coefficients, the first of which is "at" to indicate they are
AngleTorsion coefficients. In a data file, these coefficients should
be listed under a "AngleTorsion Coeffs" heading and you must leave out
the "at", i.e. only list 8 coefficients after the dihedral type.
at
D1 (energy/radian)
D2 (energy/radian)
D3 (energy/radian)
E1 (energy/radian)
E2 (energy/radian)
E3 (energy/radian)
theta1 (degrees)
theta2 (degrees) :ul
Theta1 and theta2 are specified in degrees, but LAMMPS converts them
to radians internally; hence the units of D and E are in
energy/radian.
For the Eaat formula, each line in a
"dihedral_coeff"_dihedral_coeff.html command in the input script lists
4 coefficients, the first of which is "aat" to indicate they are
AngleAngleTorsion coefficients. In a data file, these coefficients
should be listed under a "AngleAngleTorsion Coeffs" heading and you
must leave out the "aat", i.e. only list 3 coefficients after the
dihedral type.
aat
M (energy/radian^2)
theta1 (degrees)
theta2 (degrees) :ul
Theta1 and theta2 are specified in degrees, but LAMMPS converts them
to radians internally; hence the units of M are in energy/radian^2.
For the Ebb13 formula, each line in a
"dihedral_coeff"_dihedral_coeff.html command in the input script lists
4 coefficients, the first of which is "bb13" to indicate they are
BondBond13 coefficients. In a data file, these coefficients should be
listed under a "BondBond13 Coeffs" heading and you must leave out the
"bb13", i.e. only list 3 coefficients after the dihedral type.
bb13
N (energy/distance^2)
r1 (distance)
r3 (distance) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
CLASS2 package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
:line
:link(Sun)
[(Sun)] Sun, J Phys Chem B 102, 7338-7364 (1998).
diff --git a/doc/dihedral_cosine_shift_exp.html b/doc/dihedral_cosine_shift_exp.html
index c6ab2cae7..f0270280a 100644
--- a/doc/dihedral_cosine_shift_exp.html
+++ b/doc/dihedral_cosine_shift_exp.html
@@ -1,91 +1,91 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style cosine/shift/exp command
</H3>
<H3>dihedral_style cosine/shift/exp/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style cosine/shift/exp
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style cosine/shift/exp
dihedral_coeff 1 10.0 45.0 2.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cosine/shift/exp</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_cosine_shift_exp.jpg">
</CENTER>
<P>where Umin, theta, and a are defined for each dihedral type.
</P>
<P>The potential is bounded between [-Umin:0] and the minimum is located
at the angle theta0. The a parameter can be both positive or negative
and is used to control the spring constant at the equilibrium.
</P>
<P>The spring constant is given by k=a exp(a) Umin/ [2 (Exp(a)-1)].
For a>3 k/Umin = a/2 to better than 5% relative error. For negative
values of the a parameter, the spring constant is essentially zero,
and anharmonic terms takes over. The potential is furthermore well
behaved in the limit a->0, where it has been implemented to linear
order in a for a < 0.001.
</P>
<P>The following coefficients must be defined for each dihedral type via
the <A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>umin (energy)
<LI>theta (angle)
<LI>A (real number)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>,
<A HREF = "angle_cosineshiftexp.html">angle_cosineshiftexp</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/dihedral_cosine_shift_exp.txt b/doc/dihedral_cosine_shift_exp.txt
index d1e1c8223..1807d1c7e 100644
--- a/doc/dihedral_cosine_shift_exp.txt
+++ b/doc/dihedral_cosine_shift_exp.txt
@@ -1,85 +1,85 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style cosine/shift/exp command :h3
dihedral_style cosine/shift/exp/omp command :h3
[Syntax:]
dihedral_style cosine/shift/exp :pre
[Examples:]
dihedral_style cosine/shift/exp
dihedral_coeff 1 10.0 45.0 2.0 :pre
[Description:]
The {cosine/shift/exp} dihedral style uses the potential
:c,image(Eqs/dihedral_cosine_shift_exp.jpg)
where Umin, theta, and a are defined for each dihedral type.
The potential is bounded between \[-Umin:0\] and the minimum is located
at the angle theta0. The a parameter can be both positive or negative
and is used to control the spring constant at the equilibrium.
The spring constant is given by k=a exp(a) Umin/ \[2 (Exp(a)-1)\].
For a>3 k/Umin = a/2 to better than 5% relative error. For negative
values of the a parameter, the spring constant is essentially zero,
and anharmonic terms takes over. The potential is furthermore well
behaved in the limit a->0, where it has been implemented to linear
order in a for a < 0.001.
The following coefficients must be defined for each dihedral type via
the "dihedral_coeff"_dihedral_coeff.html command as in the example
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
umin (energy)
theta (angle)
A (real number) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html,
"angle_cosineshiftexp"_angle_cosineshiftexp.html
[Default:] none
diff --git a/doc/dihedral_harmonic.html b/doc/dihedral_harmonic.html
index d8c3a73f6..ad361cfce 100644
--- a/doc/dihedral_harmonic.html
+++ b/doc/dihedral_harmonic.html
@@ -1,76 +1,76 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style harmonic command
</H3>
<H3>dihedral_style harmonic/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style harmonic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style harmonic
dihedral_coeff 1 80.0 1 2
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_harmonic.jpg">
</CENTER>
<P>The following coefficients must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K (energy)
<LI>d (+1 or -1)
<LI>n (integer >= 0)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/dihedral_harmonic.txt b/doc/dihedral_harmonic.txt
index a076931a0..8eefbc02b 100644
--- a/doc/dihedral_harmonic.txt
+++ b/doc/dihedral_harmonic.txt
@@ -1,70 +1,70 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style harmonic command :h3
dihedral_style harmonic/omp command :h3
[Syntax:]
dihedral_style harmonic :pre
[Examples:]
dihedral_style harmonic
dihedral_coeff 1 80.0 1 2 :pre
[Description:]
The {harmonic} dihedral style uses the potential
:c,image(Eqs/dihedral_harmonic.jpg)
The following coefficients must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K (energy)
d (+1 or -1)
n (integer >= 0) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
diff --git a/doc/dihedral_helix.html b/doc/dihedral_helix.html
index 86b372833..f95b796e1 100644
--- a/doc/dihedral_helix.html
+++ b/doc/dihedral_helix.html
@@ -1,90 +1,90 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style helix command
</H3>
<H3>dihedral_style helix/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style helix
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style helix
dihedral_coeff 1 80.0 100.0 40.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>helix</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_helix.jpg">
</CENTER>
<P>This coarse-grain dihedral potential is described in <A HREF = "#Guo">(Guo)</A>.
For dihedral angles in the helical region, the energy function is
represented by a standard potential consisting of three minima, one
corresponding to the trans (t) state and the other to gauche states
(g+ and g-). The paper describes how the A,B,C parameters are chosen
so as to balance secondary (largely driven by local interactions) and
tertiary structure (driven by long-range interactions).
</P>
<P>The following coefficients must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>A (energy)
<LI>B (energy)
<LI>C (energy)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Guo"></A>
<P><B>(Guo)</B> Guo and Thirumalai, Journal of Molecular Biology, 263, 323-43 (1996).
</P>
</HTML>
diff --git a/doc/dihedral_helix.txt b/doc/dihedral_helix.txt
index 8792c1076..7706c04c2 100644
--- a/doc/dihedral_helix.txt
+++ b/doc/dihedral_helix.txt
@@ -1,83 +1,83 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style helix command :h3
dihedral_style helix/omp command :h3
[Syntax:]
dihedral_style helix :pre
[Examples:]
dihedral_style helix
dihedral_coeff 1 80.0 100.0 40.0 :pre
[Description:]
The {helix} dihedral style uses the potential
:c,image(Eqs/dihedral_helix.jpg)
This coarse-grain dihedral potential is described in "(Guo)"_#Guo.
For dihedral angles in the helical region, the energy function is
represented by a standard potential consisting of three minima, one
corresponding to the trans (t) state and the other to gauche states
(g+ and g-). The paper describes how the A,B,C parameters are chosen
so as to balance secondary (largely driven by local interactions) and
tertiary structure (driven by long-range interactions).
The following coefficients must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
A (energy)
B (energy)
C (energy) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
:line
:link(Guo)
[(Guo)] Guo and Thirumalai, Journal of Molecular Biology, 263, 323-43 (1996).
diff --git a/doc/dihedral_multi_harmonic.html b/doc/dihedral_multi_harmonic.html
index 10601f336..4872c2934 100644
--- a/doc/dihedral_multi_harmonic.html
+++ b/doc/dihedral_multi_harmonic.html
@@ -1,78 +1,78 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style multi/harmonic command
</H3>
<H3>dihedral_style multi/harmonic/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style multi/harmonic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style multi/harmonic
dihedral_coeff 1 20 20 20 20 20
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>multi/harmonic</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_multi_harmonic.jpg">
</CENTER>
<P>The following coefficients must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>A1 (energy)
<LI>A2 (energy)
<LI>A3 (energy)
<LI>A4 (energy)
<LI>A5 (energy)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/dihedral_multi_harmonic.txt b/doc/dihedral_multi_harmonic.txt
index 505857fe8..97b87546a 100644
--- a/doc/dihedral_multi_harmonic.txt
+++ b/doc/dihedral_multi_harmonic.txt
@@ -1,72 +1,72 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style multi/harmonic command :h3
dihedral_style multi/harmonic/omp command :h3
[Syntax:]
dihedral_style multi/harmonic :pre
[Examples:]
dihedral_style multi/harmonic
dihedral_coeff 1 20 20 20 20 20 :pre
[Description:]
The {multi/harmonic} dihedral style uses the potential
:c,image(Eqs/dihedral_multi_harmonic.jpg)
The following coefficients must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
A1 (energy)
A2 (energy)
A3 (energy)
A4 (energy)
A5 (energy) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
diff --git a/doc/dihedral_opls.html b/doc/dihedral_opls.html
index e0656dd83..6bedadc0c 100644
--- a/doc/dihedral_opls.html
+++ b/doc/dihedral_opls.html
@@ -1,88 +1,88 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dihedral_style opls command
</H3>
<H3>dihedral_style opls/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dihedral_style opls
</PRE>
<P><B>Examples:</B>
</P>
<PRE>dihedral_style opls
dihedral_coeff 1 90.0 90.0 90.0 70.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>opls</I> dihedral style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/dihedral_opls.jpg">
</CENTER>
<P>Note that the usual 1/2 factor is not included in the K values.
</P>
<P>This dihedral potential is used in the OPLS force field and is
described in <A HREF = "#Watkins">(Watkins)</A>.
</P>
<P>The following coefficients must be defined for each dihedral type via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command as in the example above, or in
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
or <A HREF = "read_restart.html">read_restart</A> commands:
</P>
<UL><LI>K1 (energy)
<LI>K2 (energy)
<LI>K3 (energy)
<LI>K4 (energy)
</UL>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dihedral_coeff.html">dihedral_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Watkins"></A>
<P><B>(Watkins)</B> Watkins and Jorgensen, J Phys Chem A, 105, 4118-4125 (2001).
</P>
</HTML>
diff --git a/doc/dihedral_opls.txt b/doc/dihedral_opls.txt
index c43e7a279..d12ced983 100644
--- a/doc/dihedral_opls.txt
+++ b/doc/dihedral_opls.txt
@@ -1,81 +1,81 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dihedral_style opls command :h3
dihedral_style opls/omp command :h3
[Syntax:]
dihedral_style opls :pre
[Examples:]
dihedral_style opls
dihedral_coeff 1 90.0 90.0 90.0 70.0 :pre
[Description:]
The {opls} dihedral style uses the potential
:c,image(Eqs/dihedral_opls.jpg)
Note that the usual 1/2 factor is not included in the K values.
This dihedral potential is used in the OPLS force field and is
described in "(Watkins)"_#Watkins.
The following coefficients must be defined for each dihedral type via the
"dihedral_coeff"_dihedral_coeff.html command as in the example above, or in
the data file or restart files read by the "read_data"_read_data.html
or "read_restart"_read_restart.html commands:
K1 (energy)
K2 (energy)
K3 (energy)
K4 (energy) :ul
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This dihedral style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"dihedral_coeff"_dihedral_coeff.html
[Default:] none
:line
:link(Watkins)
[(Watkins)] Watkins and Jorgensen, J Phys Chem A, 105, 4118-4125 (2001).
diff --git a/doc/dimension.html b/doc/dimension.html
index 5a0866c05..c4ebeccf7 100644
--- a/doc/dimension.html
+++ b/doc/dimension.html
@@ -1,53 +1,53 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dimension command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dimension N
</PRE>
<UL><LI>N = 2 or 3
</UL>
<P><B>Examples:</B>
</P>
<PRE>dimension 2
</PRE>
<P><B>Description:</B>
</P>
<P>Set the dimensionality of the simulation. By default LAMMPS runs 3d
simulations. To run a 2d simulation, this command should be used
prior to setting up a simulation box via the
<A HREF = "create_box.html">create_box</A> or <A HREF = "read_data.html">read_data</A> commands.
Restart files also store this setting.
</P>
-<P>See the discussion in <A HREF = "Section_howto.html">this section</A> for additional
-instructions on how to run 2d simulations.
+<P>See the discussion in <A HREF = "Section_howto.html">Section_howto</A> for
+additional instructions on how to run 2d simulations.
</P>
<P>IMPORTANT NOTE: Some models in LAMMPS treat particles as extended
spheres or ellipsoids, as opposed to point particles. In 2d, the
particles will still be spheres or ellipsoids, not circular disks or
ellipses, meaning their moment of inertia will be the same as in 3d.
</P>
<P><B>Restrictions:</B>
</P>
<P>This command must be used before the simulation box is defined by a
<A HREF = "read_data.html">read_data</A> or <A HREF = "create_box.html">create_box</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_enforce2d.html">fix enforce2d</A>
</P>
<P><B>Default:</B>
</P>
<PRE>dimension 3
</PRE>
</HTML>
diff --git a/doc/dimension.txt b/doc/dimension.txt
index 00e5bcfeb..e8e843c80 100644
--- a/doc/dimension.txt
+++ b/doc/dimension.txt
@@ -1,48 +1,48 @@
"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
dimension command :h3
[Syntax:]
dimension N :pre
N = 2 or 3 :ul
[Examples:]
dimension 2 :pre
[Description:]
Set the dimensionality of the simulation. By default LAMMPS runs 3d
simulations. To run a 2d simulation, this command should be used
prior to setting up a simulation box via the
"create_box"_create_box.html or "read_data"_read_data.html commands.
Restart files also store this setting.
-See the discussion in "this section"_Section_howto.html for additional
-instructions on how to run 2d simulations.
+See the discussion in "Section_howto"_Section_howto.html for
+additional instructions on how to run 2d simulations.
IMPORTANT NOTE: Some models in LAMMPS treat particles as extended
spheres or ellipsoids, as opposed to point particles. In 2d, the
particles will still be spheres or ellipsoids, not circular disks or
ellipses, meaning their moment of inertia will be the same as in 3d.
[Restrictions:]
This command must be used before the simulation box is defined by a
"read_data"_read_data.html or "create_box"_create_box.html command.
[Related commands:]
"fix enforce2d"_fix_enforce2d.html
[Default:]
dimension 3 :pre
diff --git a/doc/dump.html b/doc/dump.html
index 23bd26c17..8e8c90349 100644
--- a/doc/dump.html
+++ b/doc/dump.html
@@ -1,540 +1,540 @@
<HTML>
<CENTER> <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dump command
</H3>
<H3><A HREF = "dump_image.html">dump image</A> command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dump ID group-ID style N file args
</PRE>
<UL><LI>ID = user-assigned name for the dump
<LI>group-ID = ID of the group of atoms to be dumped
<LI>style = <I>atom</I> or <I>cfg</I> or <I>dcd</I> or <I>xtc</I> or <I>xyz</I> or <I>image</I> or <I>local</I> or <I>custom</I>
<LI>N = dump every this many timesteps
<LI>file = name of file to write dump info to
<LI>args = list of arguments for a particular style
<PRE> <I>atom</I> args = none
<I>cfg</I> args = same as <I>custom</I> args, see below
<I>dcd</I> args = none
<I>xtc</I> args = none
<I>xyz</I> args = none
</PRE>
<PRE> <I>image</I> args = discussed on <A HREF = "dump_image.html">dump image</A> doc page
</PRE>
<PRE> <I>local</I> args = list of local attributes
possible attributes = index, c_ID, c_ID[N], f_ID, f_ID[N]
index = enumeration of local values
c_ID = local vector calculated by a compute with ID
c_ID[N] = Nth column of local array calculated by a compute with ID
f_ID = local vector calculated by a fix with ID
f_ID[N] = Nth column of local array calculated by a fix with ID
</PRE>
<PRE> <I>custom</I> args = list of atom attributes
possible attributes = id, mol, type, element, mass,
x, y, z, xs, ys, zs, xu, yu, zu,
xsu, ysu, zsu, ix, iy, iz,
vx, vy, vz, fx, fy, fz,
q, mux, muy, muz, mu,
radius, diameter, omegax, omegay, omegaz,
angmomx, angmomy, angmomz, tqx, tqy, tqz,
spin, eradius, ervel, erforce,
c_ID, c_ID[N], f_ID, f_ID[N], v_name
</PRE>
<PRE> id = atom ID
mol = molecule ID
type = atom type
element = name of atom element, as defined by <A HREF = "dump_modify.html">dump_modify</A> command
mass = atom mass
x,y,z = unscaled atom coordinates
xs,ys,zs = scaled atom coordinates
xu,yu,zu = unwrapped atom coordinates
xsu,ysu,zsu = scaled unwrapped atom coordinates
ix,iy,iz = box image that the atom is in
vx,vy,vz = atom velocities
fx,fy,fz = forces on atoms
q = atom charge
mux,muy,muz = orientation of dipole moment of atom
mu = magnitude of dipole moment of atom
radius,diameter = radius,diameter of spherical particle
omegax,omegay,omegaz = angular velocity of extended particle
angmomx,angmomy,angmomz = angular momentum of extended particle
tqx,tqy,tqz = torque on extended particles
spin = electron spin
eradius = electron radius
ervel = electron radial velocity
erforce = electron radial force
c_ID = per-atom vector calculated by a compute with ID
c_ID[N] = Nth column of per-atom array calculated by a compute with ID
f_ID = per-atom vector calculated by a fix with ID
f_ID[N] = Nth column of per-atom array calculated by a fix with ID
v_name = per-atom vector calculated by an atom-style variable with name
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>dump myDump all atom 100 dump.atom
dump 2 subgroup atom 50 dump.run.bin
dump 4a all custom 100 dump.myforce.* id type x y vx fx
dump 4b flow custom 100 dump.%.myforce id type c_myF[3] v_ke
dump 2 inner cfg 10 dump.snap.*.cfg id type xs ys zs vx vy vz
dump snap all cfg 100 dump.config.*.cfg id type xs ys zs id type c_Stress<B>2</B>
dump 1 all xtc 1000 file.xtc
dump e_data all custom 100 dump.eff id type x y z spin eradius fx fy fz eforce
</PRE>
<P><B>Description:</B>
</P>
<P>Dump a snapshot of atom quantities to one or more files every N
timesteps in one of several styles. The <I>image</I> style is the
exception; it creates a JPG or PPM image file of the atom
configuration every N timesteps, as discussed on the <A HREF = "dump_image.html">dump
image</A> doc page.
</P>
<P>Only information for atoms in the specified group is dumped. The
<A HREF = "dump_modify.html">dump_modify thresh and region</A> commands can also
alter what atoms are included. Not all styles support all these
options; see details below.
</P>
<P>As described below, the filename determines the kind of output (text
or binary or gzipped, one big file or one per timestep, one big file
or one per processor).
</P>
<P>IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom written to a dump file may be slightly outside the simulation
box.
</P>
<P>IMPORTANT NOTE: Unless the <A HREF = "dump_modify.html">dump_modify sort</A> option
is invoked, the lines of atom information written to dump files
(typically one line per atom) will be in an indeterminate order for
each snapshot. This is even true when running on a single processor,
if the <A HREF = "atom_modify.html">atom_modify sort</A> option is on, which it is
by default. In this case atoms are re-ordered periodically during a
simulation, due to spatial sorting. It is also true when running in
parallel, because data for a single snapshot is collected from
multiple processors.
</P>
<P>For the <I>atom</I>, <I>custom</I>, <I>cfg</I>, and <I>local</I> styles, sorting is off by
default. For the <I>dcd</I>, <I>xtc</I>, and <I>xyz</I> styles, sorting by atom ID
is on by default. See the <A HREF = "dump_modify.html">dump_modify</A> doc page for
details.
</P>
<HR>
<P>The <I>style</I> keyword determines what atom quantities are written to the
file and in what format. Settings made via the
<A HREF = "dump_modify.html">dump_modify</A> command can also alter the format of
individual values and the file itself.
</P>
<P>The <I>atom</I>, <I>local</I>, and <I>custom</I> styles create files in a simple text
format that is self-explanatory when viewing a dump file. Many of the
LAMMPS <A HREF = "Section_tools.html">post-processing tools</A>, including
<A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A>, work with
this format.
</P>
<P>For post-processing purposes the <I>atom</I> and <I>custom</I> text files are
self-describing in the following sense.
</P>
<P>The dimensions of the simulation box are included in each snapshot.
For an orthogonal simulation box this information is is formatted as:
</P>
<PRE>ITEM: BOX BOUNDS xx yy zz
xlo xhi
ylo yhi
zlo zhi
</PRE>
<P>where xlo,xhi are the maximum extents of the simulation box in the
x-dimension, and similarly for y and z. The "xx yy zz" represent 6
characters that encode the style of boundary for each of the 6
simulation box boundaries (xlo,xhi and ylo,yhi and zlo,zhi). Each of
the 6 characters is either p = periodic, f = fixed, s = shrink wrap,
or m = shrink wrapped with a minimum value. See the
<A HREF = "doc/boundary.html">boundary</A> command for details.
</P>
<P>For triclinic simulation boxes (non-orthogonal), an orthogonal
bounding box which encloses the triclinic simulation box is output,
along with the 3 tilt factors (xy, xz, yz) of the triclinic box,
formatted as follows:
</P>
<PRE>ITEM: BOX BOUNDS xy xz yz xx yy zz
xlo_bound xhi_bound xy
ylo_bound yhi_bound xz
zlo_bound zhi_bound yz
</PRE>
<P>The presence of the text "xy xz yz" in the ITEM line indicates that
the 3 tilt factors will be included on each of the 3 following lines.
This bounding box is convenient for many visualization programs. The
meaning of the 6 character flags for "xx yy zz" is the same as above.
</P>
<P>Note that the first two numbers on each line are now xlo_bound instead
of xlo, etc, since they repesent a bounding box. See <A HREF = "Section_howto.html#howto_12">this
section</A> of the doc pages for a geometric
description of triclinic boxes, as defined by LAMMPS, simple formulas
for how the 6 bounding box extents (xlo_bound,xhi_bound,etc) are
calculated from the triclinic parameters, and how to transform those
parameters to and from other commonly used triclinic representations.
</P>
<P>The "ITEM: ATOMS" line in each snapshot lists column descriptors for
the per-atom lines that follow. For example, the descriptors would be
"id type xs ys zs" for the default <I>atom</I> style, and would be the atom
attributes you specify in the dump command for the <I>custom</I> style.
</P>
<P>For style <I>atom</I>, atom coordinates are written to the file, along with
the atom ID and atom type. By default, atom coords are written in a
scaled format (from 0 to 1). I.e. an x value of 0.25 means the atom
is at a location 1/4 of the distance from xlo to xhi of the box
boundaries. The format can be changed to unscaled coords via the
<A HREF = "dump_modify.html">dump_modify</A> settings. Image flags can also be
added for each atom via dump_modify.
</P>
<P>Style <I>custom</I> allows you to specify a list of atom attributes to be
written to the dump file for each atom. Possible attributes are
listed above and will appear in the order specified. You cannot
specify a quantity that is not defined for a particular simulation -
such as <I>q</I> for atom style <I>bond</I>, since that atom style doesn't
assign charges. Dumps occur at the very end of a timestep, so atom
attributes will include effects due to fixes that are applied during
the timestep. An explanation of the possible dump custom attributes
is given below.
</P>
<P>For style <I>local</I>, local output generated by <A HREF = "compute.html">computes</A>
and <A HREF = "fix.html">fixes</A> is used to gnerate lines of output that is
written to the dump file. This local data is typically calculated by
each processor based on the atoms it owns, but there may be zero or
more entities per atom, e.g. a list of bond distances. An explanation
of the possible dump local attributes is given below. Note that by
using input from the <A HREF = "compute_property_local.html">compute
property/local</A> command with dump local,
it is possible to generate information on bonds, angles, etc that can
be cut and pasted directly into a data file read by the
<A HREF = "read_data.html">read_data</A> command.
</P>
<P>Style <I>cfg</I> has the same command syntax as style <I>custom</I> and writes
extended CFG format files, as used by the
<A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A> visualization
package. Since the extended CFG format uses a single snapshot of the
system per file, a wildcard "*" must be included in the filename, as
discussed below. The list of atom attributes for style <I>cfg</I> must
begin with either "id type xs ys zs" or "id type xsu ysu zsu" or
since these quantities are needed to
write the CFG files in the appropriate format (though the "id" and
"type" fields do not appear explicitly in the file). Any remaining
attributes will be stored as "auxiliary properties" in the CFG files.
Note that you will typically want to use the <A HREF = "dump_modify.html">dump_modify
element</A> command with CFG-formatted files, to
associate element names with atom types, so that AtomEye can render
atoms appropriately. When unwrapped coordinates <I>xsu</I>, <I>ysu</I>, and <I>zsu</I>
are requested, the nominal AtomEye periodic cell dimensions are expanded
by a large factor UNWRAPEXPAND = 10.0, which ensures atoms that are
displayed correctly for up to UNWRAPEXPAND/2 periodic boundary crossings
in any direction.
Beyond this, AtomEye will rewrap the unwrapped coordinates.
The expansion causes the atoms to be drawn farther
away from the viewer, but it is easy to zoom the atoms closer, and
the interatomic distances are unaffected.
</P>
<P>The <I>dcd</I> style writes DCD files, a standard atomic trajectory format
used by the CHARMM, NAMD, and XPlor molecular dynamics packages. DCD
files are binary and thus may not be portable to different machines.
The number of atoms per snapshot cannot change with the <I>dcd</I> style.
The <I>unwrap</I> option of the <A HREF = "dump_modify.html">dump_modify</A> command
allows DCD coordinates to be written "unwrapped" by the image flags
for each atom. Unwrapped means that if the atom has passed through
a periodic boundary one or more times, the value is printed for what
the coordinate would be if it had not been wrapped back into the
periodic box. Note that these coordinates may thus be far outside
the box size stored with the snapshot.
</P>
<P>The <I>xtc</I> style writes XTC files, a compressed trajectory format used
by the GROMACS molecular dynamics package, and described
<A HREF = "http://manual.gromacs.org/current/online/xtc.html">here</A>.
The precision used in XTC files can be adjusted via the
<A HREF = "dump_modify.html">dump_modify</A> command. The default value of 1000
means that coordinates are stored to 1/1000 nanometer accuracy. XTC
files are portable binary files written in the NFS XDR data format,
so that any machine which supports XDR should be able to read them.
The number of atoms per snapshot cannot change with the <I>xtc</I> style.
The <I>unwrap</I> option of the <A HREF = "dump_modify.html">dump_modify</A> command allows
XTC coordinates to be written "unwrapped" by the image flags for each
atom. Unwrapped means that if the atom has passed thru a periodic
boundary one or more times, the value is printed for what the
coordinate would be if it had not been wrapped back into the periodic
box. Note that these coordinates may thus be far outside the box size
stored with the snapshot.
</P>
<P>The <I>xyz</I> style writes XYZ files, which is a simple text-based
coordinate format that many codes can read.
</P>
<P>Note that DCD, XTC, and XYZ formatted files can be read directly by
<A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> (a popular molecular viewing
-program). See <A HREF = "Section_tools.html#vmd">this section</A> of the manual and
-the tools/lmp2vmd/README.txt file for more information about support
-in VMD for reading and visualizing LAMMPS dump files.
+program). See <A HREF = "Section_tools.html#vmd">Section tools</A> of the manual
+and the tools/lmp2vmd/README.txt file for more information about
+support in VMD for reading and visualizing LAMMPS dump files.
</P>
<HR>
<P>Dumps are performed on timesteps that are a multiple of N (including
timestep 0) and on the last timestep of a minimization if the
minimization converges. Note that this means a dump will not be
performed on the initial timestep after the dump command is invoked,
if the current timestep is not a multiple of N. This behavior can be
changed via the <A HREF = "dump_modify.html">dump_modify first</A> command, which
can be useful if the dump command is invoked after a minimization
ended on an arbitrary timestep. N can be changed between runs by
using the <A HREF = "dump_modify.html">dump_modify every</A> command (not allowed
for <I>dcd</I> style).
</P>
<P>The specified filename determines how the dump file(s) is written.
The default is to write one large text file, which is opened when the
dump command is invoked and closed when an <A HREF = "undump.html">undump</A>
command is used or when LAMMPS exits. For the <I>dcd</I> and <I>xtc</I> styles,
this is a single large binary file.
</P>
<P>Dump filenames can contain two wildcard characters. If a "*"
character appears in the filename, then one file per snapshot is
written and the "*" character is replaced with the timestep value.
For example, tmp.dump.* becomes tmp.dump.0, tmp.dump.10000,
tmp.dump.20000, etc. This option is not available for the <I>dcd</I> and
<I>xtc</I> styles. Note that the <A HREF = "dump_modify.html">dump_modify pad</A>
command can be used to insure all timestep numbers are the same length
(e.g. 00010), which can make it easier to read a series of dump files
in order by some post-processing tools.
</P>
<P>If a "%" character appears in the filename, then one file is written
for each processor and the "%" character is replaced with the
processor ID from 0 to P-1. For example, tmp.dump.% becomes
tmp.dump.0, tmp.dump.1, ... tmp.dump.P-1, etc. This creates smaller
files and can be a fast mode of output on parallel machines that
support parallel I/O for output. This option is not available for the
<I>dcd</I>, <I>xtc</I>, and <I>xyz</I> styles.
</P>
<P>Note that the "*" and "%" characters can be used together to produce a
large number of small dump files!
</P>
<P>If the filename ends with ".bin", the dump file (or files, if "*" or
"%" is also used) is written in binary format. A binary dump file
will be about the same size as a text version, but will typically
write out much faster. Of course, when post-processing, you will need
to convert it back to text format (see the <A HREF = "Section_tools.html#binary">binary2txt
tool</A>) or write your own code to read the
binary file. The format of the binary file can be understood by
looking at the tools/binary2txt.cpp file. This option is only
available for the <I>atom</I> and <I>custom</I> styles.
</P>
<P>If the filename ends with ".gz", the dump file (or files, if "*" or "%"
is also used) is written in gzipped format. A gzipped dump file will
be about 3x smaller than the text version, but will also take longer
to write. This option is not available for the <I>dcd</I> and <I>xtc</I>
styles.
</P>
<HR>
<P>This section explains the local attributes that can be specified as
part of the <I>local</I> style.
</P>
<P>The <I>index</I> attribute can be used to generate an index number from 1
to N for each line written into the dump file, where N is the total
number of local datums from all processors, or lines of output that
will appear in the snapshot. Note that because data from different
processors depend on what atoms they currently own, and atoms migrate
between processor, there is no guarantee that the same index will be
used for the same info (e.g. a particular bond) in successive
snapshots.
</P>
<P>The <I>c_ID</I> and <I>c_ID[N]</I> attributes allow local vectors or arrays
calculated by a <A HREF = "compute.html">compute</A> to be output. The ID in the
attribute should be replaced by the actual ID of the compute that has
been defined previously in the input script. See the
<A HREF = "compute.html">compute</A> command for details. There are computes for
calculating local information such as indices, types, and energies for
bonds and angles.
</P>
<P>Note that computes which calculate global or per-atom quantities, as
opposed to local quantities, cannot be output in a dump local command.
Instead, global quantities can be output by the <A HREF = "thermo_style.html">thermo_style
custom</A> command, and per-atom quantities can be
output by the dump custom command.
</P>
<P>If <I>c_ID</I> is used as a attribute, then the local vector calculated by
the compute is printed. If <I>c_ID[N]</I> is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length local
array calculated by the compute.
</P>
<P>The <I>f_ID</I> and <I>f_ID[N]</I> attributes allow local vectors or arrays
calculated by a <A HREF = "fix.html">fix</A> to be output. The ID in the attribute
should be replaced by the actual ID of the fix that has been defined
previously in the input script.
</P>
<P>If <I>f_ID</I> is used as a attribute, then the local vector calculated by
the fix is printed. If <I>f_ID[N]</I> is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length local
array calculated by the fix.
</P>
<HR>
<P>This section explains the atom attributes that can be specified as
part of the <I>custom</I> and <I>cfg</I> styles.
</P>
<P>The <I>id</I>, <I>mol</I>, <I>type</I>, <I>element</I>, <I>mass</I>, <I>vx</I>, <I>vy</I>, <I>vz</I>, <I>fx</I>, <I>fy</I>,
<I>fz</I>, <I>q</I> attributes are self-explanatory.
</P>
<P><I>Id</I> is the atom ID. <I>Mol</I> is the molecule ID, included in the data
file for molecular systems. <I>Type</I> is the atom type. <I>Element</I> is
typically the chemical name of an element, which you must assign to
each type via the <A HREF = "dump_modify.html">dump_modify element</A> command.
More generally, it can be any string you wish to associated with an
atom type. <I>Mass</I> is the atom mass. <I>Vx</I>, <I>vy</I>, <I>vz</I>, <I>fx</I>, <I>fy</I>,
<I>fz</I>, and <I>q</I> are components of atom velocity and force and atomic
charge.
</P>
<P>There are several options for outputting atom coordinates. The <I>x</I>,
<I>y</I>, <I>z</I> attributes write atom coordinates "unscaled", in the
appropriate distance <A HREF = "units.html">units</A> (Angstroms, sigma, etc). Use
<I>xs</I>, <I>ys</I>, <I>zs</I> if you want the coordinates "scaled" to the box size,
so that each value is 0.0 to 1.0. If the simulation box is triclinic
(tilted), then all atom coords will still be between 0.0 and 1.0. Use
<I>xu</I>, <I>yu</I>, <I>zu</I> if you want the coordinates "unwrapped" by the image
flags for each atom. Unwrapped means that if the atom has passed thru
a periodic boundary one or more times, the value is printed for what
the coordinate would be if it had not been wrapped back into the
periodic box. Note that using <I>xu</I>, <I>yu</I>, <I>zu</I> means that the
coordinate values may be far outside the box bounds printed with the
snapshot. Using <I>xsu</I>, <I>ysu</I>, <I>zsu</I> is similar to using <I>xu</I>, <I>yu</I>, <I>zu</I>,
except that the unwrapped coordinates are scaled by the box size. Atoms
that have passed through a periodic boundary will have the corresponding
cooordinate increased or decreased by 1.0.
</P>
<P>The image flags can be printed directly using the <I>ix</I>,
<I>iy</I>, <I>iz</I> attributes. The <A HREF = "dump_modify.html">dump_modify</A> command
describes in more detail what is meant by scaled vs unscaled
coordinates and the image flags.
</P>
<P>The <I>mux</I>, <I>muy</I>, <I>muz</I> attributes are specific to dipolar systems
defined with an atom style of <I>dipole</I>. They give the orientation of
the atom's point dipole moment. The <I>mu</I> attribute gives the
magnitude of the atom's dipole moment.
</P>
<P>The <I>radius</I> and <I>diameter</I> attributes are specific to extended
spherical particles that have a finite size, such as those defined
with an atom style of <I>sphere</I>.
</P>
<P>The <I>omegax</I>, <I>omegay</I>, and <I>omegaz</I> attributes are specific to
extended spherical or aspherical particles that have an angular
velocity. Only certain atom styles, such as <I>sphere</I> define this
quantity.
</P>
<P>The <I>angmomx</I>, <I>angmomy</I>, and <I>angmomz</I> attributes are specific to
extended aspherical particles that have an angular momentum. Only
the <I>ellipsoid</I> atom style defines this quantity.
</P>
<P>The <I>tqx</I>, <I>tqy</I>, <I>tqz</I> attributes are for extended spherical or
aspherical particles that can sustain a rotational torque due
to interactions with other particles.
</P>
<P>The <I>spin</I>, <I>eradius</I>, <I>ervel</I>, and <I>erforce</I> attributes are for
particles that represent nuclei and electrons modeled with the
electronic force field (EFF). See <A HREF = "atom_style.html">atom_style
electron</A> and <A HREF = "pair_eff.html">pair_style eff</A> for more
details.
</P>
<P>The <I>c_ID</I> and <I>c_ID[N]</I> attributes allow per-atom vectors or arrays
calculated by a <A HREF = "compute.html">compute</A> to be output. The ID in the
attribute should be replaced by the actual ID of the compute that has
been defined previously in the input script. See the
<A HREF = "compute.html">compute</A> command for details. There are computes for
calculating the per-atom energy, stress, centro-symmetry parameter,
and coordination number of individual atoms.
</P>
<P>Note that computes which calculate global or local quantities, as
opposed to per-atom quantities, cannot be output in a dump custom
command. Instead, global quantities can be output by the
<A HREF = "thermo_style.html">thermo_style custom</A> command, and local quantities
can be output by the dump local command.
</P>
<P>If <I>c_ID</I> is used as a attribute, then the per-atom vector calculated
by the compute is printed. If <I>c_ID[N]</I> is used, then N must be in
the range from 1-M, which will print the Nth column of the M-length
per-atom array calculated by the compute.
</P>
<P>The <I>f_ID</I> and <I>f_ID[N]</I> attributes allow vector or array per-atom
quantities calculated by a <A HREF = "fix.html">fix</A> to be output. The ID in the
attribute should be replaced by the actual ID of the fix that has been
defined previously in the input script. The <A HREF = "fix_ave_atom.html">fix
ave/atom</A> command is one that calculates per-atom
quantities. Since it can time-average per-atom quantities produced by
any <A HREF = "compute.html">compute</A>, <A HREF = "fix.html">fix</A>, or atom-style
<A HREF = "variable.html">variable</A>, this allows those time-averaged results to
be written to a dump file.
</P>
<P>If <I>f_ID</I> is used as a attribute, then the per-atom vector calculated
by the fix is printed. If <I>f_ID[N]</I> is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length
per-atom array calculated by the fix.
</P>
<P>The <I>v_name</I> attribute allows per-atom vectors calculated by a
<A HREF = "variable.html">variable</A> to be output. The name in the attribute
should be replaced by the actual name of the variable that has been
defined previously in the input script. Only an atom-style variable
can be referenced, since it is the only style that generates per-atom
values. Variables of style <I>atom</I> can reference individual atom
attributes, per-atom atom attributes, thermodynamic keywords, or
invoke other computes, fixes, or variables when they are evaluated, so
this is a very general means of creating quantities to output to a
dump file.
</P>
-<P>See <A HREF = "Section_modify.html">this section</A> of the manual for information
+<P>See <A HREF = "Section_modify.html">Section_modify</A> of the manual for information
on how to add new compute and fix styles to LAMMPS to calculate
per-atom quantities which could then be output into dump files.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>To write gzipped dump files, you must compile LAMMPS with the
-DLAMMPS_GZIP option - see the <A HREF = "Section_start.html#start_2">Making
LAMMPS</A> section of the documentation.
</P>
<P>The <I>xtc</I> style is part of the XTC package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info. This is
because some machines may not support the low-level XDR data format
that XTC files are written with, which will result in a compile-time
error when a low-level include file is not found. Putting this style
in a package makes it easy to exclude from a LAMMPS build for those
machines. However, the XTC package also includes two compatibility
header files and associated functions, which should be a suitable
substitute on machines that do not have the appropriate native header
files. This option can be invoked at build time by adding
-DLAMMPS_XDR to the CCFLAGS variable in the appropriate low-level
Makefile, e.g. src/MAKE/Makefile.foo. This compatibility mode has
been tested successfully on Cray XT3/XT4/XT5 and IBM BlueGene/L
machines and should also work on IBM BG/P, and Windows XP/Vista/7
machines.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump_image.html">dump image</A>, <A HREF = "dump_modify.html">dump_modify</A>,
<A HREF = "undump.html">undump</A>
</P>
<P><B>Default:</B>
</P>
<P>The defaults for the image style are listed on the <A HREF = "dump_image.html">dump
image</A> doc page.
</P>
</HTML>
diff --git a/doc/dump.txt b/doc/dump.txt
index 56df5f44a..be599aafb 100644
--- a/doc/dump.txt
+++ b/doc/dump.txt
@@ -1,527 +1,527 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
dump command :h3
"dump image"_dump_image.html command :h3
[Syntax:]
dump ID group-ID style N file args :pre
ID = user-assigned name for the dump :ulb,l
group-ID = ID of the group of atoms to be dumped :l
style = {atom} or {cfg} or {dcd} or {xtc} or {xyz} or {image} or {local} or {custom} :l
N = dump every this many timesteps :l
file = name of file to write dump info to :l
args = list of arguments for a particular style :l
{atom} args = none
{cfg} args = same as {custom} args, see below
{dcd} args = none
{xtc} args = none
{xyz} args = none :pre
{image} args = discussed on "dump image"_dump_image.html doc page :pre
{local} args = list of local attributes
possible attributes = index, c_ID, c_ID\[N\], f_ID, f_ID\[N\]
index = enumeration of local values
c_ID = local vector calculated by a compute with ID
c_ID\[N\] = Nth column of local array calculated by a compute with ID
f_ID = local vector calculated by a fix with ID
f_ID\[N\] = Nth column of local array calculated by a fix with ID :pre
{custom} args = list of atom attributes
possible attributes = id, mol, type, element, mass,
x, y, z, xs, ys, zs, xu, yu, zu,
xsu, ysu, zsu, ix, iy, iz,
vx, vy, vz, fx, fy, fz,
q, mux, muy, muz, mu,
radius, diameter, omegax, omegay, omegaz,
angmomx, angmomy, angmomz, tqx, tqy, tqz,
spin, eradius, ervel, erforce,
c_ID, c_ID\[N\], f_ID, f_ID\[N\], v_name :pre
id = atom ID
mol = molecule ID
type = atom type
element = name of atom element, as defined by "dump_modify"_dump_modify.html command
mass = atom mass
x,y,z = unscaled atom coordinates
xs,ys,zs = scaled atom coordinates
xu,yu,zu = unwrapped atom coordinates
xsu,ysu,zsu = scaled unwrapped atom coordinates
ix,iy,iz = box image that the atom is in
vx,vy,vz = atom velocities
fx,fy,fz = forces on atoms
q = atom charge
mux,muy,muz = orientation of dipole moment of atom
mu = magnitude of dipole moment of atom
radius,diameter = radius,diameter of spherical particle
omegax,omegay,omegaz = angular velocity of extended particle
angmomx,angmomy,angmomz = angular momentum of extended particle
tqx,tqy,tqz = torque on extended particles
spin = electron spin
eradius = electron radius
ervel = electron radial velocity
erforce = electron radial force
c_ID = per-atom vector calculated by a compute with ID
c_ID\[N\] = Nth column of per-atom array calculated by a compute with ID
f_ID = per-atom vector calculated by a fix with ID
f_ID\[N\] = Nth column of per-atom array calculated by a fix with ID
v_name = per-atom vector calculated by an atom-style variable with name :pre
:ule
[Examples:]
dump myDump all atom 100 dump.atom
dump 2 subgroup atom 50 dump.run.bin
dump 4a all custom 100 dump.myforce.* id type x y vx fx
dump 4b flow custom 100 dump.%.myforce id type c_myF\[3\] v_ke
dump 2 inner cfg 10 dump.snap.*.cfg id type xs ys zs vx vy vz
dump snap all cfg 100 dump.config.*.cfg id type xs ys zs id type c_Stress[2]
dump 1 all xtc 1000 file.xtc
dump e_data all custom 100 dump.eff id type x y z spin eradius fx fy fz eforce :pre
[Description:]
Dump a snapshot of atom quantities to one or more files every N
timesteps in one of several styles. The {image} style is the
exception; it creates a JPG or PPM image file of the atom
configuration every N timesteps, as discussed on the "dump
image"_dump_image.html doc page.
Only information for atoms in the specified group is dumped. The
"dump_modify thresh and region"_dump_modify.html commands can also
alter what atoms are included. Not all styles support all these
options; see details below.
As described below, the filename determines the kind of output (text
or binary or gzipped, one big file or one per timestep, one big file
or one per processor).
IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom written to a dump file may be slightly outside the simulation
box.
IMPORTANT NOTE: Unless the "dump_modify sort"_dump_modify.html option
is invoked, the lines of atom information written to dump files
(typically one line per atom) will be in an indeterminate order for
each snapshot. This is even true when running on a single processor,
if the "atom_modify sort"_atom_modify.html option is on, which it is
by default. In this case atoms are re-ordered periodically during a
simulation, due to spatial sorting. It is also true when running in
parallel, because data for a single snapshot is collected from
multiple processors.
For the {atom}, {custom}, {cfg}, and {local} styles, sorting is off by
default. For the {dcd}, {xtc}, and {xyz} styles, sorting by atom ID
is on by default. See the "dump_modify"_dump_modify.html doc page for
details.
:line
The {style} keyword determines what atom quantities are written to the
file and in what format. Settings made via the
"dump_modify"_dump_modify.html command can also alter the format of
individual values and the file itself.
The {atom}, {local}, and {custom} styles create files in a simple text
format that is self-explanatory when viewing a dump file. Many of the
LAMMPS "post-processing tools"_Section_tools.html, including
"Pizza.py"_http://www.sandia.gov/~sjplimp/pizza.html, work with
this format.
For post-processing purposes the {atom} and {custom} text files are
self-describing in the following sense.
The dimensions of the simulation box are included in each snapshot.
For an orthogonal simulation box this information is is formatted as:
ITEM: BOX BOUNDS xx yy zz
xlo xhi
ylo yhi
zlo zhi :pre
where xlo,xhi are the maximum extents of the simulation box in the
x-dimension, and similarly for y and z. The "xx yy zz" represent 6
characters that encode the style of boundary for each of the 6
simulation box boundaries (xlo,xhi and ylo,yhi and zlo,zhi). Each of
the 6 characters is either p = periodic, f = fixed, s = shrink wrap,
or m = shrink wrapped with a minimum value. See the
"boundary"_doc/boundary.html command for details.
For triclinic simulation boxes (non-orthogonal), an orthogonal
bounding box which encloses the triclinic simulation box is output,
along with the 3 tilt factors (xy, xz, yz) of the triclinic box,
formatted as follows:
ITEM: BOX BOUNDS xy xz yz xx yy zz
xlo_bound xhi_bound xy
ylo_bound yhi_bound xz
zlo_bound zhi_bound yz :pre
The presence of the text "xy xz yz" in the ITEM line indicates that
the 3 tilt factors will be included on each of the 3 following lines.
This bounding box is convenient for many visualization programs. The
meaning of the 6 character flags for "xx yy zz" is the same as above.
Note that the first two numbers on each line are now xlo_bound instead
of xlo, etc, since they repesent a bounding box. See "this
section"_Section_howto.html#howto_12 of the doc pages for a geometric
description of triclinic boxes, as defined by LAMMPS, simple formulas
for how the 6 bounding box extents (xlo_bound,xhi_bound,etc) are
calculated from the triclinic parameters, and how to transform those
parameters to and from other commonly used triclinic representations.
The "ITEM: ATOMS" line in each snapshot lists column descriptors for
the per-atom lines that follow. For example, the descriptors would be
"id type xs ys zs" for the default {atom} style, and would be the atom
attributes you specify in the dump command for the {custom} style.
For style {atom}, atom coordinates are written to the file, along with
the atom ID and atom type. By default, atom coords are written in a
scaled format (from 0 to 1). I.e. an x value of 0.25 means the atom
is at a location 1/4 of the distance from xlo to xhi of the box
boundaries. The format can be changed to unscaled coords via the
"dump_modify"_dump_modify.html settings. Image flags can also be
added for each atom via dump_modify.
Style {custom} allows you to specify a list of atom attributes to be
written to the dump file for each atom. Possible attributes are
listed above and will appear in the order specified. You cannot
specify a quantity that is not defined for a particular simulation -
such as {q} for atom style {bond}, since that atom style doesn't
assign charges. Dumps occur at the very end of a timestep, so atom
attributes will include effects due to fixes that are applied during
the timestep. An explanation of the possible dump custom attributes
is given below.
For style {local}, local output generated by "computes"_compute.html
and "fixes"_fix.html is used to gnerate lines of output that is
written to the dump file. This local data is typically calculated by
each processor based on the atoms it owns, but there may be zero or
more entities per atom, e.g. a list of bond distances. An explanation
of the possible dump local attributes is given below. Note that by
using input from the "compute
property/local"_compute_property_local.html command with dump local,
it is possible to generate information on bonds, angles, etc that can
be cut and pasted directly into a data file read by the
"read_data"_read_data.html command.
Style {cfg} has the same command syntax as style {custom} and writes
extended CFG format files, as used by the
"AtomEye"_http://mt.seas.upenn.edu/Archive/Graphics/A visualization
package. Since the extended CFG format uses a single snapshot of the
system per file, a wildcard "*" must be included in the filename, as
discussed below. The list of atom attributes for style {cfg} must
begin with either "id type xs ys zs" or "id type xsu ysu zsu" or
since these quantities are needed to
write the CFG files in the appropriate format (though the "id" and
"type" fields do not appear explicitly in the file). Any remaining
attributes will be stored as "auxiliary properties" in the CFG files.
Note that you will typically want to use the "dump_modify
element"_dump_modify.html command with CFG-formatted files, to
associate element names with atom types, so that AtomEye can render
atoms appropriately. When unwrapped coordinates {xsu}, {ysu}, and {zsu}
are requested, the nominal AtomEye periodic cell dimensions are expanded
by a large factor UNWRAPEXPAND = 10.0, which ensures atoms that are
displayed correctly for up to UNWRAPEXPAND/2 periodic boundary crossings
in any direction.
Beyond this, AtomEye will rewrap the unwrapped coordinates.
The expansion causes the atoms to be drawn farther
away from the viewer, but it is easy to zoom the atoms closer, and
the interatomic distances are unaffected.
The {dcd} style writes DCD files, a standard atomic trajectory format
used by the CHARMM, NAMD, and XPlor molecular dynamics packages. DCD
files are binary and thus may not be portable to different machines.
The number of atoms per snapshot cannot change with the {dcd} style.
The {unwrap} option of the "dump_modify"_dump_modify.html command
allows DCD coordinates to be written "unwrapped" by the image flags
for each atom. Unwrapped means that if the atom has passed through
a periodic boundary one or more times, the value is printed for what
the coordinate would be if it had not been wrapped back into the
periodic box. Note that these coordinates may thus be far outside
the box size stored with the snapshot.
The {xtc} style writes XTC files, a compressed trajectory format used
by the GROMACS molecular dynamics package, and described
"here"_http://manual.gromacs.org/current/online/xtc.html.
The precision used in XTC files can be adjusted via the
"dump_modify"_dump_modify.html command. The default value of 1000
means that coordinates are stored to 1/1000 nanometer accuracy. XTC
files are portable binary files written in the NFS XDR data format,
so that any machine which supports XDR should be able to read them.
The number of atoms per snapshot cannot change with the {xtc} style.
The {unwrap} option of the "dump_modify"_dump_modify.html command allows
XTC coordinates to be written "unwrapped" by the image flags for each
atom. Unwrapped means that if the atom has passed thru a periodic
boundary one or more times, the value is printed for what the
coordinate would be if it had not been wrapped back into the periodic
box. Note that these coordinates may thus be far outside the box size
stored with the snapshot.
The {xyz} style writes XYZ files, which is a simple text-based
coordinate format that many codes can read.
Note that DCD, XTC, and XYZ formatted files can be read directly by
"VMD"_http://www.ks.uiuc.edu/Research/vmd (a popular molecular viewing
-program). See "this section"_Section_tools.html#vmd of the manual and
-the tools/lmp2vmd/README.txt file for more information about support
-in VMD for reading and visualizing LAMMPS dump files.
+program). See "Section tools"_Section_tools.html#vmd of the manual
+and the tools/lmp2vmd/README.txt file for more information about
+support in VMD for reading and visualizing LAMMPS dump files.
:line
Dumps are performed on timesteps that are a multiple of N (including
timestep 0) and on the last timestep of a minimization if the
minimization converges. Note that this means a dump will not be
performed on the initial timestep after the dump command is invoked,
if the current timestep is not a multiple of N. This behavior can be
changed via the "dump_modify first"_dump_modify.html command, which
can be useful if the dump command is invoked after a minimization
ended on an arbitrary timestep. N can be changed between runs by
using the "dump_modify every"_dump_modify.html command (not allowed
for {dcd} style).
The specified filename determines how the dump file(s) is written.
The default is to write one large text file, which is opened when the
dump command is invoked and closed when an "undump"_undump.html
command is used or when LAMMPS exits. For the {dcd} and {xtc} styles,
this is a single large binary file.
Dump filenames can contain two wildcard characters. If a "*"
character appears in the filename, then one file per snapshot is
written and the "*" character is replaced with the timestep value.
For example, tmp.dump.* becomes tmp.dump.0, tmp.dump.10000,
tmp.dump.20000, etc. This option is not available for the {dcd} and
{xtc} styles. Note that the "dump_modify pad"_dump_modify.html
command can be used to insure all timestep numbers are the same length
(e.g. 00010), which can make it easier to read a series of dump files
in order by some post-processing tools.
If a "%" character appears in the filename, then one file is written
for each processor and the "%" character is replaced with the
processor ID from 0 to P-1. For example, tmp.dump.% becomes
tmp.dump.0, tmp.dump.1, ... tmp.dump.P-1, etc. This creates smaller
files and can be a fast mode of output on parallel machines that
support parallel I/O for output. This option is not available for the
{dcd}, {xtc}, and {xyz} styles.
Note that the "*" and "%" characters can be used together to produce a
large number of small dump files!
If the filename ends with ".bin", the dump file (or files, if "*" or
"%" is also used) is written in binary format. A binary dump file
will be about the same size as a text version, but will typically
write out much faster. Of course, when post-processing, you will need
to convert it back to text format (see the "binary2txt
tool"_Section_tools.html#binary) or write your own code to read the
binary file. The format of the binary file can be understood by
looking at the tools/binary2txt.cpp file. This option is only
available for the {atom} and {custom} styles.
If the filename ends with ".gz", the dump file (or files, if "*" or "%"
is also used) is written in gzipped format. A gzipped dump file will
be about 3x smaller than the text version, but will also take longer
to write. This option is not available for the {dcd} and {xtc}
styles.
:line
This section explains the local attributes that can be specified as
part of the {local} style.
The {index} attribute can be used to generate an index number from 1
to N for each line written into the dump file, where N is the total
number of local datums from all processors, or lines of output that
will appear in the snapshot. Note that because data from different
processors depend on what atoms they currently own, and atoms migrate
between processor, there is no guarantee that the same index will be
used for the same info (e.g. a particular bond) in successive
snapshots.
The {c_ID} and {c_ID\[N\]} attributes allow local vectors or arrays
calculated by a "compute"_compute.html to be output. The ID in the
attribute should be replaced by the actual ID of the compute that has
been defined previously in the input script. See the
"compute"_compute.html command for details. There are computes for
calculating local information such as indices, types, and energies for
bonds and angles.
Note that computes which calculate global or per-atom quantities, as
opposed to local quantities, cannot be output in a dump local command.
Instead, global quantities can be output by the "thermo_style
custom"_thermo_style.html command, and per-atom quantities can be
output by the dump custom command.
If {c_ID} is used as a attribute, then the local vector calculated by
the compute is printed. If {c_ID\[N\]} is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length local
array calculated by the compute.
The {f_ID} and {f_ID\[N\]} attributes allow local vectors or arrays
calculated by a "fix"_fix.html to be output. The ID in the attribute
should be replaced by the actual ID of the fix that has been defined
previously in the input script.
If {f_ID} is used as a attribute, then the local vector calculated by
the fix is printed. If {f_ID\[N\]} is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length local
array calculated by the fix.
:line
This section explains the atom attributes that can be specified as
part of the {custom} and {cfg} styles.
The {id}, {mol}, {type}, {element}, {mass}, {vx}, {vy}, {vz}, {fx}, {fy},
{fz}, {q} attributes are self-explanatory.
{Id} is the atom ID. {Mol} is the molecule ID, included in the data
file for molecular systems. {Type} is the atom type. {Element} is
typically the chemical name of an element, which you must assign to
each type via the "dump_modify element"_dump_modify.html command.
More generally, it can be any string you wish to associated with an
atom type. {Mass} is the atom mass. {Vx}, {vy}, {vz}, {fx}, {fy},
{fz}, and {q} are components of atom velocity and force and atomic
charge.
There are several options for outputting atom coordinates. The {x},
{y}, {z} attributes write atom coordinates "unscaled", in the
appropriate distance "units"_units.html (Angstroms, sigma, etc). Use
{xs}, {ys}, {zs} if you want the coordinates "scaled" to the box size,
so that each value is 0.0 to 1.0. If the simulation box is triclinic
(tilted), then all atom coords will still be between 0.0 and 1.0. Use
{xu}, {yu}, {zu} if you want the coordinates "unwrapped" by the image
flags for each atom. Unwrapped means that if the atom has passed thru
a periodic boundary one or more times, the value is printed for what
the coordinate would be if it had not been wrapped back into the
periodic box. Note that using {xu}, {yu}, {zu} means that the
coordinate values may be far outside the box bounds printed with the
snapshot. Using {xsu}, {ysu}, {zsu} is similar to using {xu}, {yu}, {zu},
except that the unwrapped coordinates are scaled by the box size. Atoms
that have passed through a periodic boundary will have the corresponding
cooordinate increased or decreased by 1.0.
The image flags can be printed directly using the {ix},
{iy}, {iz} attributes. The "dump_modify"_dump_modify.html command
describes in more detail what is meant by scaled vs unscaled
coordinates and the image flags.
The {mux}, {muy}, {muz} attributes are specific to dipolar systems
defined with an atom style of {dipole}. They give the orientation of
the atom's point dipole moment. The {mu} attribute gives the
magnitude of the atom's dipole moment.
The {radius} and {diameter} attributes are specific to extended
spherical particles that have a finite size, such as those defined
with an atom style of {sphere}.
The {omegax}, {omegay}, and {omegaz} attributes are specific to
extended spherical or aspherical particles that have an angular
velocity. Only certain atom styles, such as {sphere} define this
quantity.
The {angmomx}, {angmomy}, and {angmomz} attributes are specific to
extended aspherical particles that have an angular momentum. Only
the {ellipsoid} atom style defines this quantity.
The {tqx}, {tqy}, {tqz} attributes are for extended spherical or
aspherical particles that can sustain a rotational torque due
to interactions with other particles.
The {spin}, {eradius}, {ervel}, and {erforce} attributes are for
particles that represent nuclei and electrons modeled with the
electronic force field (EFF). See "atom_style
electron"_atom_style.html and "pair_style eff"_pair_eff.html for more
details.
The {c_ID} and {c_ID\[N\]} attributes allow per-atom vectors or arrays
calculated by a "compute"_compute.html to be output. The ID in the
attribute should be replaced by the actual ID of the compute that has
been defined previously in the input script. See the
"compute"_compute.html command for details. There are computes for
calculating the per-atom energy, stress, centro-symmetry parameter,
and coordination number of individual atoms.
Note that computes which calculate global or local quantities, as
opposed to per-atom quantities, cannot be output in a dump custom
command. Instead, global quantities can be output by the
"thermo_style custom"_thermo_style.html command, and local quantities
can be output by the dump local command.
If {c_ID} is used as a attribute, then the per-atom vector calculated
by the compute is printed. If {c_ID\[N\]} is used, then N must be in
the range from 1-M, which will print the Nth column of the M-length
per-atom array calculated by the compute.
The {f_ID} and {f_ID\[N\]} attributes allow vector or array per-atom
quantities calculated by a "fix"_fix.html to be output. The ID in the
attribute should be replaced by the actual ID of the fix that has been
defined previously in the input script. The "fix
ave/atom"_fix_ave_atom.html command is one that calculates per-atom
quantities. Since it can time-average per-atom quantities produced by
any "compute"_compute.html, "fix"_fix.html, or atom-style
"variable"_variable.html, this allows those time-averaged results to
be written to a dump file.
If {f_ID} is used as a attribute, then the per-atom vector calculated
by the fix is printed. If {f_ID\[N\]} is used, then N must be in the
range from 1-M, which will print the Nth column of the M-length
per-atom array calculated by the fix.
The {v_name} attribute allows per-atom vectors calculated by a
"variable"_variable.html to be output. The name in the attribute
should be replaced by the actual name of the variable that has been
defined previously in the input script. Only an atom-style variable
can be referenced, since it is the only style that generates per-atom
values. Variables of style {atom} can reference individual atom
attributes, per-atom atom attributes, thermodynamic keywords, or
invoke other computes, fixes, or variables when they are evaluated, so
this is a very general means of creating quantities to output to a
dump file.
-See "this section"_Section_modify.html of the manual for information
+See "Section_modify"_Section_modify.html of the manual for information
on how to add new compute and fix styles to LAMMPS to calculate
per-atom quantities which could then be output into dump files.
:line
[Restrictions:]
To write gzipped dump files, you must compile LAMMPS with the
-DLAMMPS_GZIP option - see the "Making
LAMMPS"_Section_start.html#start_2 section of the documentation.
The {xtc} style is part of the XTC package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info. This is
because some machines may not support the low-level XDR data format
that XTC files are written with, which will result in a compile-time
error when a low-level include file is not found. Putting this style
in a package makes it easy to exclude from a LAMMPS build for those
machines. However, the XTC package also includes two compatibility
header files and associated functions, which should be a suitable
substitute on machines that do not have the appropriate native header
files. This option can be invoked at build time by adding
-DLAMMPS_XDR to the CCFLAGS variable in the appropriate low-level
Makefile, e.g. src/MAKE/Makefile.foo. This compatibility mode has
been tested successfully on Cray XT3/XT4/XT5 and IBM BlueGene/L
machines and should also work on IBM BG/P, and Windows XP/Vista/7
machines.
[Related commands:]
"dump image"_dump_image.html, "dump_modify"_dump_modify.html,
"undump"_undump.html
[Default:]
The defaults for the image style are listed on the "dump
image"_dump_image.html doc page.
diff --git a/doc/dump_image.html b/doc/dump_image.html
index 65eda7079..1e07899d3 100644
--- a/doc/dump_image.html
+++ b/doc/dump_image.html
@@ -1,455 +1,455 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>dump image command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>dump ID group-ID image N file color diameter keyword value ...
</PRE>
<UL><LI>ID = user-assigned name for the dump
<LI>group-ID = ID of the group of atoms to be imaged
<LI>image = style of dump command (other styles <I>atom</I> or <I>cfg</I> or <I>dcd</I> or <I>xtc</I> or <I>xyz</I> or <I>local</I> or <I>custom</I> are discussed on the <A HREF = "dump.html">dump</A> doc page)
<LI>N = dump every this many timesteps
<LI>file = name of file to write image to
<LI>color = atom attribute that determines color of each atom
<LI>diameter = atom attribute that determines size of each atom
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>adiam</I> or <I>atom</I> or <I>bond</I> or <I>size</I> or <I>view</I> or <I>center</I> or <I>up</I> or <I>zoom</I> or <I>persp</I> or <I>box</I> or <I>axes</I> or <I>shiny</I> or <I>ssao</I>
<PRE> <I>adiam</I> value = number = numeric value for atom diameter (distance units)
<I>atom</I> = yes/no = do or do not draw atoms
<I>bond</I> values = color width = color and width of bonds
color = <I>atom</I> or <I>type</I> or <I>none</I>
width = number or <I>atom</I> or <I>type</I> or <I>none</I>
number = numeric value for bond width (distance units)
<I>size</I> values = width height = size of images
width = width of image in # of pixels
height = height of image in # of pixels
<I>view</I> values = theta phi = view of simulation box
theta = view angle from +z axis (degrees)
phi = azimuthal view angle (degrees)
theta or phi can be a variable (see below)
<I>center</I> values = flag Cx Cy Cz = center point of image
flag = "s" for static, "d" for dynamic
Cx,Cy,Cz = center point of image as fraction of box dimension (0.5 = center of box)
Cx,Cy,Cz can be variables (see below)
<I>up</I> values = Ux Uy Uz = direction that is "up" in image
Ux,Uy,Uz = components of up vector
Ux,Uy,Uz can be variables (see below)
<I>zoom</I> value = zfactor = size that simulation box appears in image
zfactor = scale image size by factor > 1 to enlarge, factor < 1 to shrink
zfactor can be a variable (see below)
<I>persp</I> value = pfactor = amount of "perspective" in image
pfactor = amount of perspective (0 = none, < 1 = some, > 1 = highly skewed)
pfactor can be a variable (see below)
<I>box</I> values = yes/no diam = draw outline of simulation box
yes/no = do or do not draw simulation box lines
diam = diameter of box lines as fraction of shortest box length
<I>axes</I> values = yes/no length diam = draw xyz axes
yes/no = do or do not draw xyz axes lines next to simulation box
length = length of axes lines as fraction of respective box lengths
diam = diameter of axes lines as fraction of shortest box length
<I>shiny</I> value = sfactor = shinyness of spheres and cylinders
sfactor = shinyness of spheres and cylinders from 0.0 to 1.0
<I>ssao</I> value = yes/no seed dfactor = SSAO depth shading
yes/no = turn depth shading on/off
seed = random # seed (positive integer)
dfactor = strength of shading from 0.0 to 1.0
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>dump myDump all image 100 dump.*.jpg type type
</PRE>
<P><B>Description:</B>
</P>
<P>Dump a high-quality ray-traced image of the atom configuration every N
timesteps as either a JPG or PPM file. A series of such images can
easily be converted into an animated movie of your simulation; see
further details below. Other dump styles store snapshots of numerical
data asociated with atoms in various formats, as discussed on the
<A HREF = "dump.html">dump</A> doc page.
</P>
<P>Here are two sample images, rendered as 1024x1024 JPG files. Click to
see the full-size images:
</P>
<DIV ALIGN=center>
<A HREF = "JPG/dump1.jpg"><IMG SRC = "JPG/dump1_small.jpg"></A>
<A HREF = "JPG/dump2.jpg"><IMG SRC = "JPG/dump2_small.jpg"></A>
</DIV>
<P>Only atoms in the specified group are rendered in the image. The
<A HREF = "dump_modify.html">dump_modify region and thresh</A> commands can also
alter what atoms are included in the image.
</P>
<P>The filename suffix determines whether a JPG or PPM file is created.
If the suffix is ".jpg" or ".jpeg", then a JPG file is created, else a
PPM file is created, which is a text-based format. To write out JPG
files, you must build LAMMPS with a JPEG library. See <A HREF = "Section_start.html#start_2_4">this
section</A> of the manual for instructions
on how to do this.
</P>
<P>IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom in the image may be slightly outside the simulation box.
</P>
<HR>
<P>Dumps are performed on timesteps that are a multiple of N (including
timestep 0) and on the last timestep of a minimization if the
minimization converges. Note that this means a dump will not be
performed on the initial timestep after the dump command is invoked,
if the current timestep is not a multiple of N. This behavior can be
changed via the <A HREF = "dump_modify.html">dump_modify first</A> command, which
can be useful if the dump command is invoked after a minimization
ended on an arbitrary timestep. N can be changed between runs by
using the <A HREF = "dump_modify.html">dump_modify every</A> command.
</P>
<P>Dump image filenames must contain a wildcard character "*", so that
one image file per snapshot is written. The "*" character is replaced
with the timestep value. For example, tmp.dump.*.jpg becomes
tmp.dump.0.jpg, tmp.dump.10000.jpg, tmp.dump.20000.jpg, etc. Note
that the <A HREF = "dump_modify.html">dump_modify pad</A> command can be used to
insure all timestep numbers are the same length (e.g. 00010), which
can make it easier to convert a series of images into a movie in the
correct ordering.
</P>
<HR>
<P>The <I>color</I> and <I>diameter</I> settings determine the color and size of
atoms rendered in the image. They can be any atom attribute defined
for the <A HREF = "dump.html">dump custom</A> command, including <I>type</I> and
<I>element</I>. This includes per-atom quantities calculated by a
<A HREF = "compute.html">compute</A>, <A HREF = "fix.html">fix</A>, or <A HREF = "variable.html">variable</A>,
which are prefixed by "c_", "f_", or "v_" respectively. Note that the
<I>diameter</I> setting can be overridden with a numeric value by the
optional <I>adiam</I> keyword, in which case you can specify the <I>diameter</I>
setting with any valid atom attribute.
</P>
<P>If <I>type</I> is specified for the <I>color</I> setting, then the color of each
atom is determined by its atom type. By default the mapping of types
to colors is as follows:
</P>
<UL><LI>type 1 = red
<LI>type 2 = green
<LI>type 3 = blue
<LI>type 4 = yellow
<LI>type 5 = aqua
<LI>type 6 = cyan
</UL>
<P>and repeats itself for types > 6. This mapping can be changed by the
<A HREF = "dump_modify.html">dump_modify acolor</A> command.
</P>
<P>If <I>type</I> is specified for the <I>diameter</I> setting then the diameter of
each atom is determined by its atom type. By default all types have
diameter 1.0. This mapping can be changed by the <A HREF = "dump_modify.html">dump_modify
adiam</A> command.
</P>
<P>If <I>element</I> is specified for the <I>color</I> and/or <I>diameter</I> setting,
then the color and/or diameter of each atom is determined by which
element it is, which in turn is specified by the element-to-type
mapping specified by the "dump_modify element" command. By default
every atom type is C (carbon). Every element has a color and diameter
associated with it, which is the same as the colors and sizes used by
the <A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A> visualization package.
</P>
<P>If other atom attributes are used for the <I>color</I> or <I>diameter</I>
settings, they are interpreted in the following way.
</P>
<P>If "vx", for example, is used as the <I>color</I> setting, then the color
of the atom will depend on the x-component of its velocity. The
association of a per-atom value with a specific color is determined by
a "color map", which can be specified via the
<A HREF = "dump_modify.html">dump_modify</A> command. The basic idea is that the
atom-attribute will be within a range of values, and every value
within the range is mapped to a specific color. Depending on how the
color map is defined, that mapping can take place via interpolation so
that a value of -3.2 is halfway between "red" and "blue", or
discretely so that the value of -3.2 is "orange".
</P>
<P>If "vx", for example, is used as the <I>diameter</I> setting, then the atom
will be rendered using the x-component of its velocity as the
diameter. If the per-atom value <= 0.0, them the atom will not be
drawn. Note that finite-size spherical particles, as defined by
<A HREF = "atom_style.html">atom_style sphere</A> define a per-particle radius or
diameter, which can be used as the <I>diameter</I> setting.
</P>
<HR>
<P>The various kewords listed above control how the image is rendered.
As listed below, all of the keywords have defaults, most of which you
will likely not need to change. The <A HREF = "dump_modify.html">dump modify</A>
also has options specific to the dump image style, particularly for
assigning colors to atoms, bonds, and other image features.
</P>
<HR>
<P>The <I>adiam</I> keyword allows you to override the <I>diameter</I> setting to a
per-atom attribute with a specified numeric value. All atoms will be
drawn with that diameter, e.g. 1.5, which is in whatever distance
<A HREF = "units.html">units</A> the input script defines, e.g. Angstroms.
</P>
<P>The <I>atom</I> keyword allow you to turn off the drawing of all atoms,
if the specified value is <I>no</I>.
</P>
<P>The <I>bond</I> keyword allows to you to alter how bonds are drawn. A bond
is only drawn if both atoms in the bond are being drawn due to being
in the specified group and due to other selection criteria
(e.g. region, threshhold settings of the
<A HREF = "dump_modify.html">dump_modify</A> command). By default, bonds are drawn
if they are defined in the input data file as read by the
<A HREF = "read_data.html">read_data</A> command. Using <I>none</I> for both the bond
<I>color</I> and <I>width</I> value will turn off the drawing of all bonds.
</P>
<P>If <I>atom</I> is specified for the bond <I>color</I> value, then each bond is
drawn in 2 halves, with the color of each half being the color of the
atom at that end of the bond.
</P>
<P>If <I>type</I> is specified for the <I>color</I> value, then the color of each
bond is determined by its bond type. By default the mapping of bond
types to colors is as follows:
</P>
<UL><LI>type 1 = red
<LI>type 2 = green
<LI>type 3 = blue
<LI>type 4 = yellow
<LI>type 5 = aqua
<LI>type 6 = cyan
</UL>
<P>and repeats itself for bond types > 6. This mapping can be changed by
the <A HREF = "dump_modify.html">dump_modify bcolor</A> command.
</P>
<P>The bond <I>width</I> value can be a numeric value or <I>atom</I> or <I>type</I> (or
<I>none</I> as indicated above).
</P>
<P>If a numeric value is specified, then all bonds will be drawn as
cylinders with that diameter, e.g. 1.0, which is in whatever distance
<A HREF = "units.html">units</A> the input script defines, e.g. Angstroms.
</P>
<P>If <I>atom</I> is specified for the <I>width</I> value, then each bond
will be drawn with a width corresponding to the minimum diameter
of the 2 atoms in the bond.
</P>
<P>If <I>type</I> is specified for the <I>width</I> value then the diameter of each
bond is determined by its bond type. By default all types have
diameter 0.5. This mapping can be changed by the <A HREF = "dump_modify.html">dump_modify
bdiam</A> command.
</P>
<HR>
<P>The <I>size</I> keyword sets the width and height of the created images,
i.e. the number of pixels in each direction.
</P>
<HR>
<P>The <I>view</I>, <I>center</I>, <I>up</I>, <I>zoom</I>, and <I>persp</I> values determine how
3d simulation space is mapped to the 2d plane of the image. Basically
they control how the simulation box appears in the image.
</P>
<P>All of the <I>view</I>, <I>center</I>, <I>up</I>, <I>zoom</I>, and <I>persp</I> values can be
specified as numeric quantities, whose meaning is explained below.
Any of them can also be specified as an <A HREF = "variable.html">equal-style
variable</A>, by using v_name as the value, where "name" is
the variable name. In this case the variable will be evaluated on the
timestep each image is created to create a new value. If the
equal-style variable is time-dependent, this is a means of changing
the way the simulation box appears from image to image, effectively
doing a pan or fly-by view of your simulation.
</P>
<P>The <I>view</I> keyword determines the viewpoint from which the simulation
box is viewed, looking towards the <I>center</I> point. The <I>theta</I> value
is the vertical angle from the +z axis, and must be an angle from 0 to
180 degrees. The <I>phi</I> value is an azimuthal angle around the z axis
and can be positive or negative. A value of 0.0 is a view along the
+x axis, towards the <I>center</I> point. If <I>theta</I> or <I>phi</I> are
specified via variables, then the variable values should be in
degrees.
</P>
<P>The <I>center</I> keyword determines the point in simulation space that
will be at the center of the image. <I>Cx</I>, <I>Cy</I>, and <I>Cz</I> are
speficied as fractions of the box dimensions, so that (0.5,0.5,0.5) is
the center of the simulation box. These values do not have to be
between 0.0 and 1.0, if you want the simulation box to be offset from
the center of the image. Note, however, that if you choose strange
values for <I>Cx</I>, <I>Cy</I>, or <I>Cz</I> you may get a blank image. Internally,
<I>Cx</I>, <I>Cy</I>, and <I>Cz</I> are converted into a point in simulation space.
If <I>flag</I> is set to "s" for static, then this conversion is done once,
at the time the dump command is issued. If <I>flag</I> is set to "d" for
dynamic then the conversion is performed every time a new image is
created. If the box size or shape is changing, this will adjust the
center point in simulation space.
</P>
<P>The <I>up</I> keyword determines what direction in simulation space will be
"up" in the image. Internally it is stored as a vector that is in the
plane perpendicular to the view vector implied by the <I>theta</I> and
<I>pni</I> values, and which is also in the plane defined by the view
vector and user-specified up vector. Thus this internal vector is
computed from the user-specified <I>up</I> vector as
</P>
<PRE>up_internal = view cross (up cross view)
</PRE>
<P>This means the only restriction on the specified <I>up</I> vector is that
it cannot be parallel to the <I>view</I> vector, implied by the <I>theta</I> and
<I>phi</I> values.
</P>
<P>The <I>zoom</I> keyword scales the size of the simulation box as it appears
in the image. The default <I>zfactor</I> value of 1 should display an
image mostly filled by the atoms in the simulation box. A <I>zfactor</I> >
1 will make the simulation box larger; a <I>zfactor</I> < 1 will make it
smaller. <I>Zfactor</I> must be a value > 0.0.
</P>
<P>The <I>persp</I> keyword determines how much depth perspective is present
in the image. Depth perspective makes lines that are parallel in
simulation space appear non-parallel in the image. A <I>pfactor</I> value
of 0.0 means that parallel lines will meet at infininty (1.0/pfactor),
which is an orthographic rendering with no persepctive. A <I>pfactor</I>
value between 0.0 and 1.0 will introduce more perspective. A <I>pfactor</I>
value > 1 will create a highly skewed image with a large amount of
perspective.
</P>
<P>IMPORTANT NOTE: The <I>persp</I> keyword is not yet supported as an option.
</P>
<HR>
<P>The <I>box</I> keyword determines how the simulation box boundaries are
rendered as thin cylinders in the image. If <I>no</I> is set, then the box
boundaries are not drawn and the <I>diam</I> setting is ignored. If <I>yes</I>
is set, the 12 edges of the box are drawn, with a diameter that is a
fraction of the shortest box length in x,y,z (for 3d) or x,y (for 2d).
The color of the box boundaries can be set with the <A HREF = "dump_modify.html">dump_modify
boxcolor</A> command.
</P>
<P>The <I>axes</I> keyword determines how the coordinate axes are rendered as
thin cylinders in the image. If <I>no</I> is set, then the axes are not
drawn and the <I>length</I> and <I>diam</I> settings are ignored. If <I>yes</I> is
set, 3 thin cylinders are drawn to represent the x,y,z axes in colors
red,green,blue. The origin of these cylinders will be offset from the
lower left corner of the box by 10%. The <I>length</I> setting determines
how long the cylinders will be as a fraction of the respective box
lengths. The <I>diam</I> setting determines their thickness as a fraction
of the shortest box length in x,y,z (for 3d) or x,y (for 2d).
</P>
<HR>
<P>The <I>shiny</I> keyword determines how shiny the objects rendered in the
image will appear. The <I>sfactor</I> value must be a value 0.0 <=
<I>sfactor</I> <= 1.0, where <I>sfactor</I> = 1 is a highly reflective surface
and <I>sfactor</I> = 0 is a rough non-shiny surface.
</P>
<P>The <I>ssao</I> keyword turns on/off a screen space ambient occlusion
(SSAO) model for depth shading. If <I>yes</I> is set, then atoms further
away from the viewer are darkened via a randomized process, which is
perceived as depth. The calculation of this effect can increase the
cost of computing the image by roughly 2x. The strength of the effect
can be scaled by the <I>dfactor</I> parameter. If <I>no</I> is set, no depth
shading is performed.
</P>
<HR>
<P>A series of JPG or PPM images can be converted into a movie file and
then played as a movie using commonly available tools.
</P>
<P>Convert JPG or PPM files into an animated GIF or MPEG or other movie
file:
</P>
<UL><LI>a) Use the ImageMagick convert program.
<PRE>% convert *.jpg foo.gif
% convert *.ppm foo.mpg
</PRE>
<LI>b) Use QuickTime.
<P>Select "Open Image Sequence" under the File menu
Load the images into QuickTime to animate them
Select "Export" under the File menu
Save the movie as a QuickTime movie (*.mov) or in another format
</P>
<LI>c) Windows-based tool.
</UL>
<P>If someone tells us how to do this via a common Windows-based tool,
we'll post the instructions here.
</P>
<P>Play the movie:
</P>
<UL><LI>a) Use your browser to view an animated GIF movie.
<P>Select "Open File" under the File menu
Load the animated GIF file
</P>
<LI>b) Use the freely available mplayer tool to view an MPEG movie.
<PRE>% mplayer foo.mpg
</PRE>
<LI>c) Use the <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A>
<A HREF = "http://www.sandia.gov/~sjplimp/pizza/doc/animate.html">animate tool</A>,
which works directly on a series of image files.
<PRE>a = animate("foo*.jpg")
</PRE>
<LI>d) QuickTime and other Windows-based media players can
obviously play movie files directly.
</UL>
<HR>
-<P>See <A HREF = "Section_modify.html">this section</A> of the manual for information
+<P>See <A HREF = "Section_modify.html">Section_modify</A> of the manual for information
on how to add new compute and fix styles to LAMMPS to calculate
per-atom quantities which could then be output into dump files.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>To write JPG images, you must use a -DLAMMPS_JPEG switch when building
LAMMPS and link with a JPEG library. See the <A HREF = "Section_start.html#start_2_4">Making
LAMMPS</A> section of the documentation for
details.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "dump.html">dump</A>, <A HREF = "dump_modify.html">dump_modify</A>, <A HREF = "undump.html">undump</A>
</P>
<P><B>Default:</B>
</P>
<P>The defaults for the keywords are as follows:
</P>
<UL><LI>adiam = not specified (use diameter setting)
<LI>atom = yes
<LI>bond = none none (if no bonds in system)
<LI>bond = atom 0.5 (if bonds in system)
<LI>size = 512 512
<LI>view = 60 30 (for 3d)
<LI>view = 0 0 (for 2d)
<LI>center = s 0.5 0.5 0.5
<LI>up = 0 0 1 (for 3d)
<LI>up = 0 1 0 (for 2d)
<LI>zoom = 1.0
<LI>persp = 0.0
<LI>box = yes 0.02
<LI>axes = no 0.0 0.0
<LI>shiny = 1.0
<LI>ssao = no
</UL>
</HTML>
diff --git a/doc/dump_image.txt b/doc/dump_image.txt
index 08a74c6de..6637f0b46 100644
--- a/doc/dump_image.txt
+++ b/doc/dump_image.txt
@@ -1,439 +1,439 @@
"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 image command :h3
[Syntax:]
dump ID group-ID image N file color diameter keyword value ... :pre
ID = user-assigned name for the dump :ulb,l
group-ID = ID of the group of atoms to be imaged :l
image = style of dump command (other styles {atom} or {cfg} or {dcd} or {xtc} or {xyz} or {local} or {custom} are discussed on the "dump"_dump.html doc page) :l
N = dump every this many timesteps :l
file = name of file to write image to :l
color = atom attribute that determines color of each atom :l
diameter = atom attribute that determines size of each atom :l
zero or more keyword/value pairs may be appended :l
keyword = {adiam} or {atom} or {bond} or {size} or {view} or {center} or {up} or {zoom} or {persp} or {box} or {axes} or {shiny} or {ssao} :l
{adiam} value = number = numeric value for atom diameter (distance units)
{atom} = yes/no = do or do not draw atoms
{bond} values = color width = color and width of bonds
color = {atom} or {type} or {none}
width = number or {atom} or {type} or {none}
number = numeric value for bond width (distance units)
{size} values = width height = size of images
width = width of image in # of pixels
height = height of image in # of pixels
{view} values = theta phi = view of simulation box
theta = view angle from +z axis (degrees)
phi = azimuthal view angle (degrees)
theta or phi can be a variable (see below)
{center} values = flag Cx Cy Cz = center point of image
flag = "s" for static, "d" for dynamic
Cx,Cy,Cz = center point of image as fraction of box dimension (0.5 = center of box)
Cx,Cy,Cz can be variables (see below)
{up} values = Ux Uy Uz = direction that is "up" in image
Ux,Uy,Uz = components of up vector
Ux,Uy,Uz can be variables (see below)
{zoom} value = zfactor = size that simulation box appears in image
zfactor = scale image size by factor > 1 to enlarge, factor < 1 to shrink
zfactor can be a variable (see below)
{persp} value = pfactor = amount of "perspective" in image
pfactor = amount of perspective (0 = none, < 1 = some, > 1 = highly skewed)
pfactor can be a variable (see below)
{box} values = yes/no diam = draw outline of simulation box
yes/no = do or do not draw simulation box lines
diam = diameter of box lines as fraction of shortest box length
{axes} values = yes/no length diam = draw xyz axes
yes/no = do or do not draw xyz axes lines next to simulation box
length = length of axes lines as fraction of respective box lengths
diam = diameter of axes lines as fraction of shortest box length
{shiny} value = sfactor = shinyness of spheres and cylinders
sfactor = shinyness of spheres and cylinders from 0.0 to 1.0
{ssao} value = yes/no seed dfactor = SSAO depth shading
yes/no = turn depth shading on/off
seed = random # seed (positive integer)
dfactor = strength of shading from 0.0 to 1.0 :pre
:ule
[Examples:]
dump myDump all image 100 dump.*.jpg type type :pre
[Description:]
Dump a high-quality ray-traced image of the atom configuration every N
timesteps as either a JPG or PPM file. A series of such images can
easily be converted into an animated movie of your simulation; see
further details below. Other dump styles store snapshots of numerical
data asociated with atoms in various formats, as discussed on the
"dump"_dump.html doc page.
Here are two sample images, rendered as 1024x1024 JPG files. Click to
see the full-size images:
<DIV ALIGN=center>
:image(JPG/dump1_small.jpg,JPG/dump1.jpg)
:image(JPG/dump2_small.jpg,JPG/dump2.jpg)
</DIV>
Only atoms in the specified group are rendered in the image. The
"dump_modify region and thresh"_dump_modify.html commands can also
alter what atoms are included in the image.
The filename suffix determines whether a JPG or PPM file is created.
If the suffix is ".jpg" or ".jpeg", then a JPG file is created, else a
PPM file is created, which is a text-based format. To write out JPG
files, you must build LAMMPS with a JPEG library. See "this
section"_Section_start.html#start_2_4 of the manual for instructions
on how to do this.
IMPORTANT NOTE: Because periodic boundary conditions are enforced only
on timesteps when neighbor lists are rebuilt, the coordinates of an
atom in the image may be slightly outside the simulation box.
:line
Dumps are performed on timesteps that are a multiple of N (including
timestep 0) and on the last timestep of a minimization if the
minimization converges. Note that this means a dump will not be
performed on the initial timestep after the dump command is invoked,
if the current timestep is not a multiple of N. This behavior can be
changed via the "dump_modify first"_dump_modify.html command, which
can be useful if the dump command is invoked after a minimization
ended on an arbitrary timestep. N can be changed between runs by
using the "dump_modify every"_dump_modify.html command.
Dump image filenames must contain a wildcard character "*", so that
one image file per snapshot is written. The "*" character is replaced
with the timestep value. For example, tmp.dump.*.jpg becomes
tmp.dump.0.jpg, tmp.dump.10000.jpg, tmp.dump.20000.jpg, etc. Note
that the "dump_modify pad"_dump_modify.html command can be used to
insure all timestep numbers are the same length (e.g. 00010), which
can make it easier to convert a series of images into a movie in the
correct ordering.
:line
The {color} and {diameter} settings determine the color and size of
atoms rendered in the image. They can be any atom attribute defined
for the "dump custom"_dump.html command, including {type} and
{element}. This includes per-atom quantities calculated by a
"compute"_compute.html, "fix"_fix.html, or "variable"_variable.html,
which are prefixed by "c_", "f_", or "v_" respectively. Note that the
{diameter} setting can be overridden with a numeric value by the
optional {adiam} keyword, in which case you can specify the {diameter}
setting with any valid atom attribute.
If {type} is specified for the {color} setting, then the color of each
atom is determined by its atom type. By default the mapping of types
to colors is as follows:
type 1 = red
type 2 = green
type 3 = blue
type 4 = yellow
type 5 = aqua
type 6 = cyan :ul
and repeats itself for types > 6. This mapping can be changed by the
"dump_modify acolor"_dump_modify.html command.
If {type} is specified for the {diameter} setting then the diameter of
each atom is determined by its atom type. By default all types have
diameter 1.0. This mapping can be changed by the "dump_modify
adiam"_dump_modify.html command.
If {element} is specified for the {color} and/or {diameter} setting,
then the color and/or diameter of each atom is determined by which
element it is, which in turn is specified by the element-to-type
mapping specified by the "dump_modify element" command. By default
every atom type is C (carbon). Every element has a color and diameter
associated with it, which is the same as the colors and sizes used by
the "AtomEye"_atomeye visualization package.
:link(atomeye,http://mt.seas.upenn.edu/Archive/Graphics/A)
If other atom attributes are used for the {color} or {diameter}
settings, they are interpreted in the following way.
If "vx", for example, is used as the {color} setting, then the color
of the atom will depend on the x-component of its velocity. The
association of a per-atom value with a specific color is determined by
a "color map", which can be specified via the
"dump_modify"_dump_modify.html command. The basic idea is that the
atom-attribute will be within a range of values, and every value
within the range is mapped to a specific color. Depending on how the
color map is defined, that mapping can take place via interpolation so
that a value of -3.2 is halfway between "red" and "blue", or
discretely so that the value of -3.2 is "orange".
If "vx", for example, is used as the {diameter} setting, then the atom
will be rendered using the x-component of its velocity as the
diameter. If the per-atom value <= 0.0, them the atom will not be
drawn. Note that finite-size spherical particles, as defined by
"atom_style sphere"_atom_style.html define a per-particle radius or
diameter, which can be used as the {diameter} setting.
:line
The various kewords listed above control how the image is rendered.
As listed below, all of the keywords have defaults, most of which you
will likely not need to change. The "dump modify"_dump_modify.html
also has options specific to the dump image style, particularly for
assigning colors to atoms, bonds, and other image features.
:line
The {adiam} keyword allows you to override the {diameter} setting to a
per-atom attribute with a specified numeric value. All atoms will be
drawn with that diameter, e.g. 1.5, which is in whatever distance
"units"_units.html the input script defines, e.g. Angstroms.
The {atom} keyword allow you to turn off the drawing of all atoms,
if the specified value is {no}.
The {bond} keyword allows to you to alter how bonds are drawn. A bond
is only drawn if both atoms in the bond are being drawn due to being
in the specified group and due to other selection criteria
(e.g. region, threshhold settings of the
"dump_modify"_dump_modify.html command). By default, bonds are drawn
if they are defined in the input data file as read by the
"read_data"_read_data.html command. Using {none} for both the bond
{color} and {width} value will turn off the drawing of all bonds.
If {atom} is specified for the bond {color} value, then each bond is
drawn in 2 halves, with the color of each half being the color of the
atom at that end of the bond.
If {type} is specified for the {color} value, then the color of each
bond is determined by its bond type. By default the mapping of bond
types to colors is as follows:
type 1 = red
type 2 = green
type 3 = blue
type 4 = yellow
type 5 = aqua
type 6 = cyan :ul
and repeats itself for bond types > 6. This mapping can be changed by
the "dump_modify bcolor"_dump_modify.html command.
The bond {width} value can be a numeric value or {atom} or {type} (or
{none} as indicated above).
If a numeric value is specified, then all bonds will be drawn as
cylinders with that diameter, e.g. 1.0, which is in whatever distance
"units"_units.html the input script defines, e.g. Angstroms.
If {atom} is specified for the {width} value, then each bond
will be drawn with a width corresponding to the minimum diameter
of the 2 atoms in the bond.
If {type} is specified for the {width} value then the diameter of each
bond is determined by its bond type. By default all types have
diameter 0.5. This mapping can be changed by the "dump_modify
bdiam"_dump_modify.html command.
:line
The {size} keyword sets the width and height of the created images,
i.e. the number of pixels in each direction.
:line
The {view}, {center}, {up}, {zoom}, and {persp} values determine how
3d simulation space is mapped to the 2d plane of the image. Basically
they control how the simulation box appears in the image.
All of the {view}, {center}, {up}, {zoom}, and {persp} values can be
specified as numeric quantities, whose meaning is explained below.
Any of them can also be specified as an "equal-style
variable"_variable.html, by using v_name as the value, where "name" is
the variable name. In this case the variable will be evaluated on the
timestep each image is created to create a new value. If the
equal-style variable is time-dependent, this is a means of changing
the way the simulation box appears from image to image, effectively
doing a pan or fly-by view of your simulation.
The {view} keyword determines the viewpoint from which the simulation
box is viewed, looking towards the {center} point. The {theta} value
is the vertical angle from the +z axis, and must be an angle from 0 to
180 degrees. The {phi} value is an azimuthal angle around the z axis
and can be positive or negative. A value of 0.0 is a view along the
+x axis, towards the {center} point. If {theta} or {phi} are
specified via variables, then the variable values should be in
degrees.
The {center} keyword determines the point in simulation space that
will be at the center of the image. {Cx}, {Cy}, and {Cz} are
speficied as fractions of the box dimensions, so that (0.5,0.5,0.5) is
the center of the simulation box. These values do not have to be
between 0.0 and 1.0, if you want the simulation box to be offset from
the center of the image. Note, however, that if you choose strange
values for {Cx}, {Cy}, or {Cz} you may get a blank image. Internally,
{Cx}, {Cy}, and {Cz} are converted into a point in simulation space.
If {flag} is set to "s" for static, then this conversion is done once,
at the time the dump command is issued. If {flag} is set to "d" for
dynamic then the conversion is performed every time a new image is
created. If the box size or shape is changing, this will adjust the
center point in simulation space.
The {up} keyword determines what direction in simulation space will be
"up" in the image. Internally it is stored as a vector that is in the
plane perpendicular to the view vector implied by the {theta} and
{pni} values, and which is also in the plane defined by the view
vector and user-specified up vector. Thus this internal vector is
computed from the user-specified {up} vector as
up_internal = view cross (up cross view) :pre
This means the only restriction on the specified {up} vector is that
it cannot be parallel to the {view} vector, implied by the {theta} and
{phi} values.
The {zoom} keyword scales the size of the simulation box as it appears
in the image. The default {zfactor} value of 1 should display an
image mostly filled by the atoms in the simulation box. A {zfactor} >
1 will make the simulation box larger; a {zfactor} < 1 will make it
smaller. {Zfactor} must be a value > 0.0.
The {persp} keyword determines how much depth perspective is present
in the image. Depth perspective makes lines that are parallel in
simulation space appear non-parallel in the image. A {pfactor} value
of 0.0 means that parallel lines will meet at infininty (1.0/pfactor),
which is an orthographic rendering with no persepctive. A {pfactor}
value between 0.0 and 1.0 will introduce more perspective. A {pfactor}
value > 1 will create a highly skewed image with a large amount of
perspective.
IMPORTANT NOTE: The {persp} keyword is not yet supported as an option.
:line
The {box} keyword determines how the simulation box boundaries are
rendered as thin cylinders in the image. If {no} is set, then the box
boundaries are not drawn and the {diam} setting is ignored. If {yes}
is set, the 12 edges of the box are drawn, with a diameter that is a
fraction of the shortest box length in x,y,z (for 3d) or x,y (for 2d).
The color of the box boundaries can be set with the "dump_modify
boxcolor"_dump_modify.html command.
The {axes} keyword determines how the coordinate axes are rendered as
thin cylinders in the image. If {no} is set, then the axes are not
drawn and the {length} and {diam} settings are ignored. If {yes} is
set, 3 thin cylinders are drawn to represent the x,y,z axes in colors
red,green,blue. The origin of these cylinders will be offset from the
lower left corner of the box by 10%. The {length} setting determines
how long the cylinders will be as a fraction of the respective box
lengths. The {diam} setting determines their thickness as a fraction
of the shortest box length in x,y,z (for 3d) or x,y (for 2d).
:line
The {shiny} keyword determines how shiny the objects rendered in the
image will appear. The {sfactor} value must be a value 0.0 <=
{sfactor} <= 1.0, where {sfactor} = 1 is a highly reflective surface
and {sfactor} = 0 is a rough non-shiny surface.
The {ssao} keyword turns on/off a screen space ambient occlusion
(SSAO) model for depth shading. If {yes} is set, then atoms further
away from the viewer are darkened via a randomized process, which is
perceived as depth. The calculation of this effect can increase the
cost of computing the image by roughly 2x. The strength of the effect
can be scaled by the {dfactor} parameter. If {no} is set, no depth
shading is performed.
:line
A series of JPG or PPM images can be converted into a movie file and
then played as a movie using commonly available tools.
Convert JPG or PPM files into an animated GIF or MPEG or other movie
file:
a) Use the ImageMagick convert program. :ulb,l
% convert *.jpg foo.gif
% convert *.ppm foo.mpg :pre
b) Use QuickTime. :l
Select "Open Image Sequence" under the File menu
Load the images into QuickTime to animate them
Select "Export" under the File menu
Save the movie as a QuickTime movie (*.mov) or in another format
c) Windows-based tool. :ule,l
If someone tells us how to do this via a common Windows-based tool,
we'll post the instructions here.
Play the movie:
a) Use your browser to view an animated GIF movie. :ulb,l
Select "Open File" under the File menu
Load the animated GIF file
b) Use the freely available mplayer tool to view an MPEG movie. :l
% mplayer foo.mpg :pre
c) Use the "Pizza.py"_http://www.sandia.gov/~sjplimp/pizza.html
"animate tool"_http://www.sandia.gov/~sjplimp/pizza/doc/animate.html,
which works directly on a series of image files. :l
a = animate("foo*.jpg") :pre
d) QuickTime and other Windows-based media players can
obviously play movie files directly. :ule,l
:line
-See "this section"_Section_modify.html of the manual for information
+See "Section_modify"_Section_modify.html of the manual for information
on how to add new compute and fix styles to LAMMPS to calculate
per-atom quantities which could then be output into dump files.
:line
[Restrictions:]
To write JPG images, you must use a -DLAMMPS_JPEG switch when building
LAMMPS and link with a JPEG library. See the "Making
LAMMPS"_Section_start.html#start_2_4 section of the documentation for
details.
[Related commands:]
"dump"_dump.html, "dump_modify"_dump_modify.html, "undump"_undump.html
[Default:]
The defaults for the keywords are as follows:
adiam = not specified (use diameter setting)
atom = yes
bond = none none (if no bonds in system)
bond = atom 0.5 (if bonds in system)
size = 512 512
view = 60 30 (for 3d)
view = 0 0 (for 2d)
center = s 0.5 0.5 0.5
up = 0 0 1 (for 3d)
up = 0 1 0 (for 2d)
zoom = 1.0
persp = 0.0
box = yes 0.02
axes = no 0.0 0.0
shiny = 1.0
ssao = no :ul
diff --git a/doc/fix_addforce.html b/doc/fix_addforce.html
index 4fe72468f..60ead3703 100644
--- a/doc/fix_addforce.html
+++ b/doc/fix_addforce.html
@@ -1,176 +1,176 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix addforce command
</H3>
<H3>fix addforce/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID addforce fx fy fz keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>addforce = style name of this fix command
<LI>fx,fy,fz = force component values (force units)
-<LI>any of fx,fy,fz can be a variable (see below)
-
+<PRE> any of fx,fy,fz can be a variable (see below)
+</PRE>
<LI>zero or more keyword/value pairs may be appended to args
<LI>keyword = <I>region</I> or <I>energy</I>
<PRE> <I>region</I> value = region-ID
region-ID = ID of region atoms must be in to have added force
<I>energy</I> value = v_name
v_name = variable with name that calculates the potential energy of each atom in the added force field
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix kick flow addforce 1.0 0.0 0.0
fix kick flow addforce 1.0 0.0 v_oscillate
fix ff boundary addforce 0.0 0.0 v_push energy v_espace
</PRE>
<P><B>Description:</B>
</P>
<P>Add fx,fy,fz to the corresponding component of force for each atom in
the group. This command can be used to give an additional push to
atoms in a simulation, such as for a simulation of Poiseuille flow in
a channel.
</P>
<P>Any of the 3 quantities defining the force components can be specified
as an equal-style or atom-style <A HREF = "variable.html">variable</A>, namely <I>fx</I>,
<I>fy</I>, <I>fz</I>. If the value is a variable, it should be specified as
v_name, where name is the variable name. In this case, the variable
will be evaluated each timestep, and its value used to determine the
force component.
</P>
<P>Equal-style variables can specify formulas with various mathematical
functions, and include <A HREF = "thermo_style.html">thermo_style</A> command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent force field.
</P>
<P>Atom-style variables can specify the same formulas as equal-style
variables but can also include per-atom values, such as atom
coordinates. Thus it is easy to specify a spatially-dependent force
field with optional time-dependence as well.
</P>
<P>If the <I>region</I> keyword is used, the atom must also be in the
specified geometric <A HREF = "region.html">region</A> in order to have force added
to it.
</P>
<HR>
<P>Adding a force to atoms implies a change in their potential energy as
they move due to the applied force field. For dynamics via the "run"
command, this energy can be optionally added to the system's potential
energy for thermodynamic output (see below). For energy minimization
via the "minimize" command, this energy must be added to the system's
potential energy to formulate a self-consistent minimization problem
(see below).
</P>
<P>The <I>energy</I> keyword is not allowed if the added force is a constant
vector F = (fx,fy,fz), with all components defined as numeric
constants and not as variables. This is because LAMMPS can compute
the energy for each atom directly as E = -x dot F = -(x*fx + y*fy +
z*fz), so that -Grad(E) = F.
</P>
<P>The <I>energy</I> keyword is optional if the added force is defined with
one or more variables, and if you are performing dynamics via the
<A HREF = "run.html">run</A> command. If the keyword is not used, LAMMPS will set
the energy to 0.0, which is typically fine for dynamics.
</P>
<P>The <I>energy</I> keyword is required if the added force is defined with
one or more variables, and you are performing energy minimization via
the "minimize" command. The keyword specifies the name of an
atom-style <A HREF = "variable.html">variable</A> which is used to compute the
energy of each atom as function of its position. Like variables used
for <I>fx</I>, <I>fy</I>, <I>fz</I>, the energy variable is specified as v_name,
where name is the variable name.
</P>
<P>Note that when the <I>energy</I> keyword is used during an energy
minimization, you must insure that the formula defined for the
atom-style <A HREF = "variable.html">variable</A> is consistent with the force
variable formulas, i.e. that -Grad(E) = F. For example, if the force
were a spring-like F = kx, then the energy formula should be E =
-0.5kx^2. If you don't do this correctly, the minimization will not
converge properly.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by this
fix to add the potential "energy" inferred by the added force to the
system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>. This is a fictitious quantity but is
needed so that the <A HREF = "minimize.html">minimize</A> command can include the
forces added by this fix in a consistent manner. I.e. there is a
decrease in potential energy when atoms move in the direction of the
added force.
</P>
<P>This fix computes a global scalar and a global 3-vector of forces,
which can be accessed by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. The scalar is the potential
energy discussed above. The vector is the total force on the group of
atoms before the forces on individual atoms are changed by the fix.
The scalar and vector values calculated by this fix are "extensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
invoked by the <A HREF = "minimize.html">minimize</A> command. You should not
specify force components with a variable that has time-dependence for
use with a minimizer, since the minimizer increments the timestep as
the iteration count during the minimization.
</P>
<P>IMPORTANT NOTE: If you want the fictitious potential energy associated
with the added forces to be included in the total potential energy of
the system (the quantity being minimized), you MUST enable the
<A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option for this fix.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_setforce.html">fix setforce</A>, <A HREF = "fix_aveforce.html">fix aveforce</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_addforce.txt b/doc/fix_addforce.txt
index e2c6e2e1f..bd2a15913 100644
--- a/doc/fix_addforce.txt
+++ b/doc/fix_addforce.txt
@@ -1,163 +1,163 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix addforce command :h3
fix addforce/cuda command :h3
[Syntax:]
fix ID group-ID addforce fx fy fz keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
addforce = style name of this fix command :l
fx,fy,fz = force component values (force units) :l
-any of fx,fy,fz can be a variable (see below) :l
+ any of fx,fy,fz can be a variable (see below) :pre
zero or more keyword/value pairs may be appended to args :l
keyword = {region} or {energy} :l
{region} value = region-ID
region-ID = ID of region atoms must be in to have added force
{energy} value = v_name
v_name = variable with name that calculates the potential energy of each atom in the added force field :pre
:ule
[Examples:]
fix kick flow addforce 1.0 0.0 0.0
fix kick flow addforce 1.0 0.0 v_oscillate
fix ff boundary addforce 0.0 0.0 v_push energy v_espace :pre
[Description:]
Add fx,fy,fz to the corresponding component of force for each atom in
the group. This command can be used to give an additional push to
atoms in a simulation, such as for a simulation of Poiseuille flow in
a channel.
Any of the 3 quantities defining the force components can be specified
as an equal-style or atom-style "variable"_variable.html, namely {fx},
{fy}, {fz}. If the value is a variable, it should be specified as
v_name, where name is the variable name. In this case, the variable
will be evaluated each timestep, and its value used to determine the
force component.
Equal-style variables can specify formulas with various mathematical
functions, and include "thermo_style"_thermo_style.html command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent force field.
Atom-style variables can specify the same formulas as equal-style
variables but can also include per-atom values, such as atom
coordinates. Thus it is easy to specify a spatially-dependent force
field with optional time-dependence as well.
If the {region} keyword is used, the atom must also be in the
specified geometric "region"_region.html in order to have force added
to it.
:line
Adding a force to atoms implies a change in their potential energy as
they move due to the applied force field. For dynamics via the "run"
command, this energy can be optionally added to the system's potential
energy for thermodynamic output (see below). For energy minimization
via the "minimize" command, this energy must be added to the system's
potential energy to formulate a self-consistent minimization problem
(see below).
The {energy} keyword is not allowed if the added force is a constant
vector F = (fx,fy,fz), with all components defined as numeric
constants and not as variables. This is because LAMMPS can compute
the energy for each atom directly as E = -x dot F = -(x*fx + y*fy +
z*fz), so that -Grad(E) = F.
The {energy} keyword is optional if the added force is defined with
one or more variables, and if you are performing dynamics via the
"run"_run.html command. If the keyword is not used, LAMMPS will set
the energy to 0.0, which is typically fine for dynamics.
The {energy} keyword is required if the added force is defined with
one or more variables, and you are performing energy minimization via
the "minimize" command. The keyword specifies the name of an
atom-style "variable"_variable.html which is used to compute the
energy of each atom as function of its position. Like variables used
for {fx}, {fy}, {fz}, the energy variable is specified as v_name,
where name is the variable name.
Note that when the {energy} keyword is used during an energy
minimization, you must insure that the formula defined for the
atom-style "variable"_variable.html is consistent with the force
variable formulas, i.e. that -Grad(E) = F. For example, if the force
were a spring-like F = kx, then the energy formula should be E =
-0.5kx^2. If you don't do this correctly, the minimization will not
converge properly.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the potential "energy" inferred by the added force to the
system's potential energy as part of "thermodynamic
output"_thermo_style.html. This is a fictitious quantity but is
needed so that the "minimize"_minimize.html command can include the
forces added by this fix in a consistent manner. I.e. there is a
decrease in potential energy when atoms move in the direction of the
added force.
This fix computes a global scalar and a global 3-vector of forces,
which can be accessed by various "output
commands"_Section_howto.html#howto_15. The scalar is the potential
energy discussed above. The vector is the total force on the group of
atoms before the forces on individual atoms are changed by the fix.
The scalar and vector values calculated by this fix are "extensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
invoked by the "minimize"_minimize.html command. You should not
specify force components with a variable that has time-dependence for
use with a minimizer, since the minimizer increments the timestep as
the iteration count during the minimization.
IMPORTANT NOTE: If you want the fictitious potential energy associated
with the added forces to be included in the total potential energy of
the system (the quantity being minimized), you MUST enable the
"fix_modify"_fix_modify.html {energy} option for this fix.
[Restrictions:] none
[Related commands:]
"fix setforce"_fix_setforce.html, "fix aveforce"_fix_aveforce.html
[Default:] none
diff --git a/doc/fix_append_atoms.html b/doc/fix_append_atoms.html
index 1523661ce..f9a0d6e60 100644
--- a/doc/fix_append_atoms.html
+++ b/doc/fix_append_atoms.html
@@ -1,112 +1,113 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix append_atoms command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID append_atoms face arg ... keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>append_atoms = style name of this fix command
<LI>one face/arg pairs must be appended
<LI>face = <I>zhi</I>
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>size</I> or <I>freq</I> or <I>temp</I> or <I>random</I> or <I>units</I>
<PRE> <I>size</I> args = Lz
Lz = z size of lattice region appended in a single event(distance units)
<I>freq</I> args = freq
freq = the number of timesteps between append events
<I>temp</I> args = target damp seed extent
target = target velocity for region immediately ahead of the piston
damp = damping parameter (time units)
seed = random number seed for langevin kicks
extent = extent of thermostated region (distance units)
<I>random</I> args = xmax ymax zmax seed
<I>xmax</I>, <I>ymax</I>, <I>zmax</I> = maximum displacement in particular direction (distance units)
<I>seed</I> = random number seed for random displacement
<I>units</I> value = <I>lattice</I> or <I>box</I>
<I>lattice</I> = the wall position is defined in lattice units
<I>box</I> = the wall position is defined in simulation box units
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all append_atoms zhi size 5.0 freq 295 units lattice
fix 4 all append_atoms zhi size 15.0 freq 5 units box
fix A all append_atoms zhi size 1.0 freq 1000 units lattice
</PRE>
<P><B>Description:</B>
</P>
<P>This fix creates atoms on a lattice, appended on the zhi edge of the system box.
This can be useful when a shock or wave is propagating from zlo. This allows
the system to grow with time to accommodate an expanding wave. A simulation
box must already exist, which is typically created via the
<A HREF = "create_box.html">create_box</A> command. Before using this command, a
lattice must also be defined using the <A HREF = "lattice.html">lattice</A> command.
</P>
<P>This fix will automatically freeze atoms on the zhi edge of the system, so that
overlaps are avoided when new atoms are appended.
</P>
<P>The <I>size</I> keyword defines the size in z of the chunk of material to be added.
</P>
<P>The <I>random</I> keyword will give the atoms random displacements around their
lattice points to simulate some initial temperature.
</P>
<P>The <I>temp</I> keyword will cause a region to be thermostated with a Langevin
thermostat on the zhi boundary. The size of the region is measured from zhi and
is set with the <I>extent</I> argument.
</P>
<P>The <I>units</I> keyword determines the meaning of the distance units used
to define a wall position, but only when a numeric constant is used.
A <I>box</I> value selects standard distance units as defined by the
<A HREF = "units.html">units</A> command, e.g. Angstroms for units = real or metal.
A <I>lattice</I> value means the distance units are in lattice spacings.
The <A HREF = "lattice.html">lattice</A> command must have been previously used to
define the lattice spacings.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
-by this fix for access by various <A HREF = "Section_howto.html#4_15">output
-commands</A>. No parameter of this fix can be
-used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
+by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
+commands</A>. No parameter of this fix can
+be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix style is part of the SHOCK package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
-<P>The zhi boundary on which atoms are added with append_atoms must be shrink-wrapped.
-The zlo boundary may be any boundary type other than periodic.
+<P>The zhi boundary on which atoms are added with append_atoms must be
+shrink-wrapped. The zlo boundary may be any boundary type other than
+periodic.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_wall_piston.html">fix wall/piston</A> command
</P>
<P><B>Default:</B> <I>size</I> = 0.0, <I>freq</I> = 0, <I>units</I> = lattice.
</P>
<HR>
</HTML>
diff --git a/doc/fix_append_atoms.txt b/doc/fix_append_atoms.txt
index a98c9734d..a698ae6a5 100644
--- a/doc/fix_append_atoms.txt
+++ b/doc/fix_append_atoms.txt
@@ -1,100 +1,101 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix append_atoms command :h3
[Syntax:]
fix ID group-ID append_atoms face arg ... keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
append_atoms = style name of this fix command :l
one face/arg pairs must be appended :l
face = {zhi} :l
zero or more keyword/value pairs may be appended :l
keyword = {size} or {freq} or {temp} or {random} or {units} :l
{size} args = Lz
Lz = z size of lattice region appended in a single event(distance units)
{freq} args = freq
freq = the number of timesteps between append events
{temp} args = target damp seed extent
target = target velocity for region immediately ahead of the piston
damp = damping parameter (time units)
seed = random number seed for langevin kicks
extent = extent of thermostated region (distance units)
{random} args = xmax ymax zmax seed
{xmax}, {ymax}, {zmax} = maximum displacement in particular direction (distance units)
{seed} = random number seed for random displacement
{units} value = {lattice} or {box}
{lattice} = the wall position is defined in lattice units
{box} = the wall position is defined in simulation box units :pre
:ule
[Examples:]
fix 1 all append_atoms zhi size 5.0 freq 295 units lattice
fix 4 all append_atoms zhi size 15.0 freq 5 units box
fix A all append_atoms zhi size 1.0 freq 1000 units lattice :pre
[Description:]
This fix creates atoms on a lattice, appended on the zhi edge of the system box.
This can be useful when a shock or wave is propagating from zlo. This allows
the system to grow with time to accommodate an expanding wave. A simulation
box must already exist, which is typically created via the
"create_box"_create_box.html command. Before using this command, a
lattice must also be defined using the "lattice"_lattice.html command.
This fix will automatically freeze atoms on the zhi edge of the system, so that
overlaps are avoided when new atoms are appended.
The {size} keyword defines the size in z of the chunk of material to be added.
The {random} keyword will give the atoms random displacements around their
lattice points to simulate some initial temperature.
The {temp} keyword will cause a region to be thermostated with a Langevin
thermostat on the zhi boundary. The size of the region is measured from zhi and
is set with the {extent} argument.
The {units} keyword determines the meaning of the distance units used
to define a wall position, but only when a numeric constant is used.
A {box} value selects standard distance units as defined by the
"units"_units.html command, e.g. Angstroms for units = real or metal.
A {lattice} value means the distance units are in lattice spacings.
The "lattice"_lattice.html command must have been previously used to
define the lattice spacings.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
-commands"_Section_howto.html#4_15. No parameter of this fix can be
-used with the {start/stop} keywords of the "run"_run.html command.
+commands"_Section_howto.html#howto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
This fix style is part of the SHOCK package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
-The zhi boundary on which atoms are added with append_atoms must be shrink-wrapped.
-The zlo boundary may be any boundary type other than periodic.
+The zhi boundary on which atoms are added with append_atoms must be
+shrink-wrapped. The zlo boundary may be any boundary type other than
+periodic.
[Related commands:]
"fix wall/piston"_fix_wall_piston.html command
[Default:] {size} = 0.0, {freq} = 0, {units} = lattice.
:line
diff --git a/doc/fix_aveforce.html b/doc/fix_aveforce.html
index d2f935509..99052a01e 100644
--- a/doc/fix_aveforce.html
+++ b/doc/fix_aveforce.html
@@ -1,128 +1,128 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix aveforce command
</H3>
<H3>fix aveforce/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID aveforce fx fy fz keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>aveforce = style name of this fix command
<LI>fx,fy,fz = force component values (force units)
-<LI>any of fx,fy,fz can be a variable (see below)
-
+<PRE> any of fx,fy,fz can be a variable (see below)
+</PRE>
<LI>zero or more keyword/value pairs may be appended to args
<LI>keyword = <I>region</I>
<PRE> <I>region</I> value = region-ID
region-ID = ID of region atoms must be in to have added force
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix pressdown topwall aveforce 0.0 -1.0 0.0
fix 2 bottomwall aveforce NULL -1.0 0.0 region top
fix 2 bottomwall aveforce NULL -1.0 v_oscillate region top
</PRE>
<P><B>Description:</B>
</P>
<P>Apply an additional external force to a group of atoms in such a way
that every atom experiences the same force. This is useful for
pushing on wall or boundary atoms so that the structure of the wall
does not change over time.
</P>
<P>The existing force is averaged for the group of atoms, component by
component. The actual force on each atom is then set to the average
value plus the component specified in this command. This means each
atom in the group receives the same force.
</P>
<P>Any of the fx,fy,fz values can be specified as NULL which means the
force in that dimension is not changed. Note that this is not the
same as specifying a 0.0 value, since that sets all forces to the same
average value without adding in any additional force.
</P>
<P>Any of the 3 quantities defining the force components can be specified
as an equal-style <A HREF = "variable.html">variable</A>, namely <I>fx</I>, <I>fy</I>, <I>fz</I>.
If the value is a variable, it should be specified as v_name, where
name is the variable name. In this case, the variable will be
evaluated each timestep, and its value used to determine the average
force.
</P>
<P>Equal-style variables can specify formulas with various mathematical
functions, and include <A HREF = "thermo_style.html">thermo_style</A> command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent average force.
</P>
<P>If the <I>region</I> keyword is used, the atom must also be in the
specified geometric <A HREF = "region.html">region</A> in order to have force added
to it.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
<P>This fix computes a global 3-vector of forces, which can be accessed
by various <A HREF = "Section_howto.html#howto_15">output commands</A>. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
invoked by the <A HREF = "minimize.html">minimize</A> command. You should not
specify force components with a variable that has time-dependence for
use with a minimizer, since the minimizer increments the timestep as
the iteration count during the minimization.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_setforce.html">fix setforce</A>, <A HREF = "fix_addforce.html">fix addforce</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_aveforce.txt b/doc/fix_aveforce.txt
index b8db603c5..9759fe455 100644
--- a/doc/fix_aveforce.txt
+++ b/doc/fix_aveforce.txt
@@ -1,115 +1,115 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix aveforce command :h3
fix aveforce/cuda command :h3
[Syntax:]
fix ID group-ID aveforce fx fy fz keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
aveforce = style name of this fix command :l
fx,fy,fz = force component values (force units) :l
-any of fx,fy,fz can be a variable (see below) :l
+ any of fx,fy,fz can be a variable (see below) :pre
zero or more keyword/value pairs may be appended to args :l
keyword = {region} :l
{region} value = region-ID
region-ID = ID of region atoms must be in to have added force :pre
:ule
[Examples:]
fix pressdown topwall aveforce 0.0 -1.0 0.0
fix 2 bottomwall aveforce NULL -1.0 0.0 region top
fix 2 bottomwall aveforce NULL -1.0 v_oscillate region top :pre
[Description:]
Apply an additional external force to a group of atoms in such a way
that every atom experiences the same force. This is useful for
pushing on wall or boundary atoms so that the structure of the wall
does not change over time.
The existing force is averaged for the group of atoms, component by
component. The actual force on each atom is then set to the average
value plus the component specified in this command. This means each
atom in the group receives the same force.
Any of the fx,fy,fz values can be specified as NULL which means the
force in that dimension is not changed. Note that this is not the
same as specifying a 0.0 value, since that sets all forces to the same
average value without adding in any additional force.
Any of the 3 quantities defining the force components can be specified
as an equal-style "variable"_variable.html, namely {fx}, {fy}, {fz}.
If the value is a variable, it should be specified as v_name, where
name is the variable name. In this case, the variable will be
evaluated each timestep, and its value used to determine the average
force.
Equal-style variables can specify formulas with various mathematical
functions, and include "thermo_style"_thermo_style.html command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent average force.
If the {region} keyword is used, the atom must also be in the
specified geometric "region"_region.html in order to have force added
to it.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
This fix computes a global 3-vector of forces, which can be accessed
by various "output commands"_Section_howto.html#howto_15. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
invoked by the "minimize"_minimize.html command. You should not
specify force components with a variable that has time-dependence for
use with a minimizer, since the minimizer increments the timestep as
the iteration count during the minimization.
[Restrictions:] none
[Related commands:]
"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html
[Default:] none
diff --git a/doc/fix_dt_reset.html b/doc/fix_dt_reset.html
index 2831e47d8..6ba8481ed 100644
--- a/doc/fix_dt_reset.html
+++ b/doc/fix_dt_reset.html
@@ -1,98 +1,99 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix dt/reset command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID dt/reset N Tmin Tmax Xmax keyword values ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>dt/reset = style name of this fix command
<LI>N = recompute dt every N timesteps
-<LI>Tmin = minimum dt allowed (can be NULL) (time units)
-<LI>Tmax = maximum dt allowed (can be NULL) (time units)
+<LI>Tmin = minimum dt allowed which can be NULL (time units)
+<LI>Tmax = maximum dt allowed which can be NULL (time units)
<LI>Xmax = maximum distance for an atom to move in one timestep (distance units)
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>units</I>
</UL>
<PRE> <I>units</I> value = <I>lattice</I> or <I>box</I>
lattice = Xmax is defined in lattice units
box = Xmax is defined in simulation box units
</PRE>
<P><B>Examples:</B>
</P>
<PRE>fix 5 all dt/reset 10 1.0e-5 0.01 0.1
fix 5 all dt/reset 10 0.01 2.0 0.2 units box
</PRE>
<P><B>Description:</B>
</P>
<P>Reset the timestep size every N steps during a run, so that no atom
moves further than Xmax, based on current atom velocities and forces.
This can be useful when starting from a configuration with overlapping
atoms, where forces will be large. Or it can be useful when running
an impact simulation where one or more high-energy atoms collide with
a solid, causing a damage cascade.
</P>
<P>This fix overrides the timestep size setting made by the
<A HREF = "timestep.html">timestep</A> command. The new timestep size <I>dt</I> is
computed in the following manner.
</P>
<P>For each atom, the timestep is computed that would cause it to
displace <I>Xmax</I> on the next integration step, as a function of its
current velocity and force. Since performing this calculation exactly
would require the solution to a quartic equation, a cheaper estimate
is generated. The estimate is conservative in that the atom's
displacement is guaranteed not to exceed <I>Xmax</I>, though it may be
smaller.
</P>
<P>Given this putative timestep for each atom, the minimum timestep value
across all atoms is computed. Then the <I>Tmin</I> and <I>Tmax</I> bounds are
applied, if specified. If one (or both) is specified as NULL, it is
not applied.
</P>
<P>When the <A HREF = "run_style.html">run style</A> is <I>respa</I>, this fix resets the
outer loop (largest) timestep, which is the same timestep that the
<A HREF = "timestep.html">timestep</A> command sets.
</P>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
-<P>This fix computes a global scalar and a global vector of length 1,
+<P>This fix computes a global scalar and a global vector of length 2,
which can be accessed by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. The scalar is the current
-timestep size. The cumulative simulation time (in time units) is
-stored as the first element of the vector. The scalar and vector
-values calculated by this fix are "intensive".
+timestep size. The first element of the vector stores the cumulative
+simulation time (in time units). The second element of the vector
+stores the last timestep on which the timestep was reset to a new
+value. The scalar and vector values calculated by this fix are
+"intensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command. This fix is not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
-<P>The cumulative time is zeroed when the fix is created and
-continuously accrues thereafter. Using the
-<A HREF = "reset_timestep.html">reset_timestep</A> command while this fix is defined
-will mess up the time accumulation.
+<P>The cumulative time is zeroed when the fix is created and continuously
+accrues thereafter. Using the <A HREF = "reset_timestep.html">reset_timestep</A>
+command while this fix is defined will mess up the time accumulation.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "timestep.html">timestep</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults is units = lattice.
</P>
</HTML>
diff --git a/doc/fix_dt_reset.txt b/doc/fix_dt_reset.txt
index edd1b4c79..ce15fd343 100644
--- a/doc/fix_dt_reset.txt
+++ b/doc/fix_dt_reset.txt
@@ -1,92 +1,93 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix dt/reset command :h3
[Syntax:]
fix ID group-ID dt/reset N Tmin Tmax Xmax keyword values ... :pre
ID, group-ID are documented in "fix"_fix.html command
dt/reset = style name of this fix command
N = recompute dt every N timesteps
-Tmin = minimum dt allowed (can be NULL) (time units)
-Tmax = maximum dt allowed (can be NULL) (time units)
+Tmin = minimum dt allowed which can be NULL (time units)
+Tmax = maximum dt allowed which can be NULL (time units)
Xmax = maximum distance for an atom to move in one timestep (distance units)
zero or more keyword/value pairs may be appended
keyword = {units} :ul
{units} value = {lattice} or {box}
lattice = Xmax is defined in lattice units
box = Xmax is defined in simulation box units :pre
[Examples:]
fix 5 all dt/reset 10 1.0e-5 0.01 0.1
fix 5 all dt/reset 10 0.01 2.0 0.2 units box :pre
[Description:]
Reset the timestep size every N steps during a run, so that no atom
moves further than Xmax, based on current atom velocities and forces.
This can be useful when starting from a configuration with overlapping
atoms, where forces will be large. Or it can be useful when running
an impact simulation where one or more high-energy atoms collide with
a solid, causing a damage cascade.
This fix overrides the timestep size setting made by the
"timestep"_timestep.html command. The new timestep size {dt} is
computed in the following manner.
For each atom, the timestep is computed that would cause it to
displace {Xmax} on the next integration step, as a function of its
current velocity and force. Since performing this calculation exactly
would require the solution to a quartic equation, a cheaper estimate
is generated. The estimate is conservative in that the atom's
displacement is guaranteed not to exceed {Xmax}, though it may be
smaller.
Given this putative timestep for each atom, the minimum timestep value
across all atoms is computed. Then the {Tmin} and {Tmax} bounds are
applied, if specified. If one (or both) is specified as NULL, it is
not applied.
When the "run style"_run_style.html is {respa}, this fix resets the
outer loop (largest) timestep, which is the same timestep that the
"timestep"_timestep.html command sets.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
-This fix computes a global scalar and a global vector of length 1,
+This fix computes a global scalar and a global vector of length 2,
which can be accessed by various "output
commands"_Section_howto.html#howto_15. The scalar is the current
-timestep size. The cumulative simulation time (in time units) is
-stored as the first element of the vector. The scalar and vector
-values calculated by this fix are "intensive".
+timestep size. The first element of the vector stores the cumulative
+simulation time (in time units). The second element of the vector
+stores the last timestep on which the timestep was reset to a new
+value. The scalar and vector values calculated by this fix are
+"intensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
-The cumulative time is zeroed when the fix is created and
-continuously accrues thereafter. Using the
-"reset_timestep"_reset_timestep.html command while this fix is defined
-will mess up the time accumulation.
+The cumulative time is zeroed when the fix is created and continuously
+accrues thereafter. Using the "reset_timestep"_reset_timestep.html
+command while this fix is defined will mess up the time accumulation.
[Related commands:]
"timestep"_timestep.html
[Default:]
The option defaults is units = lattice.
diff --git a/doc/fix_enforce2d.html b/doc/fix_enforce2d.html
index cad153683..3bf7b56e4 100644
--- a/doc/fix_enforce2d.html
+++ b/doc/fix_enforce2d.html
@@ -1,74 +1,74 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix enforce2d command
</H3>
<H3>fix enforce2d/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID enforce2d
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>enforce2d = style name of this fix command
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 5 all enforce2d
</PRE>
<P><B>Description:</B>
</P>
<P>Zero out the z-dimension velocity and force on each atom in the group.
This is useful when running a 2d simulation to insure that atoms do
not move from their initial z coordinate.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
invoked by the <A HREF = "minimize.html">minimize</A> command.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B> none
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_enforce2d.txt b/doc/fix_enforce2d.txt
index 20bcf8f3c..46000e962 100644
--- a/doc/fix_enforce2d.txt
+++ b/doc/fix_enforce2d.txt
@@ -1,68 +1,68 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix enforce2d command :h3
fix enforce2d/cuda command :h3
[Syntax:]
fix ID group-ID enforce2d :pre
ID, group-ID are documented in "fix"_fix.html command
enforce2d = style name of this fix command :ul
[Examples:]
fix 5 all enforce2d :pre
[Description:]
Zero out the z-dimension velocity and force on each atom in the group.
This is useful when running a 2d simulation to insure that atoms do
not move from their initial z coordinate.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
invoked by the "minimize"_minimize.html command.
[Restrictions:] none
[Related commands:] none
[Default:] none
diff --git a/doc/fix_freeze.html b/doc/fix_freeze.html
index 762460f39..ea95a1fdb 100644
--- a/doc/fix_freeze.html
+++ b/doc/fix_freeze.html
@@ -1,91 +1,91 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix freeze command
</H3>
<H3>fix freeze/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID freeze
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>freeze = style name of this fix command
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 2 bottom freeze
</PRE>
<P><B>Description:</B>
</P>
<P>Zero out the force and torque on a granular particle. This is useful
for preventing certain particles from moving in a simulation. The
<A HREF = "pair_gran.html">granular pair styles</A> also detect if this fix has been
defined and compute interactions between frozen and non-frozen
particles appropriately, as if the frozen particle has infinite mass.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
<P>This fix computes a global 3-vector of forces, which can be accessed
by various <A HREF = "Section_howto.html#howto_15">output commands</A>. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command. This fix is not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix is part of the GRANULAR package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>There can only be a single freeze fix defined. This is because other
the <A HREF = "pair_gran.html">granular pair styles</A> treat frozen particles
differently and need to be able to reference a single group to which
this fix is applied.
</P>
<P><B>Related commands:</B> none
</P>
<P><A HREF = "atom_style.html">atom_style sphere</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_freeze.txt b/doc/fix_freeze.txt
index ac89b1819..05ad19479 100644
--- a/doc/fix_freeze.txt
+++ b/doc/fix_freeze.txt
@@ -1,85 +1,85 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix freeze command :h3
fix freeze/cuda command :h3
[Syntax:]
fix ID group-ID freeze :pre
ID, group-ID are documented in "fix"_fix.html command
freeze = style name of this fix command :ul
[Examples:]
fix 2 bottom freeze :pre
[Description:]
Zero out the force and torque on a granular particle. This is useful
for preventing certain particles from moving in a simulation. The
"granular pair styles"_pair_gran.html also detect if this fix has been
defined and compute interactions between frozen and non-frozen
particles appropriately, as if the frozen particle has infinite mass.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
This fix computes a global 3-vector of forces, which can be accessed
by various "output commands"_Section_howto.html#howto_15. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
This fix is part of the GRANULAR package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
There can only be a single freeze fix defined. This is because other
the "granular pair styles"_pair_gran.html treat frozen particles
differently and need to be able to reference a single group to which
this fix is applied.
[Related commands:] none
"atom_style sphere"_atom_style.html
[Default:] none
diff --git a/doc/fix_gravity.html b/doc/fix_gravity.html
index fbc2fce7f..b26083d2d 100644
--- a/doc/fix_gravity.html
+++ b/doc/fix_gravity.html
@@ -1,145 +1,145 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix gravity command
</H3>
<H3>fix gravity/cuda command
</H3>
<H3>fix gravity/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group gravity style magnitude args
</PRE>
<UL><LI>ID, group are documented in <A HREF = "fix.html">fix</A> command
<LI>gravity = style name of this fix command
<LI>magnitude = size of acceleration (force/mass units)
<LI>style = <I>chute</I> or <I>spherical</I> or <I>gradient</I> or <I>vector</I>
<PRE> <I>chute</I> args = angle
angle = angle in +x away from -z or -y axis in 3d/2d (in degrees)
<I>spherical</I> args = phi theta
phi = azimuthal angle from +x axis (in degrees)
theta = angle from +z or +y axis in 3d/2d (in degrees)
<I>gradient</I> args = phi theta phi_grad theta_grad
phi = azimuthal angle from +x axis (in degrees)
theta = angle from +z or +y axis in 3d/2d (in degrees)
phi_grad = rate of change of angle phi (full rotations per time unit)
theta_grad = rate of change of angle theta (full rotations per time unit)
<I>vector</I> args = x y z
x y z = vector direction to apply the acceleration
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all gravity 1.0 chute 24.0
fix 1 all gravity 1.0 spherical 0.0 -180.0
fix 1 all gravity 1.0 gradient 0.0 -180.0 0.0 0.1
fix 1 all gravity 100.0 vector 1 1 0
</PRE>
<P><B>Description:</B>
</P>
<P>Impose an additional acceleration on each particle in the group. This
fix is typically used with granular systems to include a "gravity"
term acting on the macroscopic particles. More generally, it can
represent any kind of driving field, e.g. a pressure gradient inducing
a Poiseuille flow in a fluid. Note that this fix operates differently
than the <A HREF = "fix_addforce.html">fix addforce</A> command. The addforce fix
adds the same force to each atom, independent of its mass. This
command imparts the same acceleration to each atom (force/mass).
</P>
<P>The <I>magnitude</I> of the acceleration is specified in force/mass units.
For granular systems (LJ units) this is typically 1.0. See the
<A HREF = "units.html">units</A> command for details.
</P>
<P>Style <I>chute</I> is typically used for simulations of chute flow where
the specified angle is the chute angle, with flow occurring in the +x
direction. For 3d systems, the tilt is away from the z axis; for 2d
systems, the tilt is away from the y axis.
</P>
<P>Style <I>spherical</I> allows an arbitrary 3d direction to be specified for
the acceleration vector. Phi and theta are defined in the usual
spherical coordinates. Thus for acceleration acting in the -z
direction, theta would be 180.0 (or -180.0). Theta = 90.0 and phi =
-90.0 would mean acceleration acts in the -y direction. For 2d
systems, <I>phi</I> is ignored and <I>theta</I> is an angle in the xy plane
where theta = 0.0 is the y-axis.
</P>
<P>Style <I>gradient</I> is the same as style <I>spherical</I> except that the
direction of the acceleration vector is time dependent. The units of
the gradient arguments are in full rotations per time unit. E.g. a
timestep of 0.001 and a gradient of 0.1 means the acceleration vector
would rotate thru 360 degrees every 10,000 timesteps. For the
time-dependent case, the initial direction of the acceleration vector
is set to phi,theta when the fix is specified and evolves thereafter.
For 2d systems, <I>phi</I> and <I>phi_grad</I> are ignored.
</P>
<P>Style <I>vector</I> imposes an acceleration in the vector direction given
by (x,y,z). For 2d systems, the z component is ignored.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by this
fix to add the gravitational potential energy of the system to the
system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>.
</P>
<P>This fix computes a global scalar which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. This scalar is the
gravitational potential energy of the particles in the defined field,
namely mass * (g dot x) for each particles, where x and mass are the
particles position and mass, and g is the gravitational field. The
scalar value calculated by this fix is "extensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command. This fix is not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "atom_style.html">atom_style sphere</A>, <A HREF = "fix_addforce.html">fix addforce</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_gravity.txt b/doc/fix_gravity.txt
index bad5edc99..45812ffe4 100644
--- a/doc/fix_gravity.txt
+++ b/doc/fix_gravity.txt
@@ -1,133 +1,133 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix gravity command :h3
fix gravity/cuda command :h3
fix gravity/omp command :h3
[Syntax:]
fix ID group gravity style magnitude args :pre
ID, group are documented in "fix"_fix.html command :ulb,l
gravity = style name of this fix command :l
magnitude = size of acceleration (force/mass units) :l
style = {chute} or {spherical} or {gradient} or {vector} :l
{chute} args = angle
angle = angle in +x away from -z or -y axis in 3d/2d (in degrees)
{spherical} args = phi theta
phi = azimuthal angle from +x axis (in degrees)
theta = angle from +z or +y axis in 3d/2d (in degrees)
{gradient} args = phi theta phi_grad theta_grad
phi = azimuthal angle from +x axis (in degrees)
theta = angle from +z or +y axis in 3d/2d (in degrees)
phi_grad = rate of change of angle phi (full rotations per time unit)
theta_grad = rate of change of angle theta (full rotations per time unit)
{vector} args = x y z
x y z = vector direction to apply the acceleration :pre
:ule
[Examples:]
fix 1 all gravity 1.0 chute 24.0
fix 1 all gravity 1.0 spherical 0.0 -180.0
fix 1 all gravity 1.0 gradient 0.0 -180.0 0.0 0.1
fix 1 all gravity 100.0 vector 1 1 0 :pre
[Description:]
Impose an additional acceleration on each particle in the group. This
fix is typically used with granular systems to include a "gravity"
term acting on the macroscopic particles. More generally, it can
represent any kind of driving field, e.g. a pressure gradient inducing
a Poiseuille flow in a fluid. Note that this fix operates differently
than the "fix addforce"_fix_addforce.html command. The addforce fix
adds the same force to each atom, independent of its mass. This
command imparts the same acceleration to each atom (force/mass).
The {magnitude} of the acceleration is specified in force/mass units.
For granular systems (LJ units) this is typically 1.0. See the
"units"_units.html command for details.
Style {chute} is typically used for simulations of chute flow where
the specified angle is the chute angle, with flow occurring in the +x
direction. For 3d systems, the tilt is away from the z axis; for 2d
systems, the tilt is away from the y axis.
Style {spherical} allows an arbitrary 3d direction to be specified for
the acceleration vector. Phi and theta are defined in the usual
spherical coordinates. Thus for acceleration acting in the -z
direction, theta would be 180.0 (or -180.0). Theta = 90.0 and phi =
-90.0 would mean acceleration acts in the -y direction. For 2d
systems, {phi} is ignored and {theta} is an angle in the xy plane
where theta = 0.0 is the y-axis.
Style {gradient} is the same as style {spherical} except that the
direction of the acceleration vector is time dependent. The units of
the gradient arguments are in full rotations per time unit. E.g. a
timestep of 0.001 and a gradient of 0.1 means the acceleration vector
would rotate thru 360 degrees every 10,000 timesteps. For the
time-dependent case, the initial direction of the acceleration vector
is set to phi,theta when the fix is specified and evolves thereafter.
For 2d systems, {phi} and {phi_grad} are ignored.
Style {vector} imposes an acceleration in the vector direction given
by (x,y,z). For 2d systems, the z component is ignored.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the gravitational potential energy of the system to the
system's potential energy as part of "thermodynamic
output"_thermo_style.html.
This fix computes a global scalar which can be accessed by various
"output commands"_Section_howto.html#howto_15. This scalar is the
gravitational potential energy of the particles in the defined field,
namely mass * (g dot x) for each particles, where x and mass are the
particles position and mass, and g is the gravitational field. The
scalar value calculated by this fix is "extensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:] none
[Related commands:]
"atom_style sphere"_atom_style.html, "fix addforce"_fix_addforce.html
[Default:] none
diff --git a/doc/fix_langevin.html b/doc/fix_langevin.html
index 17fefcd56..d19ae2ff4 100644
--- a/doc/fix_langevin.html
+++ b/doc/fix_langevin.html
@@ -1,253 +1,272 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix langevin command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID langevin Tstart Tstop damp seed keyword values ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>langevin = style name of this fix command
<LI>Tstart,Tstop = desired temperature at start/end of run (temperature units)
+<PRE> Tstart can be a variable (see below)
+</PRE>
<LI>damp = damping parameter (time units)
<LI>seed = random number seed to use for white noise (positive integer)
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>angmom</I> or <I>omega</I> or <I>scale</I> or <I>tally</I> or <I>zero</I>
<PRE> <I>angmom</I> value = <I>no</I> or <I>yes</I>
<I>no</I> = do not thermostat rotational degrees of freedom via the angular momentum
<I>yes</I> = do thermostat rotational degrees of freedom via the angular momentum
<I>omega</I> value = <I>no</I> or <I>yes</I>
- <I>no</I> = do not thermostat rotational degrees of freedom via then angular velocity
+ <I>no</I> = do not thermostat rotational degrees of freedom via the angular velocity
<I>yes</I> = do thermostat rotational degrees of freedom via the angular velocity
<I>scale</I> values = type ratio
type = atom type (1-N)
ratio = factor by which to scale the damping coefficient
<I>tally</I> value = <I>no</I> or <I>yes</I>
<I>no</I> = do not tally the energy added/subtracted to atoms
<I>yes</I> = do tally the energy added/subtracted to atoms
<I>zero</I> value = <I>no</I> or <I>yes</I>
<I>no</I> = do not set total random force to zero
<I>yes</I> = set total random force to zero
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 3 boundary langevin 1.0 1.0 1000.0 699483
fix 1 all langevin 1.0 1.1 100.0 48279 scale 3 1.5
</PRE>
<P><B>Description:</B>
</P>
<P>Apply a Langevin thermostat as described in <A HREF = "#Schneider">(Schneider)</A>
to a group of atoms which models an interaction with a background
implicit solvent. Used with <A HREF = "fix_nve.html">fix nve</A>, this command
performs Brownian dynamics (BD), since the total force on each atom
will have the form:
</P>
<PRE>F = Fc + Ff + Fr
Ff = - (m / damp) v
Fr is proportional to sqrt(Kb T m / (dt damp))
</PRE>
<P>Fc is the conservative force computed via the usual inter-particle
interactions (<A HREF = "pair_style.html">pair_style</A>,
<A HREF = "bond_style.html">bond_style</A>, etc).
</P>
<P>The Ff and Fr terms are added by this fix on a per-particle basis.
See the <A HREF = "pair_dpd.html">pair_style dpd/tstat</A> command for a
thermostatting option that adds similar terms on a pairwise basis to
pairs of interacting particles.
</P>
<P>Ff is a frictional drag or viscous damping term proportional to the
particle's velocity. The proportionality constant for each atom is
computed as m/damp, where m is the mass of the particle and damp is
the damping factor specified by the user.
</P>
<P>Fr is a force due to solvent atoms at a temperature T randomly bumping
into the particle. As derived from the fluctuation/dissipation
theorem, its magnitude as shown above is proportional to sqrt(Kb T m /
dt damp), where Kb is the Boltzmann constant, T is the desired
temperature, m is the mass of the particle, dt is the timestep size,
and damp is the damping factor. Random numbers are used to randomize
the direction and magnitude of this force as described in
<A HREF = "#Dunweg">(Dunweg)</A>, where a uniform random number is used (instead of
a Gaussian random number) for speed.
</P>
<P>Note that the thermostat effect of this fix is applied to only the
translational degrees of freedom for the particles, which is an
important consideration if extended spherical or aspherical particles
which have rotational degrees of freedom are being thermostatted with
this fix. The translational degrees of freedom can also have a bias
velocity removed from them before thermostatting takes place; see the
description below.
</P>
<P>IMPORTANT NOTE: Unlike the <A HREF = "fix_nh.html">fix nvt</A> command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies forces to effect
thermostatting. Thus you must use a separate time integration fix,
like <A HREF = "fix_nve.html">fix nve</A> to actually update the velocities and
positions of atoms using the modified forces. Likewise, this fix
should not normally be used on atoms that also have their temperature
controlled by another fix - e.g. by <A HREF = "fix_nh.html">fix nvt</A> or <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A> commands.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
</P>
<P>The desired temperature at each timestep is a ramped value during the
run from <I>Tstart</I> to <I>Tstop</I>.
</P>
+<P><I>Tstart</I> can be specified as an equal-style or atom-style
+<A HREF = "variable.html">variable</A>. In this case, the <I>Tstop</I> setting is
+ignored. If the value is a variable, it should be specified as
+v_name, where name is the variable name. In this case, the variable
+will be evaluated each timestep, and its value used to determine the
+target temperature.
+</P>
+<P>Equal-style variables can specify formulas with various mathematical
+functions, and include <A HREF = "thermo_style.html">thermo_style</A> command
+keywords for the simulation box parameters and timestep and elapsed
+time. Thus it is easy to specify a time-dependent temperature.
+</P>
+<P>Atom-style variables can specify the same formulas as equal-style
+variables but can also include per-atom values, such as atom
+coordinates. Thus it is easy to specify a spatially-dependent
+temperature with optional time-dependence as well.
+</P>
<P>Like other fixes that perform thermostatting, this fix can be used
with <A HREF = "compute.html">compute commands</A> that remove a "bias" from the
atom velocities. E.g. removing the center-of-mass velocity from a
group of atoms or removing the x-component of velocity from the
calculation. This is not done by default, but only if the
<A HREF = "fix_modify.html">fix_modify</A> command is used to assign a temperature
compute to this fix that includes such a bias term. See the doc pages
for individual <A HREF = "compute.html">compute commands</A> to determine which ones
include a bias. In this case, the thermostat works in the following
manner: bias is removed from each atom, thermostatting is performed on
the remaining thermal degrees of freedom, and the bias is added back
in.
</P>
<P>The <I>damp</I> parameter is specified in time units and determines how
rapidly the temperature is relaxed. For example, a value of 100.0
means to relax the temperature in a timespan of (roughly) 100 time
units (tau or fmsec or psec - see the <A HREF = "units.html">units</A> command).
The damp factor can be thought of as inversely related to the
viscosity of the solvent. I.e. a small relaxation time implies a
hi-viscosity solvent and vice versa. See the discussion about gamma
and viscosity in the documentation for the <A HREF = "fix_viscous.html">fix
viscous</A> command for more details.
</P>
<P>The random # <I>seed</I> must be a positive integer. A Marsaglia random
number generator is used. Each processor uses the input seed to
generate its own unique seed and its own stream of random numbers.
Thus the dynamics of the system will not be identical on two runs on
different numbers of processors.
</P>
<HR>
<P>The keyword/value option pairs are used in the following ways.
</P>
<P>The keyword <I>angmom</I> and <I>omega</I> keywords enable thermostatting of
rotational degrees of freedom in addition to the usual translational
degrees of freedom. This can only be done for finite-size particles.
A simulation using atom_style sphere defines an omega for finite-size
spheres. A simulation using atom_style ellipsoid defines a finite
size and shape for aspherical particles and an angular momentum. The
Langevin formulas for thermostatting the rotational degrees of freedom
are the same as those above, where force is replaced by torque, m is
replaced by the moment of inertia I, and v is replaced by omega (which
is derived from the angular momentum in the case of aspherical
particles). The rotational temperature of the particles can be
monitored by the <A HREF = "compute_temp_sphere.html">compute temp/sphere</A> and
<A HREF = "compute_temp_asphere.html">compute temp/asphere</A> commands with their
rotate options.
</P>
<P>The keyword <I>scale</I> allows the damp factor to be scaled up or down by
the specified factor for atoms of that type. This can be useful when
different atom types have different sizes or masses. It can be used
multiple times to adjust damp for several atom types. Note that
specifying a ratio of 2 increases the relaxation time which is
equivalent to the solvent's viscosity acting on particles with 1/2 the
diameter. This is the opposite effect of scale factors used by the
<A HREF = "fix_viscous.html">fix viscous</A> command, since the damp factor in fix
<I>langevin</I> is inversely related to the gamma factor in fix <I>viscous</I>.
Also note that the damping factor in fix <I>langevin</I> includes the
particle mass in Ff, unlike fix <I>viscous</I>. Thus the mass and size of
different atom types should be accounted for in the choice of ratio
values.
</P>
<P>The keyword <I>tally</I> enables the calculation of the cumulative energy
added/subtracted to the atoms as they are thermostatted. Effectively
it is the energy exchanged between the infinite thermal reservoir and
the particles. As described below, this energy can then be printed
out or added to the potential energy of the system to monitor energy
conservation.
</P>
<P>The keyword <I>zero</I> can be used to eliminate drift due to the
thermostat. Because the random forces on different atoms are
independent, they do not sum exactly to zero. As a result, this fix
applies a small random force to the entire system, and the
center-of-mass of the system undergoes a slow random walk. If the
keyword <I>zero</I> is set to <I>yes</I>, the total random force is set exactly
to zero by subtracting off an equal part of it from each atom in the
group. As a result, the center-of-mass of a system with zero initial
momentum will not drift over time.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. Because the state of the random number generator
is not saved in restart files, this means you cannot do "exact"
restarts with this fix, where the simulation continues on the same as
if no restart had taken place. However, in a statistical sense, a
restarted simulation should produce the same behavior.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>temp</I> option is supported by this
fix. You can use it to assign a temperature <A HREF = "compute.html">compute</A>
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by this
fix to add the energy change induced by Langevin thermostatting to the
system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>. Note that use of this option requires
setting the <I>tally</I> keyword to <I>yes</I>.
</P>
<P>This fix computes a global scalar which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive". Note that calculation of this
quantity requires setting the <I>tally</I> keyword to <I>yes</I>.
</P>
<P>This fix can ramp its target temperature over multiple runs, using the
<I>start</I> and <I>stop</I> keywords of the <A HREF = "run.html">run</A> command. See the
<A HREF = "run.html">run</A> command for details of how to do this.
</P>
<P>This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "fix_temp_rescale.html">fix temp/rescale</A>, <A HREF = "fix_viscous.html">fix
viscous</A>, <A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "pair_dpd.html">pair_style
dpd/tstat</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are angmom = no, omega = no, scale = 1.0 for all
types, tally = no, zero = no.
</P>
<HR>
<A NAME = "Dunweg"></A>
<P><B>(Dunweg)</B> Dunweg and Paul, Int J of Modern Physics C, 2, 817-27 (1991).
</P>
<A NAME = "Schneider"></A>
<P><B>(Schneider)</B> Schneider and Stoll, Phys Rev B, 17, 1302 (1978).
</P>
</HTML>
diff --git a/doc/fix_langevin.txt b/doc/fix_langevin.txt
index 63fd2135f..085bcdccd 100644
--- a/doc/fix_langevin.txt
+++ b/doc/fix_langevin.txt
@@ -1,238 +1,256 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix langevin command :h3
[Syntax:]
fix ID group-ID langevin Tstart Tstop damp seed keyword values ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
langevin = style name of this fix command :l
Tstart,Tstop = desired temperature at start/end of run (temperature units) :l
+ Tstart can be a variable (see below) :pre
damp = damping parameter (time units) :l
seed = random number seed to use for white noise (positive integer) :l
zero or more keyword/value pairs may be appended :l
keyword = {angmom} or {omega} or {scale} or {tally} or {zero} :l
{angmom} value = {no} or {yes}
{no} = do not thermostat rotational degrees of freedom via the angular momentum
{yes} = do thermostat rotational degrees of freedom via the angular momentum
{omega} value = {no} or {yes}
- {no} = do not thermostat rotational degrees of freedom via then angular velocity
+ {no} = do not thermostat rotational degrees of freedom via the angular velocity
{yes} = do thermostat rotational degrees of freedom via the angular velocity
{scale} values = type ratio
type = atom type (1-N)
ratio = factor by which to scale the damping coefficient
{tally} value = {no} or {yes}
{no} = do not tally the energy added/subtracted to atoms
{yes} = do tally the energy added/subtracted to atoms
{zero} value = {no} or {yes}
{no} = do not set total random force to zero
{yes} = set total random force to zero :pre
:ule
[Examples:]
fix 3 boundary langevin 1.0 1.0 1000.0 699483
fix 1 all langevin 1.0 1.1 100.0 48279 scale 3 1.5 :pre
[Description:]
Apply a Langevin thermostat as described in "(Schneider)"_#Schneider
to a group of atoms which models an interaction with a background
implicit solvent. Used with "fix nve"_fix_nve.html, this command
performs Brownian dynamics (BD), since the total force on each atom
will have the form:
F = Fc + Ff + Fr
Ff = - (m / damp) v
Fr is proportional to sqrt(Kb T m / (dt damp)) :pre
Fc is the conservative force computed via the usual inter-particle
interactions ("pair_style"_pair_style.html,
"bond_style"_bond_style.html, etc).
The Ff and Fr terms are added by this fix on a per-particle basis.
See the "pair_style dpd/tstat"_pair_dpd.html command for a
thermostatting option that adds similar terms on a pairwise basis to
pairs of interacting particles.
Ff is a frictional drag or viscous damping term proportional to the
particle's velocity. The proportionality constant for each atom is
computed as m/damp, where m is the mass of the particle and damp is
the damping factor specified by the user.
Fr is a force due to solvent atoms at a temperature T randomly bumping
into the particle. As derived from the fluctuation/dissipation
theorem, its magnitude as shown above is proportional to sqrt(Kb T m /
dt damp), where Kb is the Boltzmann constant, T is the desired
temperature, m is the mass of the particle, dt is the timestep size,
and damp is the damping factor. Random numbers are used to randomize
the direction and magnitude of this force as described in
"(Dunweg)"_#Dunweg, where a uniform random number is used (instead of
a Gaussian random number) for speed.
Note that the thermostat effect of this fix is applied to only the
translational degrees of freedom for the particles, which is an
important consideration if extended spherical or aspherical particles
which have rotational degrees of freedom are being thermostatted with
this fix. The translational degrees of freedom can also have a bias
velocity removed from them before thermostatting takes place; see the
description below.
IMPORTANT NOTE: Unlike the "fix nvt"_fix_nh.html command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies forces to effect
thermostatting. Thus you must use a separate time integration fix,
like "fix nve"_fix_nve.html to actually update the velocities and
positions of atoms using the modified forces. Likewise, this fix
should not normally be used on atoms that also have their temperature
controlled by another fix - e.g. by "fix nvt"_fix_nh.html or "fix
temp/rescale"_fix_temp_rescale.html commands.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
The desired temperature at each timestep is a ramped value during the
run from {Tstart} to {Tstop}.
+{Tstart} can be specified as an equal-style or atom-style
+"variable"_variable.html. In this case, the {Tstop} setting is
+ignored. If the value is a variable, it should be specified as
+v_name, where name is the variable name. In this case, the variable
+will be evaluated each timestep, and its value used to determine the
+target temperature.
+
+Equal-style variables can specify formulas with various mathematical
+functions, and include "thermo_style"_thermo_style.html command
+keywords for the simulation box parameters and timestep and elapsed
+time. Thus it is easy to specify a time-dependent temperature.
+
+Atom-style variables can specify the same formulas as equal-style
+variables but can also include per-atom values, such as atom
+coordinates. Thus it is easy to specify a spatially-dependent
+temperature with optional time-dependence as well.
+
Like other fixes that perform thermostatting, this fix can be used
with "compute commands"_compute.html that remove a "bias" from the
atom velocities. E.g. removing the center-of-mass velocity from a
group of atoms or removing the x-component of velocity from the
calculation. This is not done by default, but only if the
"fix_modify"_fix_modify.html command is used to assign a temperature
compute to this fix that includes such a bias term. See the doc pages
for individual "compute commands"_compute.html to determine which ones
include a bias. In this case, the thermostat works in the following
manner: bias is removed from each atom, thermostatting is performed on
the remaining thermal degrees of freedom, and the bias is added back
in.
The {damp} parameter is specified in time units and determines how
rapidly the temperature is relaxed. For example, a value of 100.0
means to relax the temperature in a timespan of (roughly) 100 time
units (tau or fmsec or psec - see the "units"_units.html command).
The damp factor can be thought of as inversely related to the
viscosity of the solvent. I.e. a small relaxation time implies a
hi-viscosity solvent and vice versa. See the discussion about gamma
and viscosity in the documentation for the "fix
viscous"_fix_viscous.html command for more details.
The random # {seed} must be a positive integer. A Marsaglia random
number generator is used. Each processor uses the input seed to
generate its own unique seed and its own stream of random numbers.
Thus the dynamics of the system will not be identical on two runs on
different numbers of processors.
:line
The keyword/value option pairs are used in the following ways.
The keyword {angmom} and {omega} keywords enable thermostatting of
rotational degrees of freedom in addition to the usual translational
degrees of freedom. This can only be done for finite-size particles.
A simulation using atom_style sphere defines an omega for finite-size
spheres. A simulation using atom_style ellipsoid defines a finite
size and shape for aspherical particles and an angular momentum. The
Langevin formulas for thermostatting the rotational degrees of freedom
are the same as those above, where force is replaced by torque, m is
replaced by the moment of inertia I, and v is replaced by omega (which
is derived from the angular momentum in the case of aspherical
particles). The rotational temperature of the particles can be
monitored by the "compute temp/sphere"_compute_temp_sphere.html and
"compute temp/asphere"_compute_temp_asphere.html commands with their
rotate options.
The keyword {scale} allows the damp factor to be scaled up or down by
the specified factor for atoms of that type. This can be useful when
different atom types have different sizes or masses. It can be used
multiple times to adjust damp for several atom types. Note that
specifying a ratio of 2 increases the relaxation time which is
equivalent to the solvent's viscosity acting on particles with 1/2 the
diameter. This is the opposite effect of scale factors used by the
"fix viscous"_fix_viscous.html command, since the damp factor in fix
{langevin} is inversely related to the gamma factor in fix {viscous}.
Also note that the damping factor in fix {langevin} includes the
particle mass in Ff, unlike fix {viscous}. Thus the mass and size of
different atom types should be accounted for in the choice of ratio
values.
The keyword {tally} enables the calculation of the cumulative energy
added/subtracted to the atoms as they are thermostatted. Effectively
it is the energy exchanged between the infinite thermal reservoir and
the particles. As described below, this energy can then be printed
out or added to the potential energy of the system to monitor energy
conservation.
The keyword {zero} can be used to eliminate drift due to the
thermostat. Because the random forces on different atoms are
independent, they do not sum exactly to zero. As a result, this fix
applies a small random force to the entire system, and the
center-of-mass of the system undergoes a slow random walk. If the
keyword {zero} is set to {yes}, the total random force is set exactly
to zero by subtracting off an equal part of it from each atom in the
group. As a result, the center-of-mass of a system with zero initial
momentum will not drift over time.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. Because the state of the random number generator
is not saved in restart files, this means you cannot do "exact"
restarts with this fix, where the simulation continues on the same as
if no restart had taken place. However, in a statistical sense, a
restarted simulation should produce the same behavior.
The "fix_modify"_fix_modify.html {temp} option is supported by this
fix. You can use it to assign a temperature "compute"_compute.html
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the energy change induced by Langevin thermostatting to the
system's potential energy as part of "thermodynamic
output"_thermo_style.html. Note that use of this option requires
setting the {tally} keyword to {yes}.
This fix computes a global scalar which can be accessed by various
"output commands"_Section_howto.html#howto_15. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive". Note that calculation of this
quantity requires setting the {tally} keyword to {yes}.
This fix can ramp its target temperature over multiple runs, using the
{start} and {stop} keywords of the "run"_run.html command. See the
"run"_run.html command for details of how to do this.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:] none
[Related commands:]
"fix nvt"_fix_nh.html, "fix temp/rescale"_fix_temp_rescale.html, "fix
viscous"_fix_viscous.html, "fix nvt"_fix_nh.html, "pair_style
dpd/tstat"_pair_dpd.html
[Default:]
The option defaults are angmom = no, omega = no, scale = 1.0 for all
types, tally = no, zero = no.
:line
:link(Dunweg)
[(Dunweg)] Dunweg and Paul, Int J of Modern Physics C, 2, 817-27 (1991).
:link(Schneider)
[(Schneider)] Schneider and Stoll, Phys Rev B, 17, 1302 (1978).
diff --git a/doc/fix_meso.html b/doc/fix_meso.html
index b3684d872..81bb83334 100644
--- a/doc/fix_meso.html
+++ b/doc/fix_meso.html
@@ -1,57 +1,57 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix meso command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID meso
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>meso = style name of this fix command
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all meso
</PRE>
<P><B>Description:</B>
</P>
<P>Perform time integration to update position, velocity, internal energy
and local density for atoms in the group each timestep. This fix is
needed to time-integrate mesoscopic systems where particles carry
internal variables such as SPH or DPDE.
</P>
<P>See <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">this PDF guide</A> to using SPH in
LAMMPS.
</P>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
-by this fix for access by various <A HREF = "Section_howto.html#4_15">output
-commands</A>. No parameter of this fix can be
-used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
+by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
+commands</A>. No parameter of this fix can
+be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P>"fix meso/stationary"
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_meso.txt b/doc/fix_meso.txt
index 7c6a5cfc4..85f5838dd 100644
--- a/doc/fix_meso.txt
+++ b/doc/fix_meso.txt
@@ -1,52 +1,52 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix meso command :h3
[Syntax:]
fix ID group-ID meso :pre
ID, group-ID are documented in "fix"_fix.html command
meso = style name of this fix command :ul
[Examples:]
fix 1 all meso :pre
[Description:]
Perform time integration to update position, velocity, internal energy
and local density for atoms in the group each timestep. This fix is
needed to time-integrate mesoscopic systems where particles carry
internal variables such as SPH or DPDE.
See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
LAMMPS.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
-commands"_Section_howto.html#4_15. No parameter of this fix can be
-used with the {start/stop} keywords of the "run"_run.html command.
+commands"_Section_howto.html#howto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
This fix is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"fix meso/stationary"
[Default:] none
diff --git a/doc/fix_meso_stationary.html b/doc/fix_meso_stationary.html
index 67a9a6a20..cf339c256 100644
--- a/doc/fix_meso_stationary.html
+++ b/doc/fix_meso_stationary.html
@@ -1,58 +1,58 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix meso/stationary command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID meso/stationary
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>meso = style name of this fix command
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 boundary meso/stationary
</PRE>
<P><B>Description:</B>
</P>
<P>Perform time integration to update internal energy and local density,
but not position or velocity for atoms in the group each timestep.
This fix is needed for SPH simulations to correctly time-integrate
fixed boundary particles which constrain a fluid to a given region in
space.
</P>
<P>See <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">this PDF guide</A> to using SPH in
LAMMPS.
</P>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
-by this fix for access by various <A HREF = "Section_howto.html#4_15">output
-commands</A>. No parameter of this fix can be
-used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
+by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
+commands</A>. No parameter of this fix can
+be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P>"fix meso"
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_meso_stationary.txt b/doc/fix_meso_stationary.txt
index 31bdb4b1f..5b83573bc 100644
--- a/doc/fix_meso_stationary.txt
+++ b/doc/fix_meso_stationary.txt
@@ -1,53 +1,53 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix meso/stationary command :h3
[Syntax:]
fix ID group-ID meso/stationary :pre
ID, group-ID are documented in "fix"_fix.html command
meso = style name of this fix command :ul
[Examples:]
fix 1 boundary meso/stationary :pre
[Description:]
Perform time integration to update internal energy and local density,
but not position or velocity for atoms in the group each timestep.
This fix is needed for SPH simulations to correctly time-integrate
fixed boundary particles which constrain a fluid to a given region in
space.
See "this PDF guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in
LAMMPS.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
-commands"_Section_howto.html#4_15. No parameter of this fix can be
-used with the {start/stop} keywords of the "run"_run.html command.
+commands"_Section_howto.html#howto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
This fix is part of the USER-SPH package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"fix meso"
[Default:] none
diff --git a/doc/fix_neb.html b/doc/fix_neb.html
index 79390f9b3..23a8b894d 100644
--- a/doc/fix_neb.html
+++ b/doc/fix_neb.html
@@ -1,113 +1,113 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix neb command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID neb Kspring
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>neb = style name of this fix command
<LI>Kspring = inter-replica spring constant (force/distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 active neb 10.0
</PRE>
<P><B>Description:</B>
</P>
<P>Add inter-replica forces to atoms in the group for a multi-replica
simulation run via the <A HREF = "neb.html">neb</A> command to perform a nudged
elastic band (NEB) calculation for transition state finding. Hi-level
explanations of NEB are given with the <A HREF = "neb.html">neb</A> command and in
-<A HREF = "Section_howto.html#howto_5">this section</A> of the manual. The fix neb
-command must be used with the "neb" command to define how
+<A HREF = "Section_howto.html#howto_5">Section_howto 5</A> of the manual. The fix
+neb command must be used with the "neb" command to define how
inter-replica forces are computed.
</P>
<P>Only the N atoms in the fix group experience inter-replica forces.
Atoms in the two end-point replicas do not experience these forces,
but those in intermediate replicas do. During the initial stage of
NEB, the 3N-length vector of interatomic forces Fi = -Grad(V) acting
on the atoms of each intermediate replica I is altered, as described
in the <A HREF = "#Henkelman1">(Henkelman1)</A> paper, to become:
</P>
<PRE>Fi = -Grad(V) + (Grad(V) dot That) That + Kspring (|Ri+i - Ri| - |Ri - Ri-1|) That
</PRE>
<P>Ri are the atomic coordinates of replica I; Ri-1 and Ri+1 are the
coordinates of its neighbor replicas. That (t with a hat over it) is
the unit "tangent" vector for replica I which is a function of Ri,
Ri-1, Ri+1, and the potential energy of the 3 replicas; it points
roughly in the direction of (Ri+i - Ri-1); see the
<A HREF = "#Henkelman1">(Henkelman1)</A> paper for details.
</P>
<P>The first two terms in the above equation are the component of the
interatomic forces perpendicular to the tangent vector. The last term
is a spring force between replica I and its neighbors, parallel to the
tangent vector direction with the specified spring constant <I>Kspring</I>.
</P>
<P>The effect of the first two terms is to push the atoms of each replica
toward the minimum energy path (MEP) of conformational states that
transition over the energy barrier. The MEP for an energy barrier is
defined as a sequence of 3N-dimensional states which cross the barrier
at its saddle point, each of which has a potential energy gradient
parallel to the MEP itself.
</P>
<P>The effect of the last term is to push each replica away from its two
neighbors in a direction along the MEP, so that the final set of
states are equidistant from each other.
</P>
<P>During the second stage of NEB, the forces on the N atoms in the
replica nearest the top of the energy barrier are altered so that it
climbs to the top of the barrier and finds the saddle point. The
forces on atoms in this replica are described in the
<A HREF = "#Henkelman2">(Henkelman2)</A> paper, and become:
</P>
<PRE>Fi = -Grad(V) + 2 (Grad(V) dot That) That
</PRE>
<P>The inter-replica forces for the other replicas are unchanged from the
first equation.
</P>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
as invoked by the <A HREF = "minimize.html">minimize</A> command via the
<A HREF = "neb.html">neb</A> command.
</P>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "neb.html">neb</A>
</P>
<P><B>Default:</B> none
</P>
<A NAME = "Henkelman"></A>
<P><B>(Henkelman1)</B> Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
</P>
<A NAME = "Henkelman"></A>
<P><B>(Henkelman2)</B> Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
</P>
</HTML>
diff --git a/doc/fix_neb.txt b/doc/fix_neb.txt
index 397a259c4..c84b46a42 100644
--- a/doc/fix_neb.txt
+++ b/doc/fix_neb.txt
@@ -1,106 +1,106 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix neb command :h3
[Syntax:]
fix ID group-ID neb Kspring :pre
ID, group-ID are documented in "fix"_fix.html command
neb = style name of this fix command
Kspring = inter-replica spring constant (force/distance units) :ul
[Examples:]
fix 1 active neb 10.0 :pre
[Description:]
Add inter-replica forces to atoms in the group for a multi-replica
simulation run via the "neb"_neb.html command to perform a nudged
elastic band (NEB) calculation for transition state finding. Hi-level
explanations of NEB are given with the "neb"_neb.html command and in
-"this section"_Section_howto.html#howto_5 of the manual. The fix neb
-command must be used with the "neb" command to define how
+"Section_howto 5"_Section_howto.html#howto_5 of the manual. The fix
+neb command must be used with the "neb" command to define how
inter-replica forces are computed.
Only the N atoms in the fix group experience inter-replica forces.
Atoms in the two end-point replicas do not experience these forces,
but those in intermediate replicas do. During the initial stage of
NEB, the 3N-length vector of interatomic forces Fi = -Grad(V) acting
on the atoms of each intermediate replica I is altered, as described
in the "(Henkelman1)"_#Henkelman1 paper, to become:
Fi = -Grad(V) + (Grad(V) dot That) That + Kspring (|Ri+i - Ri| - |Ri - Ri-1|) That :pre
Ri are the atomic coordinates of replica I; Ri-1 and Ri+1 are the
coordinates of its neighbor replicas. That (t with a hat over it) is
the unit "tangent" vector for replica I which is a function of Ri,
Ri-1, Ri+1, and the potential energy of the 3 replicas; it points
roughly in the direction of (Ri+i - Ri-1); see the
"(Henkelman1)"_#Henkelman1 paper for details.
The first two terms in the above equation are the component of the
interatomic forces perpendicular to the tangent vector. The last term
is a spring force between replica I and its neighbors, parallel to the
tangent vector direction with the specified spring constant {Kspring}.
The effect of the first two terms is to push the atoms of each replica
toward the minimum energy path (MEP) of conformational states that
transition over the energy barrier. The MEP for an energy barrier is
defined as a sequence of 3N-dimensional states which cross the barrier
at its saddle point, each of which has a potential energy gradient
parallel to the MEP itself.
The effect of the last term is to push each replica away from its two
neighbors in a direction along the MEP, so that the final set of
states are equidistant from each other.
During the second stage of NEB, the forces on the N atoms in the
replica nearest the top of the energy barrier are altered so that it
climbs to the top of the barrier and finds the saddle point. The
forces on atoms in this replica are described in the
"(Henkelman2)"_#Henkelman2 paper, and become:
Fi = -Grad(V) + 2 (Grad(V) dot That) That :pre
The inter-replica forces for the other replicas are unchanged from the
first equation.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
as invoked by the "minimize"_minimize.html command via the
"neb"_neb.html command.
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"neb"_neb.html
[Default:] none
:link(Henkelman)
[(Henkelman1)] Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
:link(Henkelman)
[(Henkelman2)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
diff --git a/doc/fix_nh.html b/doc/fix_nh.html
index 6bf376ba7..845d2cd0a 100644
--- a/doc/fix_nh.html
+++ b/doc/fix_nh.html
@@ -1,545 +1,545 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix nvt command
</H3>
<H3>fix nvt/cuda command
</H3>
<H3>fix npt command
</H3>
<H3>fix npt/cuda command
</H3>
<H3>fix nph command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID style_name keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>style_name = <I>nvt</I> or <I>npt</I> or <I>nph</I>
<PRE>one or more keyword value pairs may be appended
keyword = <I>temp</I> or <I>iso</I> or <I>aniso</I> or <I>tri</I> or <I>x</I> or <I>y</I> or <I>z</I> or <I>xy</I> or <I>yz</I> or <I>xz</I> or <I>couple</I> or <I>tchain</I> or <I>pchain</I> or <I>mtk</I> or <I>tloop</I> or <I>ploop</I> or <I>nreset</I> or <I>drag</I> or <I>dilate</I> or <I>scaleyz</I> or <I>scalexz</I> or <I>scalexy</I>
<I>temp</I> values = Tstart Tstop Tdamp
Tstart,Tstop = external temperature at start/end of run
Tdamp = temperature damping parameter (time units)
<I>iso</I> or <I>aniso</I> or <I>tri</I> values = Pstart Pstop Pdamp
Pstart,Pstop = scalar external pressure at start/end of run (pressure units)
Pdamp = pressure damping parameter (time units)
<I>x</I> or <I>y</I> or <I>z</I> or <I>xy</I> or <I>yz</I> or <I>xz</I> values = Pstart Pstop Pdamp
Pstart,Pstop = external stress tensor component at start/end of run (pressure units)
Pdamp = stress damping parameter (time units)
<I>couple</I> = <I>none</I> or <I>xyz</I> or <I>xy</I> or <I>yz</I> or <I>xz</I>
<I>tchain</I> value = length of thermostat chain (1 = single thermostat)
<I>pchain</I> values = length of thermostat chain on barostat (0 = no thermostat)
<I>mtk</I> value = <I>yes</I> or <I>no</I> = add in MTK adjustment term or not
<I>tloop</I> value = number of sub-cycles to perform on thermostat
<I>ploop</I> value = number of sub-cycles to perform on barostat thermostat
<I>nreset</I> value = reset reference cell every this many timesteps
<I>drag</I> value = drag factor added to barostat/thermostat (0.0 = no drag)
<I>dilate</I> value = <I>all</I> or <I>partial</I>
<I>scaleyz</I> value = <I>yes</I> or <I>no</I> = scale yz with lz
<I>scalexz</I> value = <I>yes</I> or <I>no</I> = scale xz with lz
<I>scalexy</I> value = <I>yes</I> or <I>no</I> = scale xy with ly
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all nvt temp 300.0 300.0 100.0
fix 1 water npt temp 300.0 300.0 100.0 iso 0.0 0.0 1000.0
fix 2 jello npt temp 300.0 300.0 100.0 tri 5.0 5.0 1000.0
fix 2 ice nph x 1.0 1.0 0.5 y 2.0 2.0 0.5 z 3.0 3.0 0.5 yz 0.1 0.1 0.5 xz 0.2 0.2 0.5 xy 0.3 0.3 0.5 nreset 1000
</PRE>
<P><B>Description:</B>
</P>
<P>These commands perform time integration on Nose-Hoover style
non-Hamiltonian equations of motion which are designed to generate
positions and velocities sampled from the canonical (nvt),
isothermal-isobaric (npt), and isenthalpic (nph) ensembles. This is
achieved by adding some dynamic variables which are coupled to the
particle velocities (thermostatting) and simulation domain dimensions
(barostatting). In addition to basic thermostatting and barostatting,
these fixes can also create a chain of thermostats coupled to the
particle thermostat, and another chain of thermostats coupled to the
barostat variables. The barostat can be coupled to the overall box
volume, or to individual dimensions, including the <I>xy</I>, <I>xz</I> and <I>yz</I>
tilt dimensions. The external pressure of the barostat can be
specified as either a scalar pressure (isobaric ensemble) or as
components of a symmetric stress tensor (constant stress ensemble).
When used correctly, the time-averaged temperature and stress tensor
of the particles will match the target values specified by
Tstart/Tstop and Pstart/Pstop.
</P>
<P>The equations of motion used are those of Shinoda et al. in
<A HREF = "#Shinoda">(Shinoda)</A>, which combine the hydrostatic equations of
Martyna, Tobias and Klein in <A HREF = "#Martyna">(Martyna)</A> with the strain
energy proposed by Parrinello and Rahman in
<A HREF = "#Parrinello">(Parrinello)</A>. The time integration schemes closely
follow the time-reversible measure-preserving Verlet and
rRESPA integrators derived by Tuckerman et al. in <A HREF = "#Tuckerman">(Tuckerman)</A>.
</P>
<HR>
<P>The thermostat for fix styles <I>nvt</I> and <I>npt</I> is specified using the
<I>temp</I> keyword. Other thermostat-related keywords are <I>tchain</I>,
<I>tloop</I> and <I>drag</I>, which are discussed below.
</P>
<P>The thermostat is applied to only the translational degrees of freedom
for the particles. The translational degrees of freedom can also have
a bias velocity removed before thermostatting takes place; see the
description below. The desired temperature at each timestep is a
ramped value during the run from <I>Tstart</I> to <I>Tstop</I>. The <I>Tdamp</I>
parameter is specified in time units and determines how rapidly the
temperature is relaxed. For example, a value of 10.0 means to relax
the temperature in a timespan of (roughly) 10 time units (e.g. tau or
fmsec or psec - see the <A HREF = "units.html">units</A> command). The atoms in the
fix group are the only ones whose velocities and positions are updated
by the velocity/position update portion of the integration.
</P>
<P>IMPORTANT NOTE: A Nose-Hoover thermostat will not work well for
arbitrary values of <I>Tdamp</I>. If <I>Tdamp</I> is too small, the temperature
can fluctuate wildly; if it is too large, the temperature will take a
very long time to equilibrate. A good choice for many models is a
<I>Tdamp</I> of around 100 timesteps. Note that this is NOT the same as
100 time units for most <A HREF = "units.html">units</A> settings.
</P>
<HR>
<P>The barostat for fix styles <I>npt</I> and <I>nph</I> is specified using one or
more of the <I>iso</I>, <I>aniso</I>, <I>tri</I>, <I>x</I>, <I>y</I>, <I>z</I>, <I>xy</I>, <I>xz</I>, <I>yz</I>,
and <I>couple</I> keywords. These keywords give you the ability to specify
all 6 components of an external stress tensor, and to couple various
of these components together so that the dimensions they represent are
varied together during a constant-pressure simulation.
</P>
<P>Other barostat-related keywords are <I>pchain</I>, <I>mtk</I>, <I>ploop</I>,
<I>nreset</I>, <I>drag</I>, and <I>dilate</I>, which are discussed below.
</P>
<P>Orthogonal simulation boxes have 3 adjustable dimensions (x,y,z).
Triclinic (non-orthogonal) simulation boxes have 6 adjustable
dimensions (x,y,z,xy,xz,yz). The <A HREF = "create_box.html">create_box</A>, <A HREF = "read_data.html">read
data</A>, and <A HREF = "read_restart.html">read_restart</A> commands
specify whether the simulation box is orthogonal or non-orthogonal
(triclinic) and explain the meaning of the xy,xz,yz tilt factors.
</P>
<P>The target pressures for each of the 6 components of the stress tensor
can be specified independently via the <I>x</I>, <I>y</I>, <I>z</I>, <I>xy</I>, <I>xz</I>, <I>yz</I>
keywords, which correspond to the 6 simulation box dimensions. For
each component, the external pressure or tensor component at each
timestep is a ramped value during the run from <I>Pstart</I> to <I>Pstop</I>.
If a target pressure is specified for a component, then the
corresponding box dimension will change during a simulation. For
example, if the <I>y</I> keyword is used, the y-box length will change. If
the <I>xy</I> keyword is used, the xy tilt factor will change. A box
dimension will not change if that component is not specified, although
you have the option to change that dimension via the <A HREF = "fix_deform.html">fix
deform</A> command.
</P>
<P>Note that in order to use the <I>xy</I>, <I>xz</I>, or <I>yz</I> keywords, the
simulation box must be triclinic, even if its initial tilt factors are
0.0.
</P>
<P>For all barostat keywords, the <I>Pdamp</I> parameter operates like the
<I>Tdamp</I> parameter, determining the time scale on which pressure is
relaxed. For example, a value of 10.0 means to relax the pressure in
a timespan of (roughly) 10 time units (e.g. tau or fmsec or psec - see
the <A HREF = "units.html">units</A> command).
</P>
<P>IMPORTANT NOTE: A Nose-Hoover barostat will not work well for
arbitrary values of <I>Pdamp</I>. If <I>Pdamp</I> is too small, the pressure
and volume can fluctuate wildly; if it is too large, the pressure will
take a very long time to equilibrate. A good choice for many models
is a <I>Pdamp</I> of around 1000 timesteps. Note that this is NOT the same
as 1000 time units for most <A HREF = "units.html">units</A> settings.
</P>
<P>Regardless of what atoms are in the fix group, a global pressure or
stress tensor is computed for all atoms. Similarly, when the size of
the simulation box is changed, all atoms are re-scaled to new
positions, unless the keyword <I>dilate</I> is specified with a value of
<I>partial</I>, in which case only the atoms in the fix group are
re-scaled. The latter can be useful for leaving the coordinates of
atoms in a solid substrate unchanged and controlling the pressure of a
surrounding fluid.
</P>
<HR>
<P>The <I>couple</I> keyword allows two or three of the diagonal components of
the pressure tensor to be "coupled" together. The value specified
with the keyword determines which are coupled. For example, <I>xz</I>
means the <I>Pxx</I> and <I>Pzz</I> components of the stress tensor are coupled.
<I>Xyz</I> means all 3 diagonal components are coupled. Coupling means two
things: the instantaneous stress will be computed as an average of the
corresponding diagonal components, and the coupled box dimensions will
be changed together in lockstep, meaning coupled dimensions will be
dilated or contracted by the same percentage every timestep. The
<I>Pstart</I>, <I>Pstop</I>, <I>Pdamp</I> parameters for any coupled dimensions must
be identical. <I>Couple xyz</I> can be used for a 2d simulation; the <I>z</I>
dimension is simply ignored.
</P>
<HR>
<P>The <I>iso</I>, <I>aniso</I>, and <I>tri</I> keywords are simply shortcuts that are
equivalent to specifying several other keywords together.
</P>
<P>The keyword <I>iso</I> means couple all 3 diagonal components together when
pressure is computed (hydrostatic pressure), and dilate/contract the
dimensions together. Using "iso Pstart Pstop Pdamp" is the same as
specifying these 4 keywords:
</P>
<PRE>x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
couple xyz
</PRE>
<P>The keyword <I>aniso</I> means <I>x</I>, <I>y</I>, and <I>z</I> dimensions are controlled
independently using the <I>Pxx</I>, <I>Pyy</I>, and <I>Pzz</I> components of the
stress tensor as the driving forces, and the specified scalar external
pressure. Using "aniso Pstart Pstop Pdamp" is the same as specifying
these 4 keywords:
</P>
<PRE>x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
couple none
</PRE>
<P>The keyword <I>tri</I> means <I>x</I>, <I>y</I>, <I>z</I>, <I>xy</I>, <I>xz</I>, and <I>yz</I> dimensions
are controlled independently using their individual stress components
as the driving forces, and the specified scalar pressure as the
external normal stress. Using "tri Pstart Pstop Pdamp" is the same as
specifying these 7 keywords:
</P>
<PRE>x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
xy 0.0 0.0 Pdamp
yz 0.0 0.0 Pdamp
xz 0.0 0.0 Pdamp
couple none
</PRE>
<HR>
<P>In some cases (e.g. for solids) the pressure (volume) and/or
temperature of the system can oscillate undesirably when a Nose/Hoover
barostat and thermostat is applied. The optional <I>drag</I> keyword will
damp these oscillations, although it alters the Nose/Hoover equations.
A value of 0.0 (no drag) leaves the Nose/Hoover formalism unchanged.
A non-zero value adds a drag term; the larger the value specified, the
greater the damping effect. Performing a short run and monitoring the
pressure and temperature is the best way to determine if the drag term
is working. Typically a value between 0.2 to 2.0 is sufficient to
damp oscillations after a few periods. Note that use of the drag
keyword will interfere with energy conservation and will also change
the distribution of positions and velocities so that they do not
correspond to the nominal NVT, NPT, or NPH ensembles.
</P>
<P>An alternative way to control initial oscillations is to use chain
thermostats. The keyword <I>tchain</I> determines the number of thermostats
in the particle thermostat. A value of 1 corresponds to the original
Nose-Hoover thermostat. The keyword <I>pchain</I> specifies the number of
thermostats in the chain thermostatting the barostat degrees of
freedom. A value of 0 corresponds to no thermostatting of the
barostat variables.
</P>
<P>The <I>mtk</I> keyword controls whether or not the correction terms due to
Martyna, Tuckerman, and Klein are included in the equations of motion
<A HREF = "#Martyna">(Martyna)</A>. Specifying <I>no</I> reproduces the original
Hoover barostat, whose volume probability distribution function
differs from the true NPT and NPH ensembles by a factor of 1/V. Hence
using <I>yes</I> is more correct, but in many cases the difference is
negligible.
</P>
<P>The keyword <I>tloop</I> can be used to improve the accuracy of integration
scheme at little extra cost. The initial and final updates of the
thermostat variables are broken up into <I>tloop</I> substeps, each of
length <I>dt</I>/<I>tloop</I>. This corresponds to using a first-order
Suzuki-Yoshida scheme <A HREF = "#Tuckerman2006">(Tuckerman2006)</A>. The keyword
<I>ploop</I> does the same thing for the barostat thermostat.
</P>
<P>The keyword <I>nreset</I> controls how often the reference dimensions used
to define the strain energy are reset. If this keyword is not used,
or is given a value of zero, then the reference dimensions are set to
those of the initial simulation domain and are never changed. If the
simulation domain changes significantly during the simulation, then
the final average pressure tensor will differ significantly from the
specified values of the external stress tensor. A value of <I>nstep</I>
means that every <I>nstep</I> timesteps, the reference dimensions are set
to those of the current simulation domain.
</P>
<P>The <I>scaleyz</I>, <I>scalexz</I>, and <I>scalexy</I> keywords control whether or
not the corresponding tilt factors are scaled with the
associated box dimensions
when barostatting triclinic periodic cells.
The default values <I>yes</I> will turn on scaling, which corresponds to
adjusting the linear dimensions of the cell while preserving its shape.
Choosing <I>no</I> ensures that the tilt factors are not scaled with the
box dimensions. See below for restrictions and default values in different
situations. In older versions of LAMMPS, scaling of tilt factors was not
performed. The old behavior can be recovered by setting all three
scale keywords to <I>no</I>.
</P>
<HR>
<P>IMPORTANT NOTE: Using a barostat coupled to tilt dimensions <I>xy</I>,
<I>xz</I>, <I>yz</I> can sometimes result in arbitrarily large values of the
tilt dimensions, i.e. a dramatically deformed simulation box. LAMMPS
allows the tilt factors to grow a little beyond the normal limit
of half the box length (0.6 times the box length), and then performs
flipping or re-shaping to an equivalent periodic cell. The re-shaping
operation is described in more detail in the doc page for
<A HREF = "fix_deform.html">fix deform</A>. Both the barostat dynamics and
the atom trajectories are unaffected by this operation. However,
if a tilt factor is incremented by a large amount (1.5 times the
box length) on a single timestep, LAMMPS can not accomodate
this event and will terminate the simulation
with an error. This error typically
indicates that there is something badly wrong with how the simulation
was constructed, such as specifying values of <I>Pstart</I> that are
too far from the current stress value, or specifying a timestep that
is too large. Triclinic barostatting should be used with
care. This also is true for other barostat styles, although they tend
to be more forgiving of insults. In particular, it is important to
recognize that equilibrium liquids can not support a shear stress and
that equilibrium solids can not support shear stresses that exceed the yield stress.
</P>
<P>IMPORTANT NOTE: Unlike the <A HREF = "fix_temp_berendsen.html">fix
temp/berendsen</A> command which performs
thermostatting but NO time integration, these fixes perform
thermostatting/barostatting AND time integration. Thus you should not
use any other time integration fix, such as <A HREF = "fix_nve.html">fix nve</A> on
atoms to which this fix is applied. Likewise, the <I>temp</I> options for
fix nvt and fix npt should not normally be used on atoms that also
have their temperature controlled by another fix - e.g. by <A HREF = "fix_nh.html">fix
langevin</A> or <A HREF = "fix_temp_rescale.html">fix temp/rescale</A>
commands.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting and barostatting.
</P>
<HR>
<P>These fixes compute a temperature and pressure each timestep. To do
this, the fix creates its own computes of style "temp" and "pressure",
as if one of these two sets of commands had been issued:
</P>
<PRE>compute fix-ID_temp group-ID temp
compute fix-ID_press group-ID pressure fix-ID_temp
</PRE>
<PRE>compute fix-ID_temp all temp
compute fix-ID_press all pressure fix-ID_temp
</PRE>
<P>See the <A HREF = "compute_temp.html">compute temp</A> and <A HREF = "compute_pressure.html">compute
pressure</A> commands for details. Note that the
IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID
+ underscore + "press". For fix nvt, the group for the new computes
is the same as the fix group. For fix nph and fix npt, the group for
the new computes is "all" since pressure is computed for the entire
system.
</P>
<P>Note that these are NOT the computes used by thermodynamic output (see
the <A HREF = "thermo_style.html">thermo_style</A> command) with ID = <I>thermo_temp</I>
and <I>thermo_press</I>. This means you can change the attributes of this
fix's temperature or pressure via the
<A HREF = "compute_modify.html">compute_modify</A> command or print this temperature
or pressure during thermodynamic output via the <A HREF = "thermo_style.html">thermo_style
custom</A> command using the appropriate compute-ID.
It also means that changing attributes of <I>thermo_temp</I> or
<I>thermo_press</I> will have no effect on this fix.
</P>
<P>Like other fixes that perform thermostatting, fix nvt and fix npt can
be used with <A HREF = "compute.html">compute commands</A> that calculate a
temperature after removing a "bias" from the atom velocities.
E.g. removing the center-of-mass velocity from a group of atoms or
only calculating temperature on the x-component of velocity or only
calculating temperature for atoms in a geometric region. This is not
done by default, but only if the <A HREF = "fix_modify.html">fix_modify</A> command
is used to assign a temperature compute to this fix that includes such
a bias term. See the doc pages for individual <A HREF = "compute.html">compute
commands</A> to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>These fixes writes the state of all the thermostat and barostat
variables to <A HREF = "restart.html">binary restart files</A>. See the
<A HREF = "read_restart.html">read_restart</A> command for info on how to re-specify
a fix in an input script that reads a restart file, so that the
operation of the fix continues in an uninterrupted fashion.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>temp</I> and <I>press</I> options are
supported by these fixes. You can use them to assign a
<A HREF = "compute.html">compute</A> you have defined to this fix which will be used
in its thermostatting or barostatting procedure, as described above.
If you do this, note that the kinetic energy derived from the compute
temperature should be consistent with the virial term computed using
all atoms for the pressure. LAMMPS will warn you if you choose to
compute temperature on a subset of atoms.
</P>
<P>IMPORTANT NOTE: If both the <I>temp</I> and <I>press</I> keywords are used in a
single thermo_modify command (or in two separate commands), then the
order in which the keywords are specified is important. Note that a
<A HREF = "compute_pressure.html">pressure compute</A> defines its own temperature
compute as an argument when it is specified. The <I>temp</I> keyword will
override this (for the pressure compute being used by fix npt), but
only if the <I>temp</I> keyword comes after the <I>press</I> keyword. If the
<I>temp</I> keyword comes before the <I>press</I> keyword, then the new pressure
compute specified by the <I>press</I> keyword will be unaffected by the
<I>temp</I> setting.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by these
fixes to add the energy change induced by Nose/Hoover thermostatting
and barostatting to the system's potential energy as part of
<A HREF = "thermo_style.html">thermodynamic output</A>.
</P>
<P>These fixes compute a global scalar and a global vector of quantities,
which can be accessed by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. The scalar value calculated by
these fixes is "extensive"; the vector values are "intensive".
</P>
<P>The scalar is the cumulative energy change due to the fix.
</P>
<P>The vector stores internal Nose/Hoover thermostat and barostat
variables. The number and meaning of the vector values depends on
which fix is used and the settings for keywords <I>tchain</I> and <I>pchain</I>,
which specify the number of Nose/Hoover chains for the thermostat and
barostat. If no thermostatting is done, then <I>tchain</I> is 0. If no
barostatting is done, then <I>pchain</I> is 0. In the following list,
"ndof" is 0, 1, 3, or 6, and is the number of degrees of freedom in
the barostat. Its value is 0 if no barostat is used, else its value
is 6 if any off-diagonal stress tensor component is barostatted, else
its value is 1 if <I>couple xyz</I> is used or <I>couple xy</I> for a 2d
simulation, otherwise its value is 3.
</P>
<P>The order of values in the global vector and their meaning is as
follows. The notation means there are tchain values for eta, followed
by tchain for eta_dot, followed by ndof for omega, etc:
</P>
<UL><LI>eta[tchain] = particle thermostat displacements (unitless)
<LI>eta_dot[tchain] = particle thermostat velocities (1/time units)
<LI>omega[ndof] = barostat displacements (unitless)
<LI>omega_dot[ndof] = barostat velocities (1/time units)
<LI>etap[pchain] = barostat thermostat displacements (unitless)
<LI>etap_dot[pchain] = barostat thermostat velocities (1/time units)
<LI>PE_eta[tchain] = potential energy of each particle thermostat displacement (energy units)
<LI>KE_eta_dot[tchain] = kinetic energy of each particle thermostat velocity (energy units)
<LI>PE_omega[ndof] = potential energy of each barostat displacement (energy units)
<LI>KE_omega_dot[ndof] = kinetic energy of each barostat velocity (energy units)
<LI>PE_etap[pchain] = potential energy of each barostat thermostat displacement (energy units)
<LI>KE_etap_dot[pchain] = kinetic energy of each barostat thermostat velocity (energy units)
<LI>PE_strain[1] = scalar strain energy (energy units)
</UL>
<P>These fixes can ramp their external temperature and pressure over
multiple runs, using the <I>start</I> and <I>stop</I> keywords of the
<A HREF = "run.html">run</A> command. See the <A HREF = "run.html">run</A> command for details of
how to do this.
</P>
<P>These fixes are not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P>These fixes can be used with either the <I>verlet</I> or <I>respa</I>
<A HREF = "run_style.html">integrators</A>. When using one of the barostat fixes
with <I>respa</I>, LAMMPS uses an integrator constructed
according to the following factorization of the Liouville propagator
(for two rRESPA levels):
</P>
<CENTER><IMG SRC = "Eqs/fix_nh1.jpg">
</CENTER>
<P>This factorization differs somewhat from that of Tuckerman et al., in that
the barostat is only updated at the outermost rRESPA level, whereas
Tuckerman's factorization requires splitting the pressure into pieces
corresponding to the forces computed at each rRESPA level. In theory, the
latter method will exhibit better numerical stability. In practice,
because Pdamp is normally chosen to be a large multiple of the
outermost rRESPA timestep, the barostat dynamics are not the
limiting factor for numerical stability. Both
factorizations are time-reversible and can be shown to preserve the phase
space measure of the underlying non-Hamiltonian equations of motion.
</P>
<P><B>Restrictions:</B>
</P>
<P>Non-periodic dimensions cannot be barostatted. <I>Z</I>, <I>xz</I>, and <I>yz</I>,
cannot be barostatted 2D simulations. <I>Xy</I>, <I>xz</I>, and <I>yz</I> can only
be barostatted if the simulation domain is triclinic and the 2nd
dimension in the keyword (<I>y</I> dimension in <I>xy</I>) is periodic. The
<A HREF = "create_box.html">create_box</A>, <A HREF = "read_data.html">read data</A>, and
<A HREF = "read_restart.html">read_restart</A> commands specify whether the
simulation box is orthogonal or non-orthogonal (triclinic) and explain
the meaning of the xy,xz,yz tilt factors.
</P>
<P>For the <I>temp</I> keyword, the final Tstop cannot be 0.0 since it would
make the external T = 0.0 at some timestep during the simulation which
is not allowed in the Nose/Hoover formulation.
</P>
<P>The <I>scaleyz yes</I> and <I>scalexz yes</I> keyword/value pairs can not be used
for 2D simulations. <I>scaleyz yes</I>, <I>scalexz yes</I>, and <I>scalexy yes</I> options
can only be used if the 2nd dimension in the keyword is periodic,
and if the tilt factor is not coupled to the barostat via keywords
<I>tri</I>, <I>yz</I>, <I>xz</I>, and <I>xy</I>.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_nve.html">fix nve</A>, <A HREF = "fix_modify.html">fix_modify</A>, <A HREF = "run_style.html">run_style</A>
</P>
<P><B>Default:</B>
</P>
<P>The keyword defaults are tchain = 3, pchain = 3, mtk = yes, tloop =
ploop = 1, nreset = 0, drag = 0.0, dilate = all, couple = none,
scaleyz = scalexz = scalexy = yes if periodic in 2nd dimension and
not coupled to barostat, otherwise no.
</P>
<HR>
<A NAME = "Martyna"></A>
<P><B>(Martyna)</B> Martyna, Tobias and Klein, J Chem Phys, 101, 4177 (1994).
</P>
<A NAME = "Parrinello"></A>
<P><B>(Parrinello)</B> Parrinello and Rahman, J Appl Phys, 52, 7182 (1981).
</P>
<A NAME = "Tuckerman"></A>
<P><B>(Tuckerman)</B> Tuckerman, Alejandre, Lopez-Rendon, Jochim, and
Martyna, J Phys A: Math Gen, 39, 5629 (2006).
</P>
<A NAME = "Shinoda"></A>
<P><B>(Shinoda)</B> Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004).
</P>
</HTML>
diff --git a/doc/fix_nh.txt b/doc/fix_nh.txt
index f7dd7f256..749097a8c 100644
--- a/doc/fix_nh.txt
+++ b/doc/fix_nh.txt
@@ -1,529 +1,529 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix nvt command :h3
fix nvt/cuda command :h3
fix npt command :h3
fix npt/cuda command :h3
fix nph command :h3
[Syntax:]
fix ID group-ID style_name keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
style_name = {nvt} or {npt} or {nph} :l
one or more keyword value pairs may be appended
keyword = {temp} or {iso} or {aniso} or {tri} or {x} or {y} or {z} or {xy} or {yz} or {xz} or {couple} or {tchain} or {pchain} or {mtk} or {tloop} or {ploop} or {nreset} or {drag} or {dilate} or {scaleyz} or {scalexz} or {scalexy}
{temp} values = Tstart Tstop Tdamp
Tstart,Tstop = external temperature at start/end of run
Tdamp = temperature damping parameter (time units)
{iso} or {aniso} or {tri} values = Pstart Pstop Pdamp
Pstart,Pstop = scalar external pressure at start/end of run (pressure units)
Pdamp = pressure damping parameter (time units)
{x} or {y} or {z} or {xy} or {yz} or {xz} values = Pstart Pstop Pdamp
Pstart,Pstop = external stress tensor component at start/end of run (pressure units)
Pdamp = stress damping parameter (time units)
{couple} = {none} or {xyz} or {xy} or {yz} or {xz}
{tchain} value = length of thermostat chain (1 = single thermostat)
{pchain} values = length of thermostat chain on barostat (0 = no thermostat)
{mtk} value = {yes} or {no} = add in MTK adjustment term or not
{tloop} value = number of sub-cycles to perform on thermostat
{ploop} value = number of sub-cycles to perform on barostat thermostat
{nreset} value = reset reference cell every this many timesteps
{drag} value = drag factor added to barostat/thermostat (0.0 = no drag)
{dilate} value = {all} or {partial}
{scaleyz} value = {yes} or {no} = scale yz with lz
{scalexz} value = {yes} or {no} = scale xz with lz
{scalexy} value = {yes} or {no} = scale xy with ly :pre
:ule
[Examples:]
fix 1 all nvt temp 300.0 300.0 100.0
fix 1 water npt temp 300.0 300.0 100.0 iso 0.0 0.0 1000.0
fix 2 jello npt temp 300.0 300.0 100.0 tri 5.0 5.0 1000.0
fix 2 ice nph x 1.0 1.0 0.5 y 2.0 2.0 0.5 z 3.0 3.0 0.5 yz 0.1 0.1 0.5 xz 0.2 0.2 0.5 xy 0.3 0.3 0.5 nreset 1000 :pre
[Description:]
These commands perform time integration on Nose-Hoover style
non-Hamiltonian equations of motion which are designed to generate
positions and velocities sampled from the canonical (nvt),
isothermal-isobaric (npt), and isenthalpic (nph) ensembles. This is
achieved by adding some dynamic variables which are coupled to the
particle velocities (thermostatting) and simulation domain dimensions
(barostatting). In addition to basic thermostatting and barostatting,
these fixes can also create a chain of thermostats coupled to the
particle thermostat, and another chain of thermostats coupled to the
barostat variables. The barostat can be coupled to the overall box
volume, or to individual dimensions, including the {xy}, {xz} and {yz}
tilt dimensions. The external pressure of the barostat can be
specified as either a scalar pressure (isobaric ensemble) or as
components of a symmetric stress tensor (constant stress ensemble).
When used correctly, the time-averaged temperature and stress tensor
of the particles will match the target values specified by
Tstart/Tstop and Pstart/Pstop.
The equations of motion used are those of Shinoda et al. in
"(Shinoda)"_#Shinoda, which combine the hydrostatic equations of
Martyna, Tobias and Klein in "(Martyna)"_#Martyna with the strain
energy proposed by Parrinello and Rahman in
"(Parrinello)"_#Parrinello. The time integration schemes closely
follow the time-reversible measure-preserving Verlet and
rRESPA integrators derived by Tuckerman et al. in "(Tuckerman)"_#Tuckerman.
:line
The thermostat for fix styles {nvt} and {npt} is specified using the
{temp} keyword. Other thermostat-related keywords are {tchain},
{tloop} and {drag}, which are discussed below.
The thermostat is applied to only the translational degrees of freedom
for the particles. The translational degrees of freedom can also have
a bias velocity removed before thermostatting takes place; see the
description below. The desired temperature at each timestep is a
ramped value during the run from {Tstart} to {Tstop}. The {Tdamp}
parameter is specified in time units and determines how rapidly the
temperature is relaxed. For example, a value of 10.0 means to relax
the temperature in a timespan of (roughly) 10 time units (e.g. tau or
fmsec or psec - see the "units"_units.html command). The atoms in the
fix group are the only ones whose velocities and positions are updated
by the velocity/position update portion of the integration.
IMPORTANT NOTE: A Nose-Hoover thermostat will not work well for
arbitrary values of {Tdamp}. If {Tdamp} is too small, the temperature
can fluctuate wildly; if it is too large, the temperature will take a
very long time to equilibrate. A good choice for many models is a
{Tdamp} of around 100 timesteps. Note that this is NOT the same as
100 time units for most "units"_units.html settings.
:line
The barostat for fix styles {npt} and {nph} is specified using one or
more of the {iso}, {aniso}, {tri}, {x}, {y}, {z}, {xy}, {xz}, {yz},
and {couple} keywords. These keywords give you the ability to specify
all 6 components of an external stress tensor, and to couple various
of these components together so that the dimensions they represent are
varied together during a constant-pressure simulation.
Other barostat-related keywords are {pchain}, {mtk}, {ploop},
{nreset}, {drag}, and {dilate}, which are discussed below.
Orthogonal simulation boxes have 3 adjustable dimensions (x,y,z).
Triclinic (non-orthogonal) simulation boxes have 6 adjustable
dimensions (x,y,z,xy,xz,yz). The "create_box"_create_box.html, "read
data"_read_data.html, and "read_restart"_read_restart.html commands
specify whether the simulation box is orthogonal or non-orthogonal
(triclinic) and explain the meaning of the xy,xz,yz tilt factors.
The target pressures for each of the 6 components of the stress tensor
can be specified independently via the {x}, {y}, {z}, {xy}, {xz}, {yz}
keywords, which correspond to the 6 simulation box dimensions. For
each component, the external pressure or tensor component at each
timestep is a ramped value during the run from {Pstart} to {Pstop}.
If a target pressure is specified for a component, then the
corresponding box dimension will change during a simulation. For
example, if the {y} keyword is used, the y-box length will change. If
the {xy} keyword is used, the xy tilt factor will change. A box
dimension will not change if that component is not specified, although
you have the option to change that dimension via the "fix
deform"_fix_deform.html command.
Note that in order to use the {xy}, {xz}, or {yz} keywords, the
simulation box must be triclinic, even if its initial tilt factors are
0.0.
For all barostat keywords, the {Pdamp} parameter operates like the
{Tdamp} parameter, determining the time scale on which pressure is
relaxed. For example, a value of 10.0 means to relax the pressure in
a timespan of (roughly) 10 time units (e.g. tau or fmsec or psec - see
the "units"_units.html command).
IMPORTANT NOTE: A Nose-Hoover barostat will not work well for
arbitrary values of {Pdamp}. If {Pdamp} is too small, the pressure
and volume can fluctuate wildly; if it is too large, the pressure will
take a very long time to equilibrate. A good choice for many models
is a {Pdamp} of around 1000 timesteps. Note that this is NOT the same
as 1000 time units for most "units"_units.html settings.
Regardless of what atoms are in the fix group, a global pressure or
stress tensor is computed for all atoms. Similarly, when the size of
the simulation box is changed, all atoms are re-scaled to new
positions, unless the keyword {dilate} is specified with a value of
{partial}, in which case only the atoms in the fix group are
re-scaled. The latter can be useful for leaving the coordinates of
atoms in a solid substrate unchanged and controlling the pressure of a
surrounding fluid.
:line
The {couple} keyword allows two or three of the diagonal components of
the pressure tensor to be "coupled" together. The value specified
with the keyword determines which are coupled. For example, {xz}
means the {Pxx} and {Pzz} components of the stress tensor are coupled.
{Xyz} means all 3 diagonal components are coupled. Coupling means two
things: the instantaneous stress will be computed as an average of the
corresponding diagonal components, and the coupled box dimensions will
be changed together in lockstep, meaning coupled dimensions will be
dilated or contracted by the same percentage every timestep. The
{Pstart}, {Pstop}, {Pdamp} parameters for any coupled dimensions must
be identical. {Couple xyz} can be used for a 2d simulation; the {z}
dimension is simply ignored.
:line
The {iso}, {aniso}, and {tri} keywords are simply shortcuts that are
equivalent to specifying several other keywords together.
The keyword {iso} means couple all 3 diagonal components together when
pressure is computed (hydrostatic pressure), and dilate/contract the
dimensions together. Using "iso Pstart Pstop Pdamp" is the same as
specifying these 4 keywords:
x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
couple xyz :pre
The keyword {aniso} means {x}, {y}, and {z} dimensions are controlled
independently using the {Pxx}, {Pyy}, and {Pzz} components of the
stress tensor as the driving forces, and the specified scalar external
pressure. Using "aniso Pstart Pstop Pdamp" is the same as specifying
these 4 keywords:
x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
couple none :pre
The keyword {tri} means {x}, {y}, {z}, {xy}, {xz}, and {yz} dimensions
are controlled independently using their individual stress components
as the driving forces, and the specified scalar pressure as the
external normal stress. Using "tri Pstart Pstop Pdamp" is the same as
specifying these 7 keywords:
x Pstart Pstop Pdamp
y Pstart Pstop Pdamp
z Pstart Pstop Pdamp
xy 0.0 0.0 Pdamp
yz 0.0 0.0 Pdamp
xz 0.0 0.0 Pdamp
couple none :pre
:line
In some cases (e.g. for solids) the pressure (volume) and/or
temperature of the system can oscillate undesirably when a Nose/Hoover
barostat and thermostat is applied. The optional {drag} keyword will
damp these oscillations, although it alters the Nose/Hoover equations.
A value of 0.0 (no drag) leaves the Nose/Hoover formalism unchanged.
A non-zero value adds a drag term; the larger the value specified, the
greater the damping effect. Performing a short run and monitoring the
pressure and temperature is the best way to determine if the drag term
is working. Typically a value between 0.2 to 2.0 is sufficient to
damp oscillations after a few periods. Note that use of the drag
keyword will interfere with energy conservation and will also change
the distribution of positions and velocities so that they do not
correspond to the nominal NVT, NPT, or NPH ensembles.
An alternative way to control initial oscillations is to use chain
thermostats. The keyword {tchain} determines the number of thermostats
in the particle thermostat. A value of 1 corresponds to the original
Nose-Hoover thermostat. The keyword {pchain} specifies the number of
thermostats in the chain thermostatting the barostat degrees of
freedom. A value of 0 corresponds to no thermostatting of the
barostat variables.
The {mtk} keyword controls whether or not the correction terms due to
Martyna, Tuckerman, and Klein are included in the equations of motion
"(Martyna)"_#Martyna. Specifying {no} reproduces the original
Hoover barostat, whose volume probability distribution function
differs from the true NPT and NPH ensembles by a factor of 1/V. Hence
using {yes} is more correct, but in many cases the difference is
negligible.
The keyword {tloop} can be used to improve the accuracy of integration
scheme at little extra cost. The initial and final updates of the
thermostat variables are broken up into {tloop} substeps, each of
length {dt}/{tloop}. This corresponds to using a first-order
Suzuki-Yoshida scheme "(Tuckerman2006)"_#Tuckerman2006. The keyword
{ploop} does the same thing for the barostat thermostat.
The keyword {nreset} controls how often the reference dimensions used
to define the strain energy are reset. If this keyword is not used,
or is given a value of zero, then the reference dimensions are set to
those of the initial simulation domain and are never changed. If the
simulation domain changes significantly during the simulation, then
the final average pressure tensor will differ significantly from the
specified values of the external stress tensor. A value of {nstep}
means that every {nstep} timesteps, the reference dimensions are set
to those of the current simulation domain.
The {scaleyz}, {scalexz}, and {scalexy} keywords control whether or
not the corresponding tilt factors are scaled with the
associated box dimensions
when barostatting triclinic periodic cells.
The default values {yes} will turn on scaling, which corresponds to
adjusting the linear dimensions of the cell while preserving its shape.
Choosing {no} ensures that the tilt factors are not scaled with the
box dimensions. See below for restrictions and default values in different
situations. In older versions of LAMMPS, scaling of tilt factors was not
performed. The old behavior can be recovered by setting all three
scale keywords to {no}.
:line
IMPORTANT NOTE: Using a barostat coupled to tilt dimensions {xy},
{xz}, {yz} can sometimes result in arbitrarily large values of the
tilt dimensions, i.e. a dramatically deformed simulation box. LAMMPS
allows the tilt factors to grow a little beyond the normal limit
of half the box length (0.6 times the box length), and then performs
flipping or re-shaping to an equivalent periodic cell. The re-shaping
operation is described in more detail in the doc page for
"fix deform"_fix_deform.html. Both the barostat dynamics and
the atom trajectories are unaffected by this operation. However,
if a tilt factor is incremented by a large amount (1.5 times the
box length) on a single timestep, LAMMPS can not accomodate
this event and will terminate the simulation
with an error. This error typically
indicates that there is something badly wrong with how the simulation
was constructed, such as specifying values of {Pstart} that are
too far from the current stress value, or specifying a timestep that
is too large. Triclinic barostatting should be used with
care. This also is true for other barostat styles, although they tend
to be more forgiving of insults. In particular, it is important to
recognize that equilibrium liquids can not support a shear stress and
that equilibrium solids can not support shear stresses that exceed the yield stress.
IMPORTANT NOTE: Unlike the "fix
temp/berendsen"_fix_temp_berendsen.html command which performs
thermostatting but NO time integration, these fixes perform
thermostatting/barostatting AND time integration. Thus you should not
use any other time integration fix, such as "fix nve"_fix_nve.html on
atoms to which this fix is applied. Likewise, the {temp} options for
fix nvt and fix npt should not normally be used on atoms that also
have their temperature controlled by another fix - e.g. by "fix
langevin"_fix_nh.html or "fix temp/rescale"_fix_temp_rescale.html
commands.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting and barostatting.
:line
These fixes compute a temperature and pressure each timestep. To do
this, the fix creates its own computes of style "temp" and "pressure",
as if one of these two sets of commands had been issued:
compute fix-ID_temp group-ID temp
compute fix-ID_press group-ID pressure fix-ID_temp :pre
compute fix-ID_temp all temp
compute fix-ID_press all pressure fix-ID_temp :pre
See the "compute temp"_compute_temp.html and "compute
pressure"_compute_pressure.html commands for details. Note that the
IDs of the new computes are the fix-ID + underscore + "temp" or fix_ID
+ underscore + "press". For fix nvt, the group for the new computes
is the same as the fix group. For fix nph and fix npt, the group for
the new computes is "all" since pressure is computed for the entire
system.
Note that these are NOT the computes used by thermodynamic output (see
the "thermo_style"_thermo_style.html command) with ID = {thermo_temp}
and {thermo_press}. This means you can change the attributes of this
fix's temperature or pressure via the
"compute_modify"_compute_modify.html command or print this temperature
or pressure during thermodynamic output via the "thermo_style
custom"_thermo_style.html command using the appropriate compute-ID.
It also means that changing attributes of {thermo_temp} or
{thermo_press} will have no effect on this fix.
Like other fixes that perform thermostatting, fix nvt and fix npt can
be used with "compute commands"_compute.html that calculate a
temperature after removing a "bias" from the atom velocities.
E.g. removing the center-of-mass velocity from a group of atoms or
only calculating temperature on the x-component of velocity or only
calculating temperature for atoms in a geometric region. This is not
done by default, but only if the "fix_modify"_fix_modify.html command
is used to assign a temperature compute to this fix that includes such
a bias term. See the doc pages for individual "compute
commands"_compute.html to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
These fixes writes the state of all the thermostat and barostat
variables to "binary restart files"_restart.html. See the
"read_restart"_read_restart.html command for info on how to re-specify
a fix in an input script that reads a restart file, so that the
operation of the fix continues in an uninterrupted fashion.
The "fix_modify"_fix_modify.html {temp} and {press} options are
supported by these fixes. You can use them to assign a
"compute"_compute.html you have defined to this fix which will be used
in its thermostatting or barostatting procedure, as described above.
If you do this, note that the kinetic energy derived from the compute
temperature should be consistent with the virial term computed using
all atoms for the pressure. LAMMPS will warn you if you choose to
compute temperature on a subset of atoms.
IMPORTANT NOTE: If both the {temp} and {press} keywords are used in a
single thermo_modify command (or in two separate commands), then the
order in which the keywords are specified is important. Note that a
"pressure compute"_compute_pressure.html defines its own temperature
compute as an argument when it is specified. The {temp} keyword will
override this (for the pressure compute being used by fix npt), but
only if the {temp} keyword comes after the {press} keyword. If the
{temp} keyword comes before the {press} keyword, then the new pressure
compute specified by the {press} keyword will be unaffected by the
{temp} setting.
The "fix_modify"_fix_modify.html {energy} option is supported by these
fixes to add the energy change induced by Nose/Hoover thermostatting
and barostatting to the system's potential energy as part of
"thermodynamic output"_thermo_style.html.
These fixes compute a global scalar and a global vector of quantities,
which can be accessed by various "output
commands"_Section_howto.html#howto_15. The scalar value calculated by
these fixes is "extensive"; the vector values are "intensive".
The scalar is the cumulative energy change due to the fix.
The vector stores internal Nose/Hoover thermostat and barostat
variables. The number and meaning of the vector values depends on
which fix is used and the settings for keywords {tchain} and {pchain},
which specify the number of Nose/Hoover chains for the thermostat and
barostat. If no thermostatting is done, then {tchain} is 0. If no
barostatting is done, then {pchain} is 0. In the following list,
"ndof" is 0, 1, 3, or 6, and is the number of degrees of freedom in
the barostat. Its value is 0 if no barostat is used, else its value
is 6 if any off-diagonal stress tensor component is barostatted, else
its value is 1 if {couple xyz} is used or {couple xy} for a 2d
simulation, otherwise its value is 3.
The order of values in the global vector and their meaning is as
follows. The notation means there are tchain values for eta, followed
by tchain for eta_dot, followed by ndof for omega, etc:
eta\[tchain\] = particle thermostat displacements (unitless)
eta_dot\[tchain\] = particle thermostat velocities (1/time units)
omega\[ndof\] = barostat displacements (unitless)
omega_dot\[ndof\] = barostat velocities (1/time units)
etap\[pchain\] = barostat thermostat displacements (unitless)
etap_dot\[pchain\] = barostat thermostat velocities (1/time units)
PE_eta\[tchain\] = potential energy of each particle thermostat displacement (energy units)
KE_eta_dot\[tchain\] = kinetic energy of each particle thermostat velocity (energy units)
PE_omega\[ndof\] = potential energy of each barostat displacement (energy units)
KE_omega_dot\[ndof\] = kinetic energy of each barostat velocity (energy units)
PE_etap\[pchain\] = potential energy of each barostat thermostat displacement (energy units)
KE_etap_dot\[pchain\] = kinetic energy of each barostat thermostat velocity (energy units)
PE_strain\[1\] = scalar strain energy (energy units) :ul
These fixes can ramp their external temperature and pressure over
multiple runs, using the {start} and {stop} keywords of the
"run"_run.html command. See the "run"_run.html command for details of
how to do this.
These fixes are not invoked during "energy
minimization"_minimize.html.
These fixes can be used with either the {verlet} or {respa}
"integrators"_run_style.html. When using one of the barostat fixes
with {respa}, LAMMPS uses an integrator constructed
according to the following factorization of the Liouville propagator
(for two rRESPA levels):
:c,image(Eqs/fix_nh1.jpg)
This factorization differs somewhat from that of Tuckerman et al., in that
the barostat is only updated at the outermost rRESPA level, whereas
Tuckerman's factorization requires splitting the pressure into pieces
corresponding to the forces computed at each rRESPA level. In theory, the
latter method will exhibit better numerical stability. In practice,
because Pdamp is normally chosen to be a large multiple of the
outermost rRESPA timestep, the barostat dynamics are not the
limiting factor for numerical stability. Both
factorizations are time-reversible and can be shown to preserve the phase
space measure of the underlying non-Hamiltonian equations of motion.
[Restrictions:]
Non-periodic dimensions cannot be barostatted. {Z}, {xz}, and {yz},
cannot be barostatted 2D simulations. {Xy}, {xz}, and {yz} can only
be barostatted if the simulation domain is triclinic and the 2nd
dimension in the keyword ({y} dimension in {xy}) is periodic. The
"create_box"_create_box.html, "read data"_read_data.html, and
"read_restart"_read_restart.html commands specify whether the
simulation box is orthogonal or non-orthogonal (triclinic) and explain
the meaning of the xy,xz,yz tilt factors.
For the {temp} keyword, the final Tstop cannot be 0.0 since it would
make the external T = 0.0 at some timestep during the simulation which
is not allowed in the Nose/Hoover formulation.
The {scaleyz yes} and {scalexz yes} keyword/value pairs can not be used
for 2D simulations. {scaleyz yes}, {scalexz yes}, and {scalexy yes} options
can only be used if the 2nd dimension in the keyword is periodic,
and if the tilt factor is not coupled to the barostat via keywords
{tri}, {yz}, {xz}, and {xy}.
[Related commands:]
"fix nve"_fix_nve.html, "fix_modify"_fix_modify.html, "run_style"_run_style.html
[Default:]
The keyword defaults are tchain = 3, pchain = 3, mtk = yes, tloop =
ploop = 1, nreset = 0, drag = 0.0, dilate = all, couple = none,
scaleyz = scalexz = scalexy = yes if periodic in 2nd dimension and
not coupled to barostat, otherwise no.
:line
:link(Martyna)
[(Martyna)] Martyna, Tobias and Klein, J Chem Phys, 101, 4177 (1994).
:link(Parrinello)
[(Parrinello)] Parrinello and Rahman, J Appl Phys, 52, 7182 (1981).
:link(Tuckerman)
[(Tuckerman)] Tuckerman, Alejandre, Lopez-Rendon, Jochim, and
Martyna, J Phys A: Math Gen, 39, 5629 (2006).
:link(Shinoda)
[(Shinoda)] Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004).
diff --git a/doc/fix_nve.html b/doc/fix_nve.html
index e08b86dcd..2a544abd0 100644
--- a/doc/fix_nve.html
+++ b/doc/fix_nve.html
@@ -1,75 +1,75 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix nve command
</H3>
<H3>fix nve/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID nve
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>nve = style name of this fix command
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all nve
</PRE>
<P><B>Description:</B>
</P>
<P>Perform constant NVE integration to update position and velocity for
atoms in the group each timestep. V is volume; E is energy. This
creates a system trajectory consistent with the microcanonical
ensemble.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "fix_nh.html">fix npt</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_nve.txt b/doc/fix_nve.txt
index fbc23c25e..3558efda0 100644
--- a/doc/fix_nve.txt
+++ b/doc/fix_nve.txt
@@ -1,69 +1,69 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix nve command :h3
fix nve/cuda command :h3
[Syntax:]
fix ID group-ID nve :pre
ID, group-ID are documented in "fix"_fix.html command
nve = style name of this fix command :ul
[Examples:]
fix 1 all nve :pre
[Description:]
Perform constant NVE integration to update position and velocity for
atoms in the group each timestep. V is volume; E is energy. This
creates a system trajectory consistent with the microcanonical
ensemble.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:] none
[Related commands:]
"fix nvt"_fix_nh.html, "fix npt"_fix_nh.html
[Default:] none
diff --git a/doc/fix_nve_sphere.html b/doc/fix_nve_sphere.html
index f2f5678cd..2702bcbfb 100644
--- a/doc/fix_nve_sphere.html
+++ b/doc/fix_nve_sphere.html
@@ -1,105 +1,105 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix nve/sphere command
</H3>
<H3>fix nve/sphere/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID nve/sphere
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>nve/sphere = style name of this fix command
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>update</I>
<PRE> <I>update</I> value = <I>dipole</I>
dipole = update orientation of dipole moment during integration
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all nve/sphere
fix 1 all nve/sphere update dipole
</PRE>
<P><B>Description:</B>
</P>
<P>Perform constant NVE integration to update position, velocity, and
angular velocity for extended spherical particles in the group each
timestep. V is volume; E is energy. This creates a system trajectory
consistent with the microcanonical ensemble.
</P>
<P>This fix differs from the <A HREF = "fix_nve.html">fix nve</A> command, which
assumes point particles and only updates their position and velocity.
</P>
<P>If the <I>update</I> keyword is used with the <I>dipole</I> value, then the
orientation of the dipole moment of each particle is also updated
during the time integration. This option should be used for models
where a dipole moment is assigned to particles via use of the
<A HREF = "atom_style.html">atom_style dipole</A> command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix requires that atoms store torque and angular velocity (omega)
and a radius as defined by the <A HREF = "atom_style.html">atom_style sphere</A>
command. If the <I>dipole</I> keyword is used, then they must also store a
dipole moment as defined by the <A HREF = "atom_style.html">atom_style dipole</A>
command.
</P>
<P>All particles in the group must be finite-size spheres. They cannot
be point particles.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_nve.html">fix nve</A>, <A HREF = "fix_nve_asphere.html">fix nve/asphere</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_nve_sphere.txt b/doc/fix_nve_sphere.txt
index 3c5864d3f..ebaeabd40 100755
--- a/doc/fix_nve_sphere.txt
+++ b/doc/fix_nve_sphere.txt
@@ -1,94 +1,94 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix nve/sphere command :h3
fix nve/sphere/omp command :h3
[Syntax:]
fix ID group-ID nve/sphere :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
nve/sphere = style name of this fix command :l
zero or more keyword/value pairs may be appended :l
keyword = {update} :l
{update} value = {dipole}
dipole = update orientation of dipole moment during integration :pre
:ule
[Examples:]
fix 1 all nve/sphere
fix 1 all nve/sphere update dipole :pre
[Description:]
Perform constant NVE integration to update position, velocity, and
angular velocity for extended spherical particles in the group each
timestep. V is volume; E is energy. This creates a system trajectory
consistent with the microcanonical ensemble.
This fix differs from the "fix nve"_fix_nve.html command, which
assumes point particles and only updates their position and velocity.
If the {update} keyword is used with the {dipole} value, then the
orientation of the dipole moment of each particle is also updated
during the time integration. This option should be used for models
where a dipole moment is assigned to particles via use of the
"atom_style dipole"_atom_style.html command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
This fix requires that atoms store torque and angular velocity (omega)
and a radius as defined by the "atom_style sphere"_atom_style.html
command. If the {dipole} keyword is used, then they must also store a
dipole moment as defined by the "atom_style dipole"_atom_style.html
command.
All particles in the group must be finite-size spheres. They cannot
be point particles.
[Related commands:]
"fix nve"_fix_nve.html, "fix nve/asphere"_fix_nve_asphere.html
[Default:] none
diff --git a/doc/fix_qeq_comb.html b/doc/fix_qeq_comb.html
index c66b49dc4..984b6bd68 100644
--- a/doc/fix_qeq_comb.html
+++ b/doc/fix_qeq_comb.html
@@ -1,143 +1,143 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix qeq/comb command
</H3>
<H3>fix qeq/comb/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID qeq/comb Nevery precision keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>qeq/comb = style name of this fix command
<LI>Nevery = perform charge equilibration every this many steps
<LI>precision = convergence criterion for charge equilibration
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>file</I>
<PRE> <I>file</I> value = filename
filename = name of file to write QEQ equilibration info to
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 surface qeq/comb 10 0.0001
</PRE>
<P><B>Description:</B>
</P>
<P>Perform charge equilibration (QeQ) in conjunction with the COMB
(Charge-Optimized Many-Body) potential as described in
<A HREF = "#COMB_1">(COMB_1)</A> and <A HREF = "#COMB_2">(COMB_2)</A>. It performs the charge
equilibration portion of the calculation using the so-called QEq
method, whereby the charge on each atom is adjusted to minimize the
energy of the system. This fix can only be used with the COMB
potential; see the <A HREF = "fix_qeq_reqx.html">fix qeq/reax</A> command for a QeQ
calculation that can be used with any potential.
</P>
<P>Only charges on the atoms in the specified group are equilibrated.
The fix relies on the pair style (COMB in this case) to calculate the
per-atom electronegativity (effective force on the charges). An
electronegativity equalization calculation (or QEq) is performed in an
interative fashion, which in parallel requires communication at each
iteration for processors to exchange charge information about nearby
atoms with each other. See <A HREF = "#Rappe_and_Goddard">Rappe_and_Goddard</A> and
<A HREF = "#Rick_and_Stuart">Rick_and_Stuart</A> for details.
</P>
<P>During a run, charge equilibration is peformed every <I>Nevery</I> time
steps. Charge equilibration is also always enforced on the first step
of each run. The <I>precision</I> argument controls the tolerance for the
difference in electronegativity for all atoms during charge
equilibration. <I>Precision</I> is a trade-off between the cost of
performing charge equilibration (more iterations) and accuracy.
</P>
<P>If the <I>file</I> keyword is used, then information about each
equilibration calculation is written to the specifed file.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
<P>This fix produces a per-atom vector which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. The vector stores the
gradient of the charge on each atom. The per-atom values be accessed
on any timestep.
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command. This fix is not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix command currently only supports <A HREF = "pair_comb.html">pair style <I>comb</I></A>.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_comb.html">pair_style comb</A>
</P>
<P><B>Default:</B>
</P>
<P>No file output is performed.
</P>
<HR>
<A NAME = "COMB_1"></A>
<P><B>(COMB_1)</B> J. Yu, S. B. Sinnott, S. R. Phillpot, Phys Rev B, 75, 085311 (2007),
</P>
<A NAME = "COMB_2"></A>
<P><B>(COMB_2)</B> T.-R. Shan, B. D. Devine, T. W. Kemper, S. B. Sinnott, S. R.
Phillpot, Phys Rev B, 81, 125328 (2010).
</P>
<A NAME = "Rappe_and_Goddard"></A>
<P><B>(Rappe_and_Goddard)</B> A. K. Rappe, W. A. Goddard, J Phys Chem 95, 3358
(1991).
</P>
<A NAME = "Rick_and_Stuart"></A>
<P><B>(Rick_and_Stuart)</B> S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys
101, 16141 (1994).
</P>
</HTML>
diff --git a/doc/fix_qeq_comb.txt b/doc/fix_qeq_comb.txt
index 3fbb9dc7b..5cce65180 100644
--- a/doc/fix_qeq_comb.txt
+++ b/doc/fix_qeq_comb.txt
@@ -1,126 +1,126 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix qeq/comb command :h3
fix qeq/comb/omp command :h3
[Syntax:]
fix ID group-ID qeq/comb Nevery precision keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
qeq/comb = style name of this fix command :l
Nevery = perform charge equilibration every this many steps :l
precision = convergence criterion for charge equilibration :l
zero or more keyword/value pairs may be appended :l
keyword = {file} :l
{file} value = filename
filename = name of file to write QEQ equilibration info to :pre
:ule
[Examples:]
fix 1 surface qeq/comb 10 0.0001 :pre
[Description:]
Perform charge equilibration (QeQ) in conjunction with the COMB
(Charge-Optimized Many-Body) potential as described in
"(COMB_1)"_#COMB_1 and "(COMB_2)"_#COMB_2. It performs the charge
equilibration portion of the calculation using the so-called QEq
method, whereby the charge on each atom is adjusted to minimize the
energy of the system. This fix can only be used with the COMB
potential; see the "fix qeq/reax"_fix_qeq_reqx.html command for a QeQ
calculation that can be used with any potential.
Only charges on the atoms in the specified group are equilibrated.
The fix relies on the pair style (COMB in this case) to calculate the
per-atom electronegativity (effective force on the charges). An
electronegativity equalization calculation (or QEq) is performed in an
interative fashion, which in parallel requires communication at each
iteration for processors to exchange charge information about nearby
atoms with each other. See "Rappe_and_Goddard"_#Rappe_and_Goddard and
"Rick_and_Stuart"_#Rick_and_Stuart for details.
During a run, charge equilibration is peformed every {Nevery} time
steps. Charge equilibration is also always enforced on the first step
of each run. The {precision} argument controls the tolerance for the
difference in electronegativity for all atoms during charge
equilibration. {Precision} is a trade-off between the cost of
performing charge equilibration (more iterations) and accuracy.
If the {file} keyword is used, then information about each
equilibration calculation is written to the specifed file.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
This fix produces a per-atom vector which can be accessed by various
"output commands"_Section_howto.html#howto_15. The vector stores the
gradient of the charge on each atom. The per-atom values be accessed
on any timestep.
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
This fix command currently only supports "pair style {comb}"_pair_comb.html.
[Related commands:]
"pair_style comb"_pair_comb.html
[Default:]
No file output is performed.
:line
:link(COMB_1)
[(COMB_1)] J. Yu, S. B. Sinnott, S. R. Phillpot, Phys Rev B, 75, 085311 (2007),
:link(COMB_2)
[(COMB_2)] T.-R. Shan, B. D. Devine, T. W. Kemper, S. B. Sinnott, S. R.
Phillpot, Phys Rev B, 81, 125328 (2010).
:link(Rappe_and_Goddard)
[(Rappe_and_Goddard)] A. K. Rappe, W. A. Goddard, J Phys Chem 95, 3358
(1991).
:link(Rick_and_Stuart)
[(Rick_and_Stuart)] S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys
101, 16141 (1994).
diff --git a/doc/fix_setforce.html b/doc/fix_setforce.html
index 6e713254d..2ac1db341 100644
--- a/doc/fix_setforce.html
+++ b/doc/fix_setforce.html
@@ -1,129 +1,129 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix setforce command
</H3>
<H3>fix setforce/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID setforce fx fy fz keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>setforce = style name of this fix command
<LI>fx,fy,fz = force component values
<LI>any of fx,fy,fz can be a variable (see below)
<LI>zero or more keyword/value pairs may be appended to args
<LI>keyword = <I>region</I>
<PRE> <I>region</I> value = region-ID
region-ID = ID of region atoms must be in to have added force
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix freeze indenter setforce 0.0 0.0 0.0
fix 2 edge setforce NULL 0.0 0.0
fix 2 edge setforce NULL 0.0 v_oscillate
</PRE>
<P><B>Description:</B>
</P>
<P>Set each component of force on each atom in the group to the specified
values fx,fy,fz. This erases all previously computed forces on the
atom, though additional fixes could add new forces. This command can
be used to freeze certain atoms in the simulation by zeroing their
force, either for running dynamics or performing an energy
minimization. For dynamics, this assumes their initial velocity is
also zero.
</P>
<P>Any of the fx,fy,fz values can be specified as NULL which means do not
alter the force component in that dimension.
</P>
<P>Any of the 3 quantities defining the force components can be specified
as an equal-style or atom-style <A HREF = "variable.html">variable</A>, namely <I>fx</I>,
<I>fy</I>, <I>fz</I>. If the value is a variable, it should be specified as
v_name, where name is the variable name. In this case, the variable
will be evaluated each timestep, and its value used to determine the
force component.
</P>
<P>Equal-style variables can specify formulas with various mathematical
functions, and include <A HREF = "thermo_style.html">thermo_style</A> command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent force field.
</P>
<P>Atom-style variables can specify the same formulas as equal-style
variables but can also include per-atom values, such as atom
coordinates. Thus it is easy to specify a spatially-dependent force
field with optional time-dependence as well.
</P>
<P>If the <I>region</I> keyword is used, the atom must also be in the
specified geometric <A HREF = "region.html">region</A> in order to have force added
to it.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
<P>This fix computes a global 3-vector of forces, which can be accessed
by various <A HREF = "Section_howto.html#howto_15">output commands</A>. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
invoked by the <A HREF = "minimize.html">minimize</A> command, but you cannot set
forces to any value besides zero when performing a minimization. Use
the <A HREF = "fix_addforce.html">fix addforce</A> command if you want to apply a
non-zero force to atoms during a minimization.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_addforce.html">fix addforce</A>, <A HREF = "fix_aveforce.html">fix aveforce</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_setforce.txt b/doc/fix_setforce.txt
index 90404f032..c215e3ed2 100644
--- a/doc/fix_setforce.txt
+++ b/doc/fix_setforce.txt
@@ -1,116 +1,116 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix setforce command :h3
fix setforce/cuda command :h3
[Syntax:]
fix ID group-ID setforce fx fy fz keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
setforce = style name of this fix command :l
fx,fy,fz = force component values :l
any of fx,fy,fz can be a variable (see below) :l
zero or more keyword/value pairs may be appended to args :l
keyword = {region} :l
{region} value = region-ID
region-ID = ID of region atoms must be in to have added force :pre
:ule
[Examples:]
fix freeze indenter setforce 0.0 0.0 0.0
fix 2 edge setforce NULL 0.0 0.0
fix 2 edge setforce NULL 0.0 v_oscillate :pre
[Description:]
Set each component of force on each atom in the group to the specified
values fx,fy,fz. This erases all previously computed forces on the
atom, though additional fixes could add new forces. This command can
be used to freeze certain atoms in the simulation by zeroing their
force, either for running dynamics or performing an energy
minimization. For dynamics, this assumes their initial velocity is
also zero.
Any of the fx,fy,fz values can be specified as NULL which means do not
alter the force component in that dimension.
Any of the 3 quantities defining the force components can be specified
as an equal-style or atom-style "variable"_variable.html, namely {fx},
{fy}, {fz}. If the value is a variable, it should be specified as
v_name, where name is the variable name. In this case, the variable
will be evaluated each timestep, and its value used to determine the
force component.
Equal-style variables can specify formulas with various mathematical
functions, and include "thermo_style"_thermo_style.html command
keywords for the simulation box parameters and timestep and elapsed
time. Thus it is easy to specify a time-dependent force field.
Atom-style variables can specify the same formulas as equal-style
variables but can also include per-atom values, such as atom
coordinates. Thus it is easy to specify a spatially-dependent force
field with optional time-dependence as well.
If the {region} keyword is used, the atom must also be in the
specified geometric "region"_region.html in order to have force added
to it.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
This fix computes a global 3-vector of forces, which can be accessed
by various "output commands"_Section_howto.html#howto_15. This is the
total force on the group of atoms before the forces on individual
atoms are changed by the fix. The vector values calculated by this
fix are "extensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
invoked by the "minimize"_minimize.html command, but you cannot set
forces to any value besides zero when performing a minimization. Use
the "fix addforce"_fix_addforce.html command if you want to apply a
non-zero force to atoms during a minimization.
[Restrictions:] none
[Related commands:]
"fix addforce"_fix_addforce.html, "fix aveforce"_fix_aveforce.html
[Default:] none
diff --git a/doc/fix_shake.html b/doc/fix_shake.html
index a5aad277a..1834d16bd 100644
--- a/doc/fix_shake.html
+++ b/doc/fix_shake.html
@@ -1,139 +1,139 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix shake command
</H3>
<H3>fix shake/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID shake tol iter N keyword values ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>shake = style name of this fix command
<LI>tol = accuracy tolerance of SHAKE solution
<LI>iter = max # of iterations in each SHAKE solution
<LI>N = print SHAKE statistics every this many timesteps (0 = never)
<LI>one or more keyword/value pairs are appended
<LI>keyword = <I>b</I> or <I>a</I> or <I>t</I> or <I>m</I>
<PRE> <I>b</I> values = one or more bond types
<I>a</I> values = one or more angle types
<I>t</I> values = one or more atom types
<I>m</I> value = one or more mass values
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 sub shake 0.0001 20 10 b 4 19 a 3 5 2
fix 1 sub shake 0.0001 20 10 t 5 6 m 1.0 a 31
</PRE>
<P><B>Description:</B>
</P>
<P>Apply bond and angle constraints to specified bonds and angles in the
simulation. This typically enables a longer timestep.
</P>
<P>Each timestep the specified bonds and angles are reset to their
equilibrium lengths and angular values via the well-known SHAKE
algorithm. This is done by applying an additional constraint force so
that the new positions preserve the desired atom separations. The
equations for the additional force are solved via an iterative method
that typically converges to an accurate solution in a few iterations.
The desired tolerance (e.g. 1.0e-4 = 1 part in 10000) and maximum # of
iterations are specified as arguments. Setting the N argument will
print statistics to the screen and log file about regarding the
lengths of bonds and angles that are being constrained. Small delta
values mean SHAKE is doing a good job.
</P>
<P>In LAMMPS, only small clusters of atoms can be constrained. This is
so the constraint calculation for a cluster can be performed by a
single processor, to enable good parallel performance. A cluster is
defined as a central atom connected to others in the cluster by
constrained bonds. LAMMPS allows for the following kinds of clusters
to be constrained: one central atom bonded to 1 or 2 or 3 atoms, or
one central atom bonded to 2 others and the angle between the 3 atoms
also constrained. This means water molecules or CH2 or CH3 groups may
be constrained, but not all the C-C backbone bonds of a long polymer
chain.
</P>
<P>The <I>b</I> keyword lists bond types that will be constrained. The <I>t</I>
keyword lists atom types. All bonds connected to an atom of the
specified type will be constrained. The <I>m</I> keyword lists atom
masses. All bonds connected to atoms of the specified masses will be
constrained (within a fudge factor of MASSDELTA specified in
fix_shake.cpp). The <I>a</I> keyword lists angle types. If both bonds in
the angle are constrained then the angle will also be constrained if
its type is in the list.
</P>
<P>For all keywords, a particular bond is only constrained if both atoms
in the bond are in the group specified with the SHAKE fix.
</P>
<P>The degrees-of-freedom removed by SHAKE bonds and angles are accounted
for in temperature and pressure computations. Similarly, the SHAKE
contribution to the pressure of the system (virial) is also accounted
for.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>For computational efficiency, there can only be one shake fix defined
in a simulation.
</P>
<P>If you use a tolerance that is too large or a max-iteration count that
is too small, the constraints will not be enforced very strongly,
which can lead to poor energy conservation. You can test for this in
your system by running a constant NVE simulation with a particular set
of SHAKE parameters and monitoring the energy versus time.
</P>
<P><B>Related commands:</B> none
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_shake.txt b/doc/fix_shake.txt
index dee3239bd..ed0eb85fd 100644
--- a/doc/fix_shake.txt
+++ b/doc/fix_shake.txt
@@ -1,125 +1,125 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix shake command :h3
fix shake/cuda command :h3
[Syntax:]
fix ID group-ID shake tol iter N keyword values ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
shake = style name of this fix command :l
tol = accuracy tolerance of SHAKE solution :l
iter = max # of iterations in each SHAKE solution :l
N = print SHAKE statistics every this many timesteps (0 = never) :l
one or more keyword/value pairs are appended :l
keyword = {b} or {a} or {t} or {m} :l
{b} values = one or more bond types
{a} values = one or more angle types
{t} values = one or more atom types
{m} value = one or more mass values :pre
:ule
[Examples:]
fix 1 sub shake 0.0001 20 10 b 4 19 a 3 5 2
fix 1 sub shake 0.0001 20 10 t 5 6 m 1.0 a 31 :pre
[Description:]
Apply bond and angle constraints to specified bonds and angles in the
simulation. This typically enables a longer timestep.
Each timestep the specified bonds and angles are reset to their
equilibrium lengths and angular values via the well-known SHAKE
algorithm. This is done by applying an additional constraint force so
that the new positions preserve the desired atom separations. The
equations for the additional force are solved via an iterative method
that typically converges to an accurate solution in a few iterations.
The desired tolerance (e.g. 1.0e-4 = 1 part in 10000) and maximum # of
iterations are specified as arguments. Setting the N argument will
print statistics to the screen and log file about regarding the
lengths of bonds and angles that are being constrained. Small delta
values mean SHAKE is doing a good job.
In LAMMPS, only small clusters of atoms can be constrained. This is
so the constraint calculation for a cluster can be performed by a
single processor, to enable good parallel performance. A cluster is
defined as a central atom connected to others in the cluster by
constrained bonds. LAMMPS allows for the following kinds of clusters
to be constrained: one central atom bonded to 1 or 2 or 3 atoms, or
one central atom bonded to 2 others and the angle between the 3 atoms
also constrained. This means water molecules or CH2 or CH3 groups may
be constrained, but not all the C-C backbone bonds of a long polymer
chain.
The {b} keyword lists bond types that will be constrained. The {t}
keyword lists atom types. All bonds connected to an atom of the
specified type will be constrained. The {m} keyword lists atom
masses. All bonds connected to atoms of the specified masses will be
constrained (within a fudge factor of MASSDELTA specified in
fix_shake.cpp). The {a} keyword lists angle types. If both bonds in
the angle are constrained then the angle will also be constrained if
its type is in the list.
For all keywords, a particular bond is only constrained if both atoms
in the bond are in the group specified with the SHAKE fix.
The degrees-of-freedom removed by SHAKE bonds and angles are accounted
for in temperature and pressure computations. Similarly, the SHAKE
contribution to the pressure of the system (virial) is also accounted
for.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
For computational efficiency, there can only be one shake fix defined
in a simulation.
If you use a tolerance that is too large or a max-iteration count that
is too small, the constraints will not be enforced very strongly,
which can lead to poor energy conservation. You can test for this in
your system by running a constant NVE simulation with a particular set
of SHAKE parameters and monitoring the energy versus time.
[Related commands:] none
[Default:] none
diff --git a/doc/fix_temp_berendsen.html b/doc/fix_temp_berendsen.html
index 0762f66ee..494311d17 100644
--- a/doc/fix_temp_berendsen.html
+++ b/doc/fix_temp_berendsen.html
@@ -1,166 +1,166 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix temp/berendsen command
</H3>
<H3>fix temp/berendsen/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID temp/berendsen Tstart Tstop Tdamp
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>temp/berendsen = style name of this fix command
<LI>Tstart,Tstop = desired temperature at start/end of run
<LI>Tdamp = temperature damping parameter (time units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all temp/berendsen 300.0 300.0 100.0
</PRE>
<P><B>Description:</B>
</P>
<P>Reset the temperature of a group of atoms by using a Berendsen
thermostat <A HREF = "#Berendsen">(Berendsen)</A>, which rescales their velocities
every timestep.
</P>
<P>The thermostat is applied to only the translational degrees of freedom
for the particles, which is an important consideration if extended
spherical or aspherical particles which have rotational degrees of
freedom are being thermostatted with this fix. The translational
degrees of freedom can also have a bias velocity removed from them
before thermostatting takes place; see the description below.
</P>
<P>The desired temperature at each timestep is a ramped value during the
run from <I>Tstart</I> to <I>Tstop</I>. The <I>Tdamp</I> parameter is specified in
time units and determines how rapidly the temperature is relaxed. For
example, a value of 100.0 means to relax the temperature in a timespan
of (roughly) 100 time units (tau or fmsec or psec - see the
<A HREF = "units.html">units</A> command).
</P>
<P>IMPORTANT NOTE: Unlike the <A HREF = "fix_nh.html">fix nvt</A> command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies velocities to
effect thermostatting. Thus you must use a separate time integration
fix, like <A HREF = "fix_nve.html">fix nve</A> to actually update the positions of
atoms using the modified velocities. Likewise, this fix should not
normally be used on atoms that also have their temperature controlled
by another fix - e.g. by <A HREF = "fix_nh.html">fix nvt</A> or <A HREF = "fix_langevin.html">fix
langevin</A> commands.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
</P>
<P>This fix computes a temperature each timestep. To do this, the fix
creates its own compute of style "temp", as if this command had been
issued:
</P>
<PRE>compute fix-ID_temp group-ID temp
</PRE>
<P>See the <A HREF = "compute_temp.html">compute temp</A> command for details. Note
that the ID of the new compute is the fix-ID + underscore + "temp",
and the group for the new compute is the same as the fix group.
</P>
<P>Note that this is NOT the compute used by thermodynamic output (see
the <A HREF = "thermo_style.html">thermo_style</A> command) with ID = <I>thermo_temp</I>.
This means you can change the attributes of this fix's temperature
(e.g. its degrees-of-freedom) via the
<A HREF = "compute_modify.html">compute_modify</A> command or print this temperature
during thermodynamic output via the <A HREF = "thermo_style.html">thermo_style
custom</A> command using the appropriate compute-ID.
It also means that changing attributes of <I>thermo_temp</I> will have no
effect on this fix.
</P>
<P>Like other fixes that perform thermostatting, this fix can be used
with <A HREF = "compute.html">compute commands</A> that calculate a temperature
after removing a "bias" from the atom velocities. E.g. removing the
center-of-mass velocity from a group of atoms or only calculating
temperature on the x-component of velocity or only calculating
temperature for atoms in a geometric region. This is not done by
default, but only if the <A HREF = "fix_modify.html">fix_modify</A> command is used
to assign a temperature compute to this fix that includes such a bias
term. See the doc pages for individual <A HREF = "compute.html">compute
commands</A> to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>temp</I> option is supported by this
fix. You can use it to assign a temperature <A HREF = "compute.html">compute</A>
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by this
fix to add the energy change implied by a velocity rescaling to the
system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>.
</P>
<P>This fix computes a global scalar which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive".
</P>
<P>This fix can ramp its target temperature over multiple runs, using the
<I>start</I> and <I>stop</I> keywords of the <A HREF = "run.html">run</A> command. See the
<A HREF = "run.html">run</A> command for details of how to do this.
</P>
<P>This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_nve.html">fix nve</A>, <A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "fix_temp_rescale.html">fix
temp/rescale</A>, <A HREF = "fix_langevin.html">fix langevin</A>,
<A HREF = "fix_modify.html">fix_modify</A>, <A HREF = "compute_temp.html">compute temp</A>,
<A HREF = "fix_press_berendsen.html">fix press/berendsen</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Berendsen"></A>
<P><B>(Berendsen)</B> Berendsen, Postma, van Gunsteren, DiNola, Haak, J Chem
Phys, 81, 3684 (1984).
</P>
</HTML>
diff --git a/doc/fix_temp_berendsen.txt b/doc/fix_temp_berendsen.txt
index 8dd962041..4ac7e2b6e 100644
--- a/doc/fix_temp_berendsen.txt
+++ b/doc/fix_temp_berendsen.txt
@@ -1,160 +1,160 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix temp/berendsen command :h3
fix temp/berendsen/cuda command :h3
[Syntax:]
fix ID group-ID temp/berendsen Tstart Tstop Tdamp :pre
ID, group-ID are documented in "fix"_fix.html command
temp/berendsen = style name of this fix command
Tstart,Tstop = desired temperature at start/end of run
Tdamp = temperature damping parameter (time units) :ul
[Examples:]
fix 1 all temp/berendsen 300.0 300.0 100.0 :pre
[Description:]
Reset the temperature of a group of atoms by using a Berendsen
thermostat "(Berendsen)"_#Berendsen, which rescales their velocities
every timestep.
The thermostat is applied to only the translational degrees of freedom
for the particles, which is an important consideration if extended
spherical or aspherical particles which have rotational degrees of
freedom are being thermostatted with this fix. The translational
degrees of freedom can also have a bias velocity removed from them
before thermostatting takes place; see the description below.
The desired temperature at each timestep is a ramped value during the
run from {Tstart} to {Tstop}. The {Tdamp} parameter is specified in
time units and determines how rapidly the temperature is relaxed. For
example, a value of 100.0 means to relax the temperature in a timespan
of (roughly) 100 time units (tau or fmsec or psec - see the
"units"_units.html command).
IMPORTANT NOTE: Unlike the "fix nvt"_fix_nh.html command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies velocities to
effect thermostatting. Thus you must use a separate time integration
fix, like "fix nve"_fix_nve.html to actually update the positions of
atoms using the modified velocities. Likewise, this fix should not
normally be used on atoms that also have their temperature controlled
by another fix - e.g. by "fix nvt"_fix_nh.html or "fix
langevin"_fix_langevin.html commands.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
This fix computes a temperature each timestep. To do this, the fix
creates its own compute of style "temp", as if this command had been
issued:
compute fix-ID_temp group-ID temp :pre
See the "compute temp"_compute_temp.html command for details. Note
that the ID of the new compute is the fix-ID + underscore + "temp",
and the group for the new compute is the same as the fix group.
Note that this is NOT the compute used by thermodynamic output (see
the "thermo_style"_thermo_style.html command) with ID = {thermo_temp}.
This means you can change the attributes of this fix's temperature
(e.g. its degrees-of-freedom) via the
"compute_modify"_compute_modify.html command or print this temperature
during thermodynamic output via the "thermo_style
custom"_thermo_style.html command using the appropriate compute-ID.
It also means that changing attributes of {thermo_temp} will have no
effect on this fix.
Like other fixes that perform thermostatting, this fix can be used
with "compute commands"_compute.html that calculate a temperature
after removing a "bias" from the atom velocities. E.g. removing the
center-of-mass velocity from a group of atoms or only calculating
temperature on the x-component of velocity or only calculating
temperature for atoms in a geometric region. This is not done by
default, but only if the "fix_modify"_fix_modify.html command is used
to assign a temperature compute to this fix that includes such a bias
term. See the doc pages for individual "compute
commands"_compute.html to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {temp} option is supported by this
fix. You can use it to assign a temperature "compute"_compute.html
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the energy change implied by a velocity rescaling to the
system's potential energy as part of "thermodynamic
output"_thermo_style.html.
This fix computes a global scalar which can be accessed by various
"output commands"_Section_howto.html#howto_15. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive".
This fix can ramp its target temperature over multiple runs, using the
{start} and {stop} keywords of the "run"_run.html command. See the
"run"_run.html command for details of how to do this.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:] none
[Related commands:]
"fix nve"_fix_nve.html, "fix nvt"_fix_nh.html, "fix
temp/rescale"_fix_temp_rescale.html, "fix langevin"_fix_langevin.html,
"fix_modify"_fix_modify.html, "compute temp"_compute_temp.html,
"fix press/berendsen"_fix_press_berendsen.html
[Default:] none
:line
:link(Berendsen)
[(Berendsen)] Berendsen, Postma, van Gunsteren, DiNola, Haak, J Chem
Phys, 81, 3684 (1984).
diff --git a/doc/fix_temp_rescale.html b/doc/fix_temp_rescale.html
index 81273ed4e..34fd4ea23 100644
--- a/doc/fix_temp_rescale.html
+++ b/doc/fix_temp_rescale.html
@@ -1,166 +1,166 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix temp/rescale command
</H3>
<H3>fix temp/rescale/cuda command
</H3>
<H3>fix temp/rescale/limit/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID temp/rescale N Tstart Tstop window fraction
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>temp/rescale = style name of this fix command
<LI>N = perform rescaling every N steps
<LI>Tstart,Tstop = desired temperature at start/end of run (temperature units)
<LI>window = only rescale if temperature is outside this window (temperature units)
<LI>fraction = rescale to target temperature by this fraction
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 3 flow temp/rescale 100 1.0 1.1 0.02 0.5
fix 3 boundary temp/rescale 1 1.0 1.5 0.05 1.0
fix 3 boundary temp/rescale 1 1.0 1.5 0.05 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>Reset the temperature of a group of atoms by explicitly rescaling
their velocities.
</P>
<P>The rescaling is applied to only the translational degrees of freedom
for the particles, which is an important consideration if extended
spherical or aspherical particles which have rotational degrees of
freedom are being thermostatted with this fix. The translational
degrees of freedom can also have a bias velocity removed from them
before thermostatting takes place; see the description below.
</P>
<P>Rescaling is performed every N timesteps. The target temperature is a
ramped value between the <I>Tstart</I> and <I>Tstop</I> temperatures at the
beginning and end of the run.
</P>
<P>Rescaling is only performed if the difference between the current and
desired temperatures is greater than the <I>window</I> value. The amount
of rescaling that is applied is a <I>fraction</I> (from 0.0 to 1.0) of the
difference between the actual and desired temperature. E.g. if
<I>fraction</I> = 1.0, the temperature is reset to exactly the desired
value.
</P>
<P>IMPORTANT NOTE: Unlike the <A HREF = "fix_nh.html">fix nvt</A> command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies velocities to
effect thermostatting. Thus you must use a separate time integration
fix, like <A HREF = "fix_nve.html">fix nve</A> to actually update the positions of
atoms using the modified velocities. Likewise, this fix should not
normally be used on atoms that also have their temperature controlled
by another fix - e.g. by <A HREF = "fix_nh.html">fix nvt</A> or <A HREF = "fix_langevin.html">fix
langevin</A> commands.
</P>
<P>See <A HREF = "Section_howto.html#howto_16">this howto section</A> of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
</P>
<P>This fix computes a temperature each timestep. To do this, the fix
creates its own compute of style "temp", as if one of this command had
been issued:
</P>
<PRE>compute fix-ID_temp group-ID temp
</PRE>
<P>See the <A HREF = "compute_temp.html">compute temp</A> for details. Note that the
ID of the new compute is the fix-ID + underscore + "temp", and the
group for the new compute is the same as the fix group.
</P>
<P>Note that this is NOT the compute used by thermodynamic output (see
the <A HREF = "thermo_style.html">thermo_style</A> command) with ID = <I>thermo_temp</I>.
This means you can change the attributes of this fix's temperature
(e.g. its degrees-of-freedom) via the
<A HREF = "compute_modify.html">compute_modify</A> command or print this temperature
during thermodynamic output via the <A HREF = "thermo_style.html">thermo_style
custom</A> command using the appropriate compute-ID.
It also means that changing attributes of <I>thermo_temp</I> will have no
effect on this fix.
</P>
<P>Like other fixes that perform thermostatting, this fix can be used
with <A HREF = "compute.html">compute commands</A> that calculate a temperature
after removing a "bias" from the atom velocities. E.g. removing the
center-of-mass velocity from a group of atoms or only calculating
temperature on the x-component of velocity or only calculating
temperature for atoms in a geometric region. This is not done by
default, but only if the <A HREF = "fix_modify.html">fix_modify</A> command is used
to assign a temperature compute to this fix that includes such a bias
term. See the doc pages for individual <A HREF = "compute.html">compute
commands</A> to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>temp</I> option is supported by this
fix. You can use it to assign a temperature <A HREF = "compute.html">compute</A>
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by this
fix to add the energy change implied by a velocity rescaling to the
system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>.
</P>
<P>This fix computes a global scalar which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive".
</P>
<P>This fix can ramp its target temperature over multiple runs, using the
<I>start</I> and <I>stop</I> keywords of the <A HREF = "run.html">run</A> command. See the
<A HREF = "run.html">run</A> command for details of how to do this.
</P>
<P>This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_langevin.html">fix langevin</A>, <A HREF = "fix_nh.html">fix nvt</A>,
<A HREF = "fix_modify.html">fix_modify</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_temp_rescale.txt b/doc/fix_temp_rescale.txt
index 5fbe99e5b..0215f837f 100644
--- a/doc/fix_temp_rescale.txt
+++ b/doc/fix_temp_rescale.txt
@@ -1,159 +1,159 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix temp/rescale command :h3
fix temp/rescale/cuda command :h3
fix temp/rescale/limit/cuda command :h3
[Syntax:]
fix ID group-ID temp/rescale N Tstart Tstop window fraction :pre
ID, group-ID are documented in "fix"_fix.html command
temp/rescale = style name of this fix command
N = perform rescaling every N steps
Tstart,Tstop = desired temperature at start/end of run (temperature units)
window = only rescale if temperature is outside this window (temperature units)
fraction = rescale to target temperature by this fraction :ul
[Examples:]
fix 3 flow temp/rescale 100 1.0 1.1 0.02 0.5
fix 3 boundary temp/rescale 1 1.0 1.5 0.05 1.0
fix 3 boundary temp/rescale 1 1.0 1.5 0.05 1.0 :pre
[Description:]
Reset the temperature of a group of atoms by explicitly rescaling
their velocities.
The rescaling is applied to only the translational degrees of freedom
for the particles, which is an important consideration if extended
spherical or aspherical particles which have rotational degrees of
freedom are being thermostatted with this fix. The translational
degrees of freedom can also have a bias velocity removed from them
before thermostatting takes place; see the description below.
Rescaling is performed every N timesteps. The target temperature is a
ramped value between the {Tstart} and {Tstop} temperatures at the
beginning and end of the run.
Rescaling is only performed if the difference between the current and
desired temperatures is greater than the {window} value. The amount
of rescaling that is applied is a {fraction} (from 0.0 to 1.0) of the
difference between the actual and desired temperature. E.g. if
{fraction} = 1.0, the temperature is reset to exactly the desired
value.
IMPORTANT NOTE: Unlike the "fix nvt"_fix_nh.html command which
performs Nose/Hoover thermostatting AND time integration, this fix
does NOT perform time integration. It only modifies velocities to
effect thermostatting. Thus you must use a separate time integration
fix, like "fix nve"_fix_nve.html to actually update the positions of
atoms using the modified velocities. Likewise, this fix should not
normally be used on atoms that also have their temperature controlled
by another fix - e.g. by "fix nvt"_fix_nh.html or "fix
langevin"_fix_langevin.html commands.
See "this howto section"_Section_howto.html#howto_16 of the manual for
a discussion of different ways to compute temperature and perform
thermostatting.
This fix computes a temperature each timestep. To do this, the fix
creates its own compute of style "temp", as if one of this command had
been issued:
compute fix-ID_temp group-ID temp :pre
See the "compute temp"_compute_temp.html for details. Note that the
ID of the new compute is the fix-ID + underscore + "temp", and the
group for the new compute is the same as the fix group.
Note that this is NOT the compute used by thermodynamic output (see
the "thermo_style"_thermo_style.html command) with ID = {thermo_temp}.
This means you can change the attributes of this fix's temperature
(e.g. its degrees-of-freedom) via the
"compute_modify"_compute_modify.html command or print this temperature
during thermodynamic output via the "thermo_style
custom"_thermo_style.html command using the appropriate compute-ID.
It also means that changing attributes of {thermo_temp} will have no
effect on this fix.
Like other fixes that perform thermostatting, this fix can be used
with "compute commands"_compute.html that calculate a temperature
after removing a "bias" from the atom velocities. E.g. removing the
center-of-mass velocity from a group of atoms or only calculating
temperature on the x-component of velocity or only calculating
temperature for atoms in a geometric region. This is not done by
default, but only if the "fix_modify"_fix_modify.html command is used
to assign a temperature compute to this fix that includes such a bias
term. See the doc pages for individual "compute
commands"_compute.html to determine which ones include a bias. In
this case, the thermostat works in the following manner: the current
temperature is calculated taking the bias into account, bias is
removed from each atom, thermostatting is performed on the remaining
thermal degrees of freedom, and the bias is added back in.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html.
The "fix_modify"_fix_modify.html {temp} option is supported by this
fix. You can use it to assign a temperature "compute"_compute.html
you have defined to this fix which will be used in its thermostatting
procedure, as described above. For consistency, the group used by
this fix and by the compute should be the same.
The "fix_modify"_fix_modify.html {energy} option is supported by this
fix to add the energy change implied by a velocity rescaling to the
system's potential energy as part of "thermodynamic
output"_thermo_style.html.
This fix computes a global scalar which can be accessed by various
"output commands"_Section_howto.html#howto_15. The scalar is the
cummulative energy change due to this fix. The scalar value
calculated by this fix is "extensive".
This fix can ramp its target temperature over multiple runs, using the
{start} and {stop} keywords of the "run"_run.html command. See the
"run"_run.html command for details of how to do this.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:] none
[Related commands:]
"fix langevin"_fix_langevin.html, "fix nvt"_fix_nh.html,
"fix_modify"_fix_modify.html
[Default:] none
diff --git a/doc/fix_viscosity.html b/doc/fix_viscosity.html
index 51eee268f..57e0502b3 100644
--- a/doc/fix_viscosity.html
+++ b/doc/fix_viscosity.html
@@ -1,171 +1,172 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix viscosity command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID viscosity N vdim pdim Nbin keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>viscosity = style name of this fix command
<LI>N = perform momentum exchange every N steps
<LI>vdim = <I>x</I> or <I>y</I> or <I>z</I> = which momentum component to exchange
<LI>pdim = <I>x</I> or <I>y</I> or <I>z</I> = direction of momentum transfer
<LI>Nbin = # of layers in pdim direction (must be even number)
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>swap</I> or <I>target</I>
<PRE> <I>swap</I> value = Nswap = number of swaps to perform every N steps
<I>vtarget</I> value = V or INF = target velocity of swap partners (velocity units)
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 all viscosity 100 x z 20
fix 1 all viscosity 50 x z 20 swap 2 vtarget 1.5
</PRE>
<P><B>Description:</B>
</P>
<P>Use the Muller-Plathe algorithm described in <A HREF = "#Muller-Plathe">this
paper</A> to exchange momenta between two particles in
different regions of the simulation box every N steps. This induces a
shear velocity profile in the system. As described below this enables
a viscosity of the fluid to be calculated. This algorithm is
sometimes called a reverse non-equilibrium MD (reverse NEMD) approach
to computing viscosity. This is because the usual NEMD approach is to
impose a shear velocity profile on the system and measure the response
via an off-diagonal component of the stress tensor, which is
proportional to the momentum flux. In the Muller-Plathe method, the
momentum flux is imposed, and the shear velocity profile is the
system's response.
</P>
<P>The simulation box is divided into <I>Nbin</I> layers in the <I>pdim</I>
direction, where the layer 1 is at the low end of that dimension and
the layer <I>Nbin</I> is at the high end. Every N steps, Nswap pairs of
atoms are chosen in the following manner. Only atoms in the fix group
are considered. Nswap atoms in layer 1 with positive velocity
components in the <I>vdim</I> direction closest to the target value <I>V</I> are
selected. Similarly, Nswap atoms in the "middle" layer (see below) with
negative velocity components in the <I>vdim</I> direction closest to the
negative of the target value <I>V</I> are selected. The two sets of Nswap
atoms are paired up and their <I>vdim</I> momenta components are swapped
within each pair. This resets their velocities, typically in opposite
directions. Over time, this induces a shear velocity profile in the
system which can be measured using commands such as the following,
which writes the profile to the file tmp.profile:
</P>
<PRE>fix f1 all ave/spatial 100 10 1000 z lower 0.05 vx &
file tmp.profile units reduced
</PRE>
<P>Note that by default, Nswap = 1 and vtarget = INF, though this can be
changed by the optional <I>swap</I> and <I>vtarget</I> keywords. When vtarget =
INF, one or more atoms with the most positive and negative velocity
components are selected. Setting these parameters appropriately, in
conjunction with the swap rate N, allows the momentum flux rate to be
adjusted across a wide range of values, and the momenta to be
exchanged in large chunks or more smoothly.
</P>
<P>The "middle" layer for momenta swapping is defined as the <I>Nbin</I>/2 + 1
layer. Thus if <I>Nbin</I> = 20, the two swapping layers are 1 and 11.
This should lead to a symmetric velocity profile since the two layers
are separated by the same distance in both directions in a periodic
sense. This is why <I>Nbin</I> is restricted to being an even number.
</P>
<P>As described below, the total momentum transferred by these velocity
swaps is computed by the fix and can be output. Dividing this
quantity by time and the cross-sectional area of the simulation box
yields a momentum flux. The ratio of momentum flux to the slope of
the shear velocity profile is the viscosity of the fluid, in
appopriate units. See the <A HREF = "#Muller-Plathe">Muller-Plathe paper</A> for
details.
</P>
<P>IMPORTANT NOTE: After equilibration, if the velocity profile you
observe is not linear, then you are likely swapping momentum too
frequently and are not in a regime of linear response. In this case
you cannot accurately infer a viscosity and should try increasing
the Nevery parameter.
</P>
<P>An alternative method for calculating a viscosity is to run a NEMD
-simulation, as described in <A HREF = "Section_howto.html#howto_13">this section</A>
-of the manual. NEMD simulations deform the simmulation box via the
-<A HREF = "fix_deform.html">fix deform</A> command. Thus they cannot be run on a
-charged system using a <A HREF = "kspace_style.html">PPPM solver</A> since PPPM does
-not currently support non-orthogonal boxes. Using fix viscosity keeps
-the box orthogonal; thus it does not suffer from this limitation.
+simulation, as described in <A HREF = "Section_howto.html#howto_13">Section_howto
+13</A> of the manual. NEMD simulations
+deform the simmulation box via the <A HREF = "fix_deform.html">fix deform</A>
+command. Thus they cannot be run on a charged system using a <A HREF = "kspace_style.html">PPPM
+solver</A> since PPPM does not currently support
+non-orthogonal boxes. Using fix viscosity keeps the box orthogonal;
+thus it does not suffer from this limitation.
</P>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix.
</P>
<P>This fix computes a global scalar which can be accessed by various
<A HREF = "Section_howto.html#howto_15">output commands</A>. The scalar is the
cummulative momentum transferred between the bottom and middle of the
simulation box (in the <I>pdim</I> direction) is stored as a scalar
quantity by this fix. This quantity is zeroed when the fix is defined
and accumlates thereafter, once every N steps. The units of the
quantity are momentum = mass*velocity. The scalar value calculated by
this fix is "intensive".
</P>
<P>No parameter of this fix can be used with the <I>start/stop</I> keywords of
the <A HREF = "run.html">run</A> command. This fix is not invoked during <A HREF = "minimize.html">energy
minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>Swaps conserve both momentum and kinetic energy, even if the masses of
the swapped atoms are not equal. Thus you should not need to
thermostat the system. If you do use a thermostat, you may want to
apply it only to the non-swapped dimensions (other than <I>vdim</I>).
</P>
<P>LAMMPS does not check, but you should not use this fix to swap
velocities of atoms that are in constrained molecules, e.g. via <A HREF = "fix_shake.html">fix
shake</A> or <A HREF = "fix_rigid.html">fix rigid</A>. This is because
application of the constraints will alter the amount of transferred
momentum. You should, however, be able to use flexible molecules.
See the <A HREF = "#Maginn">Maginn paper</A> for an example of using this algorithm
in a computation of alcohol molecule properties.
</P>
<P>When running a simulation with large, massive particles or molecules
in a background solvent, you may want to only exchange momenta bewteen
solvent particles.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_ave_spatial.html">fix ave/spatial</A>, <A HREF = "fix_thermal_conductivity.html">fix
thermal/conductivity</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are swap = 1 and vtarget = INF.
</P>
<HR>
<A NAME = "Muller-Plathe"></A>
<P><B>(Muller-Plathe)</B> Muller-Plathe, Phys Rev E, 59, 4894-4898 (1999).
</P>
<A NAME = "Maginn"></A>
<P><B>(Maginn)</B> Kelkar, Rafferty, Maginn, Siepmann, Fluid Phase Equilibria,
260, 218-231 (2007).
</P>
</HTML>
diff --git a/doc/fix_viscosity.txt b/doc/fix_viscosity.txt
index 3e3952687..511c194bb 100644
--- a/doc/fix_viscosity.txt
+++ b/doc/fix_viscosity.txt
@@ -1,156 +1,157 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix viscosity command :h3
[Syntax:]
fix ID group-ID viscosity N vdim pdim Nbin keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
viscosity = style name of this fix command :l
N = perform momentum exchange every N steps :l
vdim = {x} or {y} or {z} = which momentum component to exchange :l
pdim = {x} or {y} or {z} = direction of momentum transfer :l
Nbin = # of layers in pdim direction (must be even number) :l
zero or more keyword/value pairs may be appended :l
keyword = {swap} or {target} :l
{swap} value = Nswap = number of swaps to perform every N steps
{vtarget} value = V or INF = target velocity of swap partners (velocity units) :pre
:ule
[Examples:]
fix 1 all viscosity 100 x z 20
fix 1 all viscosity 50 x z 20 swap 2 vtarget 1.5 :pre
[Description:]
Use the Muller-Plathe algorithm described in "this
paper"_#Muller-Plathe to exchange momenta between two particles in
different regions of the simulation box every N steps. This induces a
shear velocity profile in the system. As described below this enables
a viscosity of the fluid to be calculated. This algorithm is
sometimes called a reverse non-equilibrium MD (reverse NEMD) approach
to computing viscosity. This is because the usual NEMD approach is to
impose a shear velocity profile on the system and measure the response
via an off-diagonal component of the stress tensor, which is
proportional to the momentum flux. In the Muller-Plathe method, the
momentum flux is imposed, and the shear velocity profile is the
system's response.
The simulation box is divided into {Nbin} layers in the {pdim}
direction, where the layer 1 is at the low end of that dimension and
the layer {Nbin} is at the high end. Every N steps, Nswap pairs of
atoms are chosen in the following manner. Only atoms in the fix group
are considered. Nswap atoms in layer 1 with positive velocity
components in the {vdim} direction closest to the target value {V} are
selected. Similarly, Nswap atoms in the "middle" layer (see below) with
negative velocity components in the {vdim} direction closest to the
negative of the target value {V} are selected. The two sets of Nswap
atoms are paired up and their {vdim} momenta components are swapped
within each pair. This resets their velocities, typically in opposite
directions. Over time, this induces a shear velocity profile in the
system which can be measured using commands such as the following,
which writes the profile to the file tmp.profile:
fix f1 all ave/spatial 100 10 1000 z lower 0.05 vx &
file tmp.profile units reduced :pre
Note that by default, Nswap = 1 and vtarget = INF, though this can be
changed by the optional {swap} and {vtarget} keywords. When vtarget =
INF, one or more atoms with the most positive and negative velocity
components are selected. Setting these parameters appropriately, in
conjunction with the swap rate N, allows the momentum flux rate to be
adjusted across a wide range of values, and the momenta to be
exchanged in large chunks or more smoothly.
The "middle" layer for momenta swapping is defined as the {Nbin}/2 + 1
layer. Thus if {Nbin} = 20, the two swapping layers are 1 and 11.
This should lead to a symmetric velocity profile since the two layers
are separated by the same distance in both directions in a periodic
sense. This is why {Nbin} is restricted to being an even number.
As described below, the total momentum transferred by these velocity
swaps is computed by the fix and can be output. Dividing this
quantity by time and the cross-sectional area of the simulation box
yields a momentum flux. The ratio of momentum flux to the slope of
the shear velocity profile is the viscosity of the fluid, in
appopriate units. See the "Muller-Plathe paper"_#Muller-Plathe for
details.
IMPORTANT NOTE: After equilibration, if the velocity profile you
observe is not linear, then you are likely swapping momentum too
frequently and are not in a regime of linear response. In this case
you cannot accurately infer a viscosity and should try increasing
the Nevery parameter.
An alternative method for calculating a viscosity is to run a NEMD
-simulation, as described in "this section"_Section_howto.html#howto_13
-of the manual. NEMD simulations deform the simmulation box via the
-"fix deform"_fix_deform.html command. Thus they cannot be run on a
-charged system using a "PPPM solver"_kspace_style.html since PPPM does
-not currently support non-orthogonal boxes. Using fix viscosity keeps
-the box orthogonal; thus it does not suffer from this limitation.
+simulation, as described in "Section_howto
+13"_Section_howto.html#howto_13 of the manual. NEMD simulations
+deform the simmulation box via the "fix deform"_fix_deform.html
+command. Thus they cannot be run on a charged system using a "PPPM
+solver"_kspace_style.html since PPPM does not currently support
+non-orthogonal boxes. Using fix viscosity keeps the box orthogonal;
+thus it does not suffer from this limitation.
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix.
This fix computes a global scalar which can be accessed by various
"output commands"_Section_howto.html#howto_15. The scalar is the
cummulative momentum transferred between the bottom and middle of the
simulation box (in the {pdim} direction) is stored as a scalar
quantity by this fix. This quantity is zeroed when the fix is defined
and accumlates thereafter, once every N steps. The units of the
quantity are momentum = mass*velocity. The scalar value calculated by
this fix is "intensive".
No parameter of this fix can be used with the {start/stop} keywords of
the "run"_run.html command. This fix is not invoked during "energy
minimization"_minimize.html.
[Restrictions:]
Swaps conserve both momentum and kinetic energy, even if the masses of
the swapped atoms are not equal. Thus you should not need to
thermostat the system. If you do use a thermostat, you may want to
apply it only to the non-swapped dimensions (other than {vdim}).
LAMMPS does not check, but you should not use this fix to swap
velocities of atoms that are in constrained molecules, e.g. via "fix
shake"_fix_shake.html or "fix rigid"_fix_rigid.html. This is because
application of the constraints will alter the amount of transferred
momentum. You should, however, be able to use flexible molecules.
See the "Maginn paper"_#Maginn for an example of using this algorithm
in a computation of alcohol molecule properties.
When running a simulation with large, massive particles or molecules
in a background solvent, you may want to only exchange momenta bewteen
solvent particles.
[Related commands:]
"fix ave/spatial"_fix_ave_spatial.html, "fix
thermal/conductivity"_fix_thermal_conductivity.html
[Default:]
The option defaults are swap = 1 and vtarget = INF.
:line
:link(Muller-Plathe)
[(Muller-Plathe)] Muller-Plathe, Phys Rev E, 59, 4894-4898 (1999).
:link(Maginn)
[(Maginn)] Kelkar, Rafferty, Maginn, Siepmann, Fluid Phase Equilibria,
260, 218-231 (2007).
diff --git a/doc/fix_viscous.html b/doc/fix_viscous.html
index fe03b9867..94a9c6980 100644
--- a/doc/fix_viscous.html
+++ b/doc/fix_viscous.html
@@ -1,131 +1,131 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix viscous command
</H3>
<H3>fix viscous/cuda command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID viscous gamma keyword values ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>viscous = style name of this fix command
<LI>gamma = damping coefficient (force/velocity units)
<LI>zero or more keyword/value pairs may be appended
<PRE>keyword = <I>scale</I>
<I>scale</I> values = type ratio
type = atom type (1-N)
ratio = factor to scale the damping coefficient by
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 flow viscous 0.1
fix 1 damp viscous 0.5 scale 3 2.5
</PRE>
<P><B>Description:</B>
</P>
<P>Add a viscous damping force to atoms in the group that is proportional
to the velocity of the atom. The added force can be thought of as a
frictional interaction with implicit solvent, i.e. the no-slip Stokes
drag on a spherical particle. In granular simulations this can be
useful for draining the kinetic energy from the system in a controlled
fashion. If used without additional thermostatting (to add kinetic
energy to the system), it has the effect of slowly (or rapidly)
freezing the system; hence it can also be used as a simple energy
minimization technique.
</P>
<P>The damping force F is given by F = - gamma * velocity. The larger
the coefficient, the faster the kinetic energy is reduced. If the
optional keyword <I>scale</I> is used, gamma can scaled up or down by the
specified factor for atoms of that type. It can be used multiple
times to adjust gamma for several atom types.
</P>
<P>IMPORTANT NOTE: You should specify gamma in force/velocity units.
This is not the same as mass/time units, at least for some of the
LAMMPS <A HREF = "units.html">units</A> options like "real" or "metal" that are not
self-consistent.
</P>
<P>In a Brownian dynamics context, gamma = Kb T / D, where Kb =
Boltzmann's constant, T = temperature, and D = particle diffusion
coefficient. D can be written as Kb T / (3 pi eta d), where eta =
dynamic viscosity of the frictional fluid and d = diameter of
particle. This means gamma = 3 pi eta d, and thus is proportional to
the viscosity of the fluid and the particle diameter.
</P>
<P>In the current implementation, rather than have the user specify a
viscosity, gamma is specified directly in force/velocity units. If
needed, gamma can be adjusted for atoms of different sizes
(i.e. sigma) by using the <I>scale</I> keyword.
</P>
<P>Note that Brownian dynamics models also typically include a randomized
force term to thermostat the system at a chosen temperature. The <A HREF = "fix_langevin.html">fix
langevin</A> command does this. It has the same
viscous damping term as fix viscous and adds a random force to each
atom. Hence if using fix <I>langevin</I> you do not typically need to use
fix <I>viscous</I>. Also note that the gamma of fix viscous is related to
the damping parameter of <A HREF = "fix_langevin.html">fix langevin</A>, except that
the units of gamma are force/velocity and the units of damp are time,
so that it can more easily be used as a thermostat.
</P>
<HR>
<P>Styles with a <I>cuda</I> suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-<A HREF = "Section_accelerate.html">this section</A> of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various <A HREF = "Section_howto.html#howto_15">output
commands</A>. No parameter of this fix can
be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
</P>
<P>The forces due to this fix are imposed during an energy minimization,
invoked by the <A HREF = "minimize.html">minimize</A> command. This fix should only
be used with damped dynamics minimizers that allow for
non-conservative forces. See the <A HREF = "min_style.html">min_style</A> command
for details.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_langevin.html">fix langevin</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/fix_viscous.txt b/doc/fix_viscous.txt
index bfd26b726..2e1b87837 100644
--- a/doc/fix_viscous.txt
+++ b/doc/fix_viscous.txt
@@ -1,120 +1,120 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix viscous command :h3
fix viscous/cuda command :h3
[Syntax:]
fix ID group-ID viscous gamma keyword values ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
viscous = style name of this fix command :l
gamma = damping coefficient (force/velocity units) :l
zero or more keyword/value pairs may be appended :l
keyword = {scale}
{scale} values = type ratio
type = atom type (1-N)
ratio = factor to scale the damping coefficient by :pre
:ule
[Examples:]
fix 1 flow viscous 0.1
fix 1 damp viscous 0.5 scale 3 2.5 :pre
[Description:]
Add a viscous damping force to atoms in the group that is proportional
to the velocity of the atom. The added force can be thought of as a
frictional interaction with implicit solvent, i.e. the no-slip Stokes
drag on a spherical particle. In granular simulations this can be
useful for draining the kinetic energy from the system in a controlled
fashion. If used without additional thermostatting (to add kinetic
energy to the system), it has the effect of slowly (or rapidly)
freezing the system; hence it can also be used as a simple energy
minimization technique.
The damping force F is given by F = - gamma * velocity. The larger
the coefficient, the faster the kinetic energy is reduced. If the
optional keyword {scale} is used, gamma can scaled up or down by the
specified factor for atoms of that type. It can be used multiple
times to adjust gamma for several atom types.
IMPORTANT NOTE: You should specify gamma in force/velocity units.
This is not the same as mass/time units, at least for some of the
LAMMPS "units"_units.html options like "real" or "metal" that are not
self-consistent.
In a Brownian dynamics context, gamma = Kb T / D, where Kb =
Boltzmann's constant, T = temperature, and D = particle diffusion
coefficient. D can be written as Kb T / (3 pi eta d), where eta =
dynamic viscosity of the frictional fluid and d = diameter of
particle. This means gamma = 3 pi eta d, and thus is proportional to
the viscosity of the fluid and the particle diameter.
In the current implementation, rather than have the user specify a
viscosity, gamma is specified directly in force/velocity units. If
needed, gamma can be adjusted for atoms of different sizes
(i.e. sigma) by using the {scale} keyword.
Note that Brownian dynamics models also typically include a randomized
force term to thermostat the system at a chosen temperature. The "fix
langevin"_fix_langevin.html command does this. It has the same
viscous damping term as fix viscous and adds a random force to each
atom. Hence if using fix {langevin} you do not typically need to use
fix {viscous}. Also note that the gamma of fix viscous is related to
the damping parameter of "fix langevin"_fix_langevin.html, except that
the units of gamma are force/velocity and the units of damp are time,
so that it can more easily be used as a thermostat.
:line
Styles with a {cuda} suffix are functionally the same as the
corresponding style without the suffix. They have been optimized to
run faster, depending on your available hardware, as discussed in
-"this section"_Section_accelerate.html of the manual. The accelerated
-styles take the same arguments and should produce the same results,
-except for round-off and precision issues.
+"Section_accelerate"_Section_accelerate.html of the manual. The
+accelerated styles take the same arguments and should produce the same
+results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA package. They are
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
commands"_Section_howto.html#howto_15. No parameter of this fix can
be used with the {start/stop} keywords of the "run"_run.html command.
The forces due to this fix are imposed during an energy minimization,
invoked by the "minimize"_minimize.html command. This fix should only
be used with damped dynamics minimizers that allow for
non-conservative forces. See the "min_style"_min_style.html command
for details.
[Restrictions:] none
[Related commands:]
"fix langevin"_fix_langevin.html
[Default:] none
diff --git a/doc/fix_wall_piston.html b/doc/fix_wall_piston.html
index 17b3262da..12b25dc30 100644
--- a/doc/fix_wall_piston.html
+++ b/doc/fix_wall_piston.html
@@ -1,133 +1,133 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>fix wall/piston command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID wall/piston face arg ... keyword value ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>wall/piston = style name of this fix command
<LI>one face/arg pair must be appended
<LI>face = <I>zlo</I>
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>pos</I> or <I>vel</I> or <I>ramp</I> or <I>units</I>
<PRE> <I>pos</I> args = z
z = z coordinate at which the piston begins (distance units)
<I>vel</I> args = vz
vz = final velocity of the piston (velocity units)
<I>ramp</I> = use a linear velocity ramp from 0 to vz
<I>temp</I> args = target damp seed extent
target = target velocity for region immediately ahead of the piston
damp = damping paramter (time units)
seed = random number seed for langevin kicks
extent = extent of thermostated region (distance units)
<I>units</I> value = <I>lattice</I> or <I>box</I>
<I>lattice</I> = the wall position is defined in lattice units
<I>box</I> = the wall position is defined in simulation box units
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix xwalls all wall/piston zlo
fix walls all wall/piston zlo pos 1.0 0.0 0.0 vel 0.0 0.0 10.0 units box
fix top all wall/piston zlo vel 0.0 0.0 10.0 ramp
</PRE>
<P><B>Description:</B>
</P>
<P>Bound the simulation with a moving wall which reflect particles
in the specified group and drive the system with an effective infinite-mass
piston capable of driving shock waves.
</P>
<P>A momentum mirror technique is used, which means that if an atom (or the wall)
moves such that an atom is outside the wall on a timestep
by a distance delta (e.g. due to <A HREF = "fix_nve.html">fix nve</A>), then it is
put back inside the face by the same delta, and the velocity relative to
the moving wall is flipped in z. For instance, a stationary particle hit with a
piston wall with velocity vz, will end the timestep with a velocity of 2*vz.
</P>
<P>Currently only face <I>zlo</I> may be specified.
This creates a piston moving in the positive z direction.
Particles with z coordinate less than the wall position
are reflected to a z coordinate
greater than the wall position.
If the piston velocity is vpz and the particle velocity
before reflection is vzi, the particle velocity after
reflection is -vzi + 2*vpz.
</P>
<P>The initial position of the wall can be specified by the <I>pos</I> keyword.
</P>
<P>The final velocity of the wall can be specified by the <I>vel</I> keyword
</P>
<P>The <I>ramp</I> keyword will cause the wall/piston to adjust the velocity linearly
from zero velocity to <I>vel</I> over the course of the run. If the <I>ramp</I> keyword is omitted
then the wall/piston moves at a constant velocity defined by <I>vel</I>.
</P>
<P>The <I>temp</I> keyword will cause the region immediately in front of the wall/piston
to be thermostated with a Langevin thermostat. This region moves with the piston.
The damping and kicking are measured in the reference frame of the piston.
So, a temperature of zero would mean all particles were moving at exactly the speed
of the wall/piston.
</P>
<P>The <I>units</I> keyword determines the meaning of the distance units used
to define a wall position, but only when a numeric constant is used.
</P>
<P>A <I>box</I> value selects standard distance units as defined by the
<A HREF = "units.html">units</A> command, e.g. Angstroms for units = real or metal.
A <I>lattice</I> value means the distance units are in lattice spacings.
The <A HREF = "lattice.html">lattice</A> command must have been previously used to
define the lattice spacings.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about this fix is written to <A HREF = "restart.html">binary restart
files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options
are relevant to this fix. No global or per-atom quantities are stored
-by this fix for access by various <A HREF = "Section_howto.html#4_15">output
-commands</A>. No parameter of this fix can be
-used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
+by this fix for access by various <A HREF = "Section_howto.html#howoto_15">output
+commands</A>. No parameter of this fix can
+be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command.
This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>This fix style is part of the SHOCK package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The face that has the wall/piston must be boundary type 'm' (shrink-wrapped
with minimum a minimum value). The opposing face can be
any boundary type other than periodic.
</P>
<P>A wall/piston should not be used with rigid bodies such as those
defined by a "fix rigid" command. This is because the wall/piston
displaces atoms directly rather than exerting a force on them.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "fix_wall.html">fix wall/reflect</A> command
</P>
<P><A HREF = "fix_append_atoms.html">fix append/atoms</A> command
</P>
<P><B>Default:</B> <I>pos</I> = 0, <I>vel</I> = 0, <I>units</I> = lattice.
</P>
<HR>
</HTML>
diff --git a/doc/fix_wall_piston.txt b/doc/fix_wall_piston.txt
index 5194733c7..f4c3a5dd4 100644
--- a/doc/fix_wall_piston.txt
+++ b/doc/fix_wall_piston.txt
@@ -1,121 +1,121 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
fix wall/piston command :h3
[Syntax:]
fix ID group-ID wall/piston face arg ... keyword value ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
wall/piston = style name of this fix command :l
one face/arg pair must be appended :l
face = {zlo} :l
zero or more keyword/value pairs may be appended :l
keyword = {pos} or {vel} or {ramp} or {units} :l
{pos} args = z
z = z coordinate at which the piston begins (distance units)
{vel} args = vz
vz = final velocity of the piston (velocity units)
{ramp} = use a linear velocity ramp from 0 to vz
{temp} args = target damp seed extent
target = target velocity for region immediately ahead of the piston
damp = damping paramter (time units)
seed = random number seed for langevin kicks
extent = extent of thermostated region (distance units)
{units} value = {lattice} or {box}
{lattice} = the wall position is defined in lattice units
{box} = the wall position is defined in simulation box units :pre
:ule
[Examples:]
fix xwalls all wall/piston zlo
fix walls all wall/piston zlo pos 1.0 0.0 0.0 vel 0.0 0.0 10.0 units box
fix top all wall/piston zlo vel 0.0 0.0 10.0 ramp :pre
[Description:]
Bound the simulation with a moving wall which reflect particles
in the specified group and drive the system with an effective infinite-mass
piston capable of driving shock waves.
A momentum mirror technique is used, which means that if an atom (or the wall)
moves such that an atom is outside the wall on a timestep
by a distance delta (e.g. due to "fix nve"_fix_nve.html), then it is
put back inside the face by the same delta, and the velocity relative to
the moving wall is flipped in z. For instance, a stationary particle hit with a
piston wall with velocity vz, will end the timestep with a velocity of 2*vz.
Currently only face {zlo} may be specified.
This creates a piston moving in the positive z direction.
Particles with z coordinate less than the wall position
are reflected to a z coordinate
greater than the wall position.
If the piston velocity is vpz and the particle velocity
before reflection is vzi, the particle velocity after
reflection is -vzi + 2*vpz.
The initial position of the wall can be specified by the {pos} keyword.
The final velocity of the wall can be specified by the {vel} keyword
The {ramp} keyword will cause the wall/piston to adjust the velocity linearly
from zero velocity to {vel} over the course of the run. If the {ramp} keyword is omitted
then the wall/piston moves at a constant velocity defined by {vel}.
The {temp} keyword will cause the region immediately in front of the wall/piston
to be thermostated with a Langevin thermostat. This region moves with the piston.
The damping and kicking are measured in the reference frame of the piston.
So, a temperature of zero would mean all particles were moving at exactly the speed
of the wall/piston.
The {units} keyword determines the meaning of the distance units used
to define a wall position, but only when a numeric constant is used.
A {box} value selects standard distance units as defined by the
"units"_units.html command, e.g. Angstroms for units = real or metal.
A {lattice} value means the distance units are in lattice spacings.
The "lattice"_lattice.html command must have been previously used to
define the lattice spacings.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about this fix is written to "binary restart
files"_restart.html. None of the "fix_modify"_fix_modify.html options
are relevant to this fix. No global or per-atom quantities are stored
by this fix for access by various "output
-commands"_Section_howto.html#4_15. No parameter of this fix can be
-used with the {start/stop} keywords of the "run"_run.html command.
+commands"_Section_howto.html#howoto_15. No parameter of this fix can
+be used with the {start/stop} keywords of the "run"_run.html command.
This fix is not invoked during "energy minimization"_minimize.html.
[Restrictions:]
This fix style is part of the SHOCK package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The face that has the wall/piston must be boundary type 'm' (shrink-wrapped
with minimum a minimum value). The opposing face can be
any boundary type other than periodic.
A wall/piston should not be used with rigid bodies such as those
defined by a "fix rigid" command. This is because the wall/piston
displaces atoms directly rather than exerting a force on them.
[Related commands:]
"fix wall/reflect"_fix_wall.html command
"fix append/atoms"_fix_append_atoms.html command
[Default:] {pos} = 0, {vel} = 0, {units} = lattice.
:line
diff --git a/doc/if.html b/doc/if.html
index 3baffda0f..a0014191f 100644
--- a/doc/if.html
+++ b/doc/if.html
@@ -1,162 +1,162 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>if command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>if boolean then t1 t2 ... elif boolean f1 f2 ... elif boolean f1 f2 ... else e1 e2 ...
</PRE>
<UL><LI>boolean = a Boolean expression evaluated as TRUE or FALSE (see below)
<LI>then = required word
<LI>t1,t2,...,tN = one or more LAMMPS commands to execute if condition is met, each enclosed in quotes
<LI>elif = optional word, can appear multiple times
<LI>f1,f2,...,fN = one or more LAMMPS commands to execute if elif condition is met, each enclosed in quotes (optional arguments)
<LI>else = optional argument
<LI>e1,e2,...,eN = one or more LAMMPS commands to execute if no condition is met, each enclosed in quotes (optional arguments)
</UL>
<P><B>Examples:</B>
</P>
<PRE>if "${steps} > 1000" then exit
if "$x <= $y" then "print X is smaller = $x" else "print Y is smaller = $y"
if "(${eng} > 0.0) || ($n < 1000)" then &
"timestep 0.005" &
elif $n<10000 &
"timestep 0.01" &
else &
"timestep 0.02" &
"print 'Max step reached'"
if "${eng} > ${eng_previous}" then "jump file1" else "jump file2"
</PRE>
<P><B>Description:</B>
</P>
<P>This command provides an in-then-else capability within an input
script. A Boolean expression is evaluted and the result is TRUE or
FALSE. Note that as in the examples above, the expression can contain
variables, as defined by the <A HREF = "variable.html">variable</A> command, which
will be evaluated as part of the expression. Thus a user-defined
formula that reflects the current state of the simulation can be used
to issue one or more new commands.
</P>
<P>If the result of the Boolean expression is TRUE, then one or more
commands (t1, t2, ..., tN) are executed. If it is FALSE, then Boolean
expressions associated with successive elif keywords are evaluated
until one is found to be true, in which case its commands (f1, f2,
..., fN) are executed. If no Boolean expression is TRUE, then the
commands associated witht the else keyword, namely (e1, e2, ..., eN),
are executed. The elif and else keywords and their associated
commands are optional. If they aren't specified and the initial
Boolean expression is FALSE, then no commands are executed.
</P>
<P>The syntax for Boolean expressions is described below.
</P>
<P>Each command (t1, f1, e1, etc) can be any valid LAMMPS input script
command. If the command is more than one word, it must enclosed in
quotes, so it will be treated as a single argument, as in the examples
above.
</P>
<P>IMPORTANT NOTE: If a command itself requires a quoted argument (e.g. a
<A HREF = "print.html">print</A> command), then double and single quotes can be used
and nested in the usual manner, as in the examples above and below.
-See <A HREF = "Section_commands.html#cmd_2">this section</A> of the manual for more
-details on using quotes in arguments. Only one of level of nesting is
-allowed, but that should be sufficient for most use cases.
+See <A HREF = "Section_commands.html#cmd_2">Section_commands 2</A> of the manual for
+more details on using quotes in arguments. Only one of level of
+nesting is allowed, but that should be sufficient for most use cases.
</P>
<P>Note that by using the line continuation character "&", the if command
can be spread across many lines, though it is still a single command:
</P>
<PRE>if "$a < $b" then &
"print 'Minimum value = $a'" &
"run 1000" &
else &
'print "Minimum value = $b"' &
"minimize 0.001 0.001 1000 10000"
</PRE>
<P>Note that if one of the commands to execute is an invalid LAMMPS
command, such as "exit" in the first example above, then executing the
command will cause LAMMPS to halt.
</P>
<P>Note that by jumping to a label in the same input script, the if
command can be used to break out of a loop. See the <A HREF = "variable.html">variable
delete</A> command for info on how to delete the associated
loop variable, so that it can be re-used later in the input script.
</P>
<P>Here is an example of a double loop which uses the if and
<A HREF = "jump.html">jump</A> commands to break out of the inner loop when a
condition is met, then continues iterating thru the outer loop.
</P>
<PRE>label loopa
variable a loop 5
label loopb
variable b loop 5
print "A,B = $a,$b"
run 10000
if '$b > 2' then "print 'Jumping to another script'" "jump in.script break"
next b
jump in.script loopb
label break
variable b delete
</PRE>
<PRE>next a
jump in.script loopa
</PRE>
<HR>
<P>The Boolean expressions for the if and elif keywords have a C-like
syntax. Note that each expression is a single argument within the if
command. Thus if you want to include spaces in the expression for
clarity, you must enclose the entire expression in quotes.
</P>
<P>An expression is built out of numbers:
</P>
<PRE>0.2, 100, 1.0e20, -15.4, etc
</PRE>
<P>and Boolean operators:
</P>
<PRE>A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, !A
</PRE>
<P>Each A and B is a number or a variable reference like $a or ${abc},
or another Boolean expression.
</P>
<P>If a variable is used it must produce a number when evaluated and
substituted for in the expression, else an error will be generated.
</P>
<P>Expressions are evaluated left to right and have the usual C-style
precedence: the unary logical NOT operator "!" has the highest
precedence, the 4 relational operators "<", "<=", ">", and ">=" are
next; the two remaining relational operators "==" and "!=" are next;
then the logical AND operator "&&"; and finally the logical OR
operator "||" has the lowest precedence. Parenthesis can be used to
group one or more portions of an expression and/or enforce a different
order of evaluation than what would occur with the default precedence.
</P>
<P>The 6 relational operators return either a 1.0 or 0.0 depending on
whether the relationship between x and y is TRUE or FALSE. The
logical AND operator will return 1.0 if both its arguments are
non-zero, else it returns 0.0. The logical OR operator will return
1.0 if either of its arguments is non-zero, else it returns 0.0. The
logical NOT operator returns 1.0 if its argument is 0.0, else it
returns 0.0.
</P>
<P>The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "variable.html">variable</A>, <A HREF = "print.html">print</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/if.txt b/doc/if.txt
index a92b9213b..494021e4a 100644
--- a/doc/if.txt
+++ b/doc/if.txt
@@ -1,156 +1,156 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
if command :h3
[Syntax:]
if boolean then t1 t2 ... elif boolean f1 f2 ... elif boolean f1 f2 ... else e1 e2 ... :pre
boolean = a Boolean expression evaluated as TRUE or FALSE (see below)
then = required word
t1,t2,...,tN = one or more LAMMPS commands to execute if condition is met, each enclosed in quotes
elif = optional word, can appear multiple times
f1,f2,...,fN = one or more LAMMPS commands to execute if elif condition is met, each enclosed in quotes (optional arguments)
else = optional argument
e1,e2,...,eN = one or more LAMMPS commands to execute if no condition is met, each enclosed in quotes (optional arguments) :ul
[Examples:]
if "$\{steps\} > 1000" then exit
if "$x <= $y" then "print X is smaller = $x" else "print Y is smaller = $y"
if "($\{eng\} > 0.0) || ($n < 1000)" then &
"timestep 0.005" &
elif $n<10000 &
"timestep 0.01" &
else &
"timestep 0.02" &
"print 'Max step reached'"
if "$\{eng\} > $\{eng_previous\}" then "jump file1" else "jump file2" :pre
[Description:]
This command provides an in-then-else capability within an input
script. A Boolean expression is evaluted and the result is TRUE or
FALSE. Note that as in the examples above, the expression can contain
variables, as defined by the "variable"_variable.html command, which
will be evaluated as part of the expression. Thus a user-defined
formula that reflects the current state of the simulation can be used
to issue one or more new commands.
If the result of the Boolean expression is TRUE, then one or more
commands (t1, t2, ..., tN) are executed. If it is FALSE, then Boolean
expressions associated with successive elif keywords are evaluated
until one is found to be true, in which case its commands (f1, f2,
..., fN) are executed. If no Boolean expression is TRUE, then the
commands associated witht the else keyword, namely (e1, e2, ..., eN),
are executed. The elif and else keywords and their associated
commands are optional. If they aren't specified and the initial
Boolean expression is FALSE, then no commands are executed.
The syntax for Boolean expressions is described below.
Each command (t1, f1, e1, etc) can be any valid LAMMPS input script
command. If the command is more than one word, it must enclosed in
quotes, so it will be treated as a single argument, as in the examples
above.
IMPORTANT NOTE: If a command itself requires a quoted argument (e.g. a
"print"_print.html command), then double and single quotes can be used
and nested in the usual manner, as in the examples above and below.
-See "this section"_Section_commands.html#cmd_2 of the manual for more
-details on using quotes in arguments. Only one of level of nesting is
-allowed, but that should be sufficient for most use cases.
+See "Section_commands 2"_Section_commands.html#cmd_2 of the manual for
+more details on using quotes in arguments. Only one of level of
+nesting is allowed, but that should be sufficient for most use cases.
Note that by using the line continuation character "&", the if command
can be spread across many lines, though it is still a single command:
if "$a < $b" then &
"print 'Minimum value = $a'" &
"run 1000" &
else &
'print "Minimum value = $b"' &
"minimize 0.001 0.001 1000 10000" :pre
Note that if one of the commands to execute is an invalid LAMMPS
command, such as "exit" in the first example above, then executing the
command will cause LAMMPS to halt.
Note that by jumping to a label in the same input script, the if
command can be used to break out of a loop. See the "variable
delete"_variable.html command for info on how to delete the associated
loop variable, so that it can be re-used later in the input script.
Here is an example of a double loop which uses the if and
"jump"_jump.html commands to break out of the inner loop when a
condition is met, then continues iterating thru the outer loop.
label loopa
variable a loop 5
label loopb
variable b loop 5
print "A,B = $a,$b"
run 10000
if '$b > 2' then "print 'Jumping to another script'" "jump in.script break"
next b
jump in.script loopb
label break
variable b delete :pre
next a
jump in.script loopa :pre
:line
The Boolean expressions for the if and elif keywords have a C-like
syntax. Note that each expression is a single argument within the if
command. Thus if you want to include spaces in the expression for
clarity, you must enclose the entire expression in quotes.
An expression is built out of numbers:
0.2, 100, 1.0e20, -15.4, etc :pre
and Boolean operators:
A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, !A :pre
Each A and B is a number or a variable reference like $a or $\{abc\},
or another Boolean expression.
If a variable is used it must produce a number when evaluated and
substituted for in the expression, else an error will be generated.
Expressions are evaluated left to right and have the usual C-style
precedence: the unary logical NOT operator "!" has the highest
precedence, the 4 relational operators "<", "<=", ">", and ">=" are
next; the two remaining relational operators "==" and "!=" are next;
then the logical AND operator "&&"; and finally the logical OR
operator "||" has the lowest precedence. Parenthesis can be used to
group one or more portions of an expression and/or enforce a different
order of evaluation than what would occur with the default precedence.
The 6 relational operators return either a 1.0 or 0.0 depending on
whether the relationship between x and y is TRUE or FALSE. The
logical AND operator will return 1.0 if both its arguments are
non-zero, else it returns 0.0. The logical OR operator will return
1.0 if either of its arguments is non-zero, else it returns 0.0. The
logical NOT operator returns 1.0 if its argument is 0.0, else it
returns 0.0.
The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE.
:line
[Restrictions:] none
[Related commands:]
"variable"_variable.html, "print"_print.html
[Default:] none
diff --git a/doc/improper_class2.html b/doc/improper_class2.html
index 315163711..03cccdf6a 100644
--- a/doc/improper_class2.html
+++ b/doc/improper_class2.html
@@ -1,104 +1,130 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>improper_style class2 command
</H3>
+<H3>improper_style class2/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>improper_style class2
</PRE>
<P><B>Examples:</B>
</P>
<PRE>improper_style class2
improper_coeff 1 100.0 0
improper_coeff * aa 0.0 0.0 0.0 115.06 130.01 115.06
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>class2</I> improper style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/improper_class2.jpg">
</CENTER>
<P>where Ei is the improper term and Eaa is an angle-angle term. The 3 X
terms in Ei are an average over 3 out-of-plane angles.
</P>
<P>The 4 atoms in an improper quadruplet (listed in the data file read by
the <A HREF = "read_data.html">read_data</A> command) are ordered I,J,K,L. X_IJKL
refers to the angle between the plane of I,J,K and the plane of J,K,L,
and the bond JK lies in both planes. Similarly for X_KJLI and X_LJIK.
Note that atom J appears in the common bonds (JI, JK, JL) of all 3 X
terms. Thus J (the 2nd atom in the quadruplet) is the atom of
symmetry in the 3 X angles.
</P>
<P>The subscripts on the various theta's refer to different combinations
of 3 atoms (I,J,K,L) used to form a particular angle. E.g. Theta_IJL
is the angle formed by atoms I,J,L with J in the middle. Theta1,
theta2, theta3 are the equilibrium positions of those angles. Again,
atom J (the 2nd atom in the quadruplet) is the atom of symmetry in the
theta angles, since it is always the center atom.
</P>
<P>Since atom J is the atom of symmetry, normally the bonds J-I, J-K, J-L
would exist for an improper to be defined between the 4 atoms, but
this is not required.
</P>
<P>See <A HREF = "#Sun">(Sun)</A> for a description of the COMPASS class2 force field.
</P>
<P>Coefficients for the Ei and Eaa formulas must be defined for each
improper type via the <A HREF = "improper_coeff.html">improper_coeff</A> command as
in the example above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands.
</P>
<P>These are the 2 coefficients for the Ei formula:
</P>
<UL><LI>K (energy/radian^2)
<LI>X0 (degrees)
</UL>
<P>X0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
</P>
<P>For the Eaa formula, each line in a
<A HREF = "improper_coeff.html">improper_coeff</A> command in the input script lists
7 coefficients, the first of which is "aa" to indicate they are
AngleAngle coefficients. In a data file, these coefficients should be
listed under a "AngleAngle Coeffs" heading and you must leave out the
"aa", i.e. only list 6 coefficients after the improper type.
</P>
<UL><LI>aa
<LI>M1 (energy/distance)
<LI>M2 (energy/distance)
<LI>M3 (energy/distance)
<LI>theta1 (degrees)
<LI>theta2 (degrees)
<LI>theta3 (degrees)
</UL>
<P>The theta values are specified in degrees, but LAMMPS converts them to
radians internally; hence the units of M are in energy/radian^2.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This improper style can only be used if LAMMPS was built with the
CLASS2 package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "improper_coeff.html">improper_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Sun"></A>
<P><B>(Sun)</B> Sun, J Phys Chem B 102, 7338-7364 (1998).
</P>
</HTML>
diff --git a/doc/improper_class2.txt b/doc/improper_class2.txt
index 156d97fa8..f6d66b9c7 100644
--- a/doc/improper_class2.txt
+++ b/doc/improper_class2.txt
@@ -1,98 +1,123 @@
"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
improper_style class2 command :h3
+improper_style class2/omp command :h3
[Syntax:]
improper_style class2 :pre
[Examples:]
improper_style class2
improper_coeff 1 100.0 0
improper_coeff * aa 0.0 0.0 0.0 115.06 130.01 115.06 :pre
[Description:]
The {class2} improper style uses the potential
:c,image(Eqs/improper_class2.jpg)
where Ei is the improper term and Eaa is an angle-angle term. The 3 X
terms in Ei are an average over 3 out-of-plane angles.
The 4 atoms in an improper quadruplet (listed in the data file read by
the "read_data"_read_data.html command) are ordered I,J,K,L. X_IJKL
refers to the angle between the plane of I,J,K and the plane of J,K,L,
and the bond JK lies in both planes. Similarly for X_KJLI and X_LJIK.
Note that atom J appears in the common bonds (JI, JK, JL) of all 3 X
terms. Thus J (the 2nd atom in the quadruplet) is the atom of
symmetry in the 3 X angles.
The subscripts on the various theta's refer to different combinations
of 3 atoms (I,J,K,L) used to form a particular angle. E.g. Theta_IJL
is the angle formed by atoms I,J,L with J in the middle. Theta1,
theta2, theta3 are the equilibrium positions of those angles. Again,
atom J (the 2nd atom in the quadruplet) is the atom of symmetry in the
theta angles, since it is always the center atom.
Since atom J is the atom of symmetry, normally the bonds J-I, J-K, J-L
would exist for an improper to be defined between the 4 atoms, but
this is not required.
See "(Sun)"_#Sun for a description of the COMPASS class2 force field.
Coefficients for the Ei and Eaa formulas must be defined for each
improper type via the "improper_coeff"_improper_coeff.html command as
in the example above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands.
These are the 2 coefficients for the Ei formula:
K (energy/radian^2)
X0 (degrees) :ul
X0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
For the Eaa formula, each line in a
"improper_coeff"_improper_coeff.html command in the input script lists
7 coefficients, the first of which is "aa" to indicate they are
AngleAngle coefficients. In a data file, these coefficients should be
listed under a "AngleAngle Coeffs" heading and you must leave out the
"aa", i.e. only list 6 coefficients after the improper type.
aa
M1 (energy/distance)
M2 (energy/distance)
M3 (energy/distance)
theta1 (degrees)
theta2 (degrees)
theta3 (degrees) :ul
The theta values are specified in degrees, but LAMMPS converts them to
radians internally; hence the units of M are in energy/radian^2.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This improper style can only be used if LAMMPS was built with the
CLASS2 package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
[Related commands:]
"improper_coeff"_improper_coeff.html
[Default:] none
:line
:link(Sun)
[(Sun)] Sun, J Phys Chem B 102, 7338-7364 (1998).
diff --git a/doc/improper_cvff.html b/doc/improper_cvff.html
index 9c8a3e97a..211b33f1d 100644
--- a/doc/improper_cvff.html
+++ b/doc/improper_cvff.html
@@ -1,68 +1,94 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>improper_style cvff command
</H3>
+<H3>improper_style cvff/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>improper_style cvff
</PRE>
<P><B>Examples:</B>
</P>
<PRE>improper_style cvff
improper_coeff 1 80.0 -1 4
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>cvff</I> improper style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/improper_cvff.jpg">
</CENTER>
<P>where phi is the Wilson out-of-plane angle.
</P>
<P>If the 4 atoms in an improper quadruplet (listed in the data file read
by the <A HREF = "read_data.html">read_data</A> command) are ordered I,J,K,L then
the Wilson angle is between the plane of I,J,K and the plane of J,K,L.
This is essentially a dihedral angle, which is why the formula for
this improper style is the same as for <A HREF = "dihedral_harmonic.html">dihedral_style
harmonic</A>. Alternatively, you can think of
atoms J,K,L as being in a plane, and atom I above the plane, and the
Wilson angle as a measure of how far out-of-plane I is with respect to
the other 3 atoms.
</P>
<P>Note that defining 4 atoms to interact in this way, does not mean that
bonds necessarily exist between I-J, J-K, or K-L, as they would in a
linear dihedral. Normally, the bonds I-J, I-K, I-L would exist for an
improper to be defined between the 4 atoms.
</P>
<P>The following coefficients must be defined for each improper type via
the <A HREF = "improper_coeff.html">improper_coeff</A> command as in the example
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>K (energy)
<LI>d (+1 or -1)
<LI>n (0,1,2,3,4,6)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "improper_coeff.html">improper_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/improper_cvff.txt b/doc/improper_cvff.txt
index 79df38298..94736d3cd 100644
--- a/doc/improper_cvff.txt
+++ b/doc/improper_cvff.txt
@@ -1,63 +1,88 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
improper_style cvff command :h3
+improper_style cvff/omp command :h3
[Syntax:]
improper_style cvff :pre
[Examples:]
improper_style cvff
improper_coeff 1 80.0 -1 4 :pre
[Description:]
The {cvff} improper style uses the potential
:c,image(Eqs/improper_cvff.jpg)
where phi is the Wilson out-of-plane angle.
If the 4 atoms in an improper quadruplet (listed in the data file read
by the "read_data"_read_data.html command) are ordered I,J,K,L then
the Wilson angle is between the plane of I,J,K and the plane of J,K,L.
This is essentially a dihedral angle, which is why the formula for
this improper style is the same as for "dihedral_style
harmonic"_dihedral_harmonic.html. Alternatively, you can think of
atoms J,K,L as being in a plane, and atom I above the plane, and the
Wilson angle as a measure of how far out-of-plane I is with respect to
the other 3 atoms.
Note that defining 4 atoms to interact in this way, does not mean that
bonds necessarily exist between I-J, J-K, or K-L, as they would in a
linear dihedral. Normally, the bonds I-J, I-K, I-L would exist for an
improper to be defined between the 4 atoms.
The following coefficients must be defined for each improper type via
the "improper_coeff"_improper_coeff.html command as in the example
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
K (energy)
d (+1 or -1)
n (0,1,2,3,4,6) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"improper_coeff"_improper_coeff.html
[Default:] none
diff --git a/doc/improper_harmonic.html b/doc/improper_harmonic.html
index 9ba2e9cce..075a1c141 100644
--- a/doc/improper_harmonic.html
+++ b/doc/improper_harmonic.html
@@ -1,68 +1,94 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>improper_style harmonic command
</H3>
+<H3>improper_style harmonic/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>improper_style harmonic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>improper_style harmonic
improper_coeff 1 100.0 0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>harmonic</I> improper style uses the potential
</P>
<CENTER><IMG SRC = "Eqs/improper_harmonic.jpg">
</CENTER>
<P>where X is the improper angle, X0 is its equilibrium value, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
</P>
<P>If the 4 atoms in an improper quadruplet (listed in the data file read
by the <A HREF = "read_data.html">read_data</A> command) are ordered I,J,K,L then X
is the angle between the plane of I,J,K and the plane of J,K,L.
Alternatively, you can think of atoms J,K,L as being in a plane, and
atom I above the plane, and X as a measure of how far out-of-plane I
is with respect to the other 3 atoms.
</P>
<P>Note that defining 4 atoms to interact in this way, does not mean that
bonds necessarily exist between I-J, J-K, or K-L, as they would in a
linear dihedral. Normally, the bonds I-J, I-K, I-L would exist for an
improper to be defined between the 4 atoms.
</P>
<P>The following coefficients must be defined for each improper type via
the <A HREF = "improper_coeff.html">improper_coeff</A> command as in the example
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>K (energy/radian^2)
<LI>X0 (degrees)
</UL>
<P>X0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "improper_coeff.html">improper_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/improper_harmonic.txt b/doc/improper_harmonic.txt
index e57ad4130..9a0312990 100644
--- a/doc/improper_harmonic.txt
+++ b/doc/improper_harmonic.txt
@@ -1,63 +1,88 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
improper_style harmonic command :h3
+improper_style harmonic/omp command :h3
[Syntax:]
improper_style harmonic :pre
[Examples:]
improper_style harmonic
improper_coeff 1 100.0 0 :pre
[Description:]
The {harmonic} improper style uses the potential
:c,image(Eqs/improper_harmonic.jpg)
where X is the improper angle, X0 is its equilibrium value, and K is a
prefactor. Note that the usual 1/2 factor is included in K.
If the 4 atoms in an improper quadruplet (listed in the data file read
by the "read_data"_read_data.html command) are ordered I,J,K,L then X
is the angle between the plane of I,J,K and the plane of J,K,L.
Alternatively, you can think of atoms J,K,L as being in a plane, and
atom I above the plane, and X as a measure of how far out-of-plane I
is with respect to the other 3 atoms.
Note that defining 4 atoms to interact in this way, does not mean that
bonds necessarily exist between I-J, J-K, or K-L, as they would in a
linear dihedral. Normally, the bonds I-J, I-K, I-L would exist for an
improper to be defined between the 4 atoms.
The following coefficients must be defined for each improper type via
the "improper_coeff"_improper_coeff.html command as in the example
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
K (energy/radian^2)
X0 (degrees) :ul
X0 is specified in degrees, but LAMMPS converts it to radians
internally; hence the units of K are in energy/radian^2.
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"improper_coeff"_improper_coeff.html
[Default:] none
diff --git a/doc/improper_umbrella.html b/doc/improper_umbrella.html
index 2f10f5da9..8c74bad45 100644
--- a/doc/improper_umbrella.html
+++ b/doc/improper_umbrella.html
@@ -1,70 +1,96 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>improper_style umbrella command
</H3>
+<H3>improper_style umbrella/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>improper_style umbrella
</PRE>
<P><B>Examples:</B>
</P>
<PRE>improper_style umbrella
improper_coeff 1 100.0 180.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>umbrella</I> improper style uses the following potential, which is
commonly referred to as a classic inversion and used in the
<A HREF = "Section_howto.html#howto_4">DREIDING</A> force field:
</P>
<CENTER><IMG SRC = "Eqs/improper_umbrella.jpg">
</CENTER>
<P>where K is the force constant and omega is the angle between the IL
axis and the IJK plane:
</P>
<CENTER><IMG SRC = "Eqs/umbrella.jpg">
</CENTER>
<P>If omega0 = 0 the potential term has a minimum for the planar
structure. Otherwise it has two minima at +/- omega0, with a barrier
in between.
</P>
<P>See <A HREF = "#Mayo">(Mayo)</A> for a description of the DREIDING force field.
</P>
<P>The following coefficients must be defined for each improper type via
the <A HREF = "improper_coeff.html">improper_coeff</A> command as in the example
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>K (energy)
<LI>omega0 (degrees)
</UL>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "improper_coeff.html">improper_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Mayo"></A>
<P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990),
</P>
</HTML>
diff --git a/doc/improper_umbrella.txt b/doc/improper_umbrella.txt
index 31a7729a6..d5e178ff9 100644
--- a/doc/improper_umbrella.txt
+++ b/doc/improper_umbrella.txt
@@ -1,64 +1,89 @@
"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
improper_style umbrella command :h3
+improper_style umbrella/omp command :h3
[Syntax:]
improper_style umbrella :pre
[Examples:]
improper_style umbrella
improper_coeff 1 100.0 180.0 :pre
[Description:]
The {umbrella} improper style uses the following potential, which is
commonly referred to as a classic inversion and used in the
"DREIDING"_Section_howto.html#howto_4 force field:
:c,image(Eqs/improper_umbrella.jpg)
where K is the force constant and omega is the angle between the IL
axis and the IJK plane:
:c,image(Eqs/umbrella.jpg)
If omega0 = 0 the potential term has a minimum for the planar
structure. Otherwise it has two minima at +/- omega0, with a barrier
in between.
See "(Mayo)"_#Mayo for a description of the DREIDING force field.
The following coefficients must be defined for each improper type via
the "improper_coeff"_improper_coeff.html command as in the example
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
K (energy)
omega0 (degrees) :ul
+:line
+
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Restrictions:]
This improper style can only be used if LAMMPS was built with the
MOLECULAR package (which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
[Related commands:]
"improper_coeff"_improper_coeff.html
[Default:] none
:line
:link(Mayo)
[(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990),
diff --git a/doc/kspace_style.html b/doc/kspace_style.html
index 018a24053..5d6c200f5 100644
--- a/doc/kspace_style.html
+++ b/doc/kspace_style.html
@@ -1,189 +1,205 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>kspace_style command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>kspace_style style value
</PRE>
-<UL><LI>style = <I>none</I> or <I>ewald</I> or <I>pppm</I> or <I>pppm/cg</I> or <I>pppm/tip4p</I> or <I>ewald/n</I> or <I>pppm/gpu</I>
+<UL><LI>style = <I>none</I> or <I>ewald</I> or <I>pppm</I> or <I>pppm/cg</I> or <I>pppm/tip4p</I> or <I>ewald/n</I> or <I>pppm/gpu</I> or <I>ewald/omp</I> or <I>pppm/omp</I> or <I>pppm/proxy</I>
<PRE> <I>none</I> value = none
<I>ewald</I> value = precision
precision = desired accuracy
<I>pppm</I> value = precision
precision = desired accuracy
<I>pppm/cg</I> value = precision (smallq)
precision = desired accuracy
smallq = cutoff for charges to be considered (optional) (charge units)
<I>pppm/tip4p</I> value = precision
precision = desired accuracy
<I>ewald/n</I> value = precision
precision = desired accuracy
<I>pppm/gpu</I> value = precision
+ precision = desired accuracy
+ <I>ewald/omp</I> value = precision
+ precision = desired accuracy
+ <I>pppm/omp</I> value = precision
+ precision = desired accuracy
+ <I>pppm/proxy</I> value = precision
precision = desired accuracy
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>kspace_style pppm 1.0e-4
kspace_style pppm/cg 1.0e-5 1.0e-6
kspace_style none
</PRE>
<P><B>Description:</B>
</P>
<P>Define a K-space solver for LAMMPS to use each timestep to compute
long-range Coulombic interactions or long-range 1/r^N interactions.
When such a solver is used in conjunction with an appropriate pair
style, the cutoff for Coulombic or other 1/r^N interactions is
effectively infinite; each charge in the system interacts with charges
in an infinite array of periodic images of the simulation domain.
</P>
<P>The <I>ewald</I> style performs a standard Ewald summation as described in
any solid-state physics text.
</P>
<P>The <I>pppm</I> style invokes a particle-particle particle-mesh solver
<A HREF = "#Hockney">(Hockney)</A> which maps atom charge to a 3d mesh, uses 3d FFTs
to solve Poisson's equation on the mesh, then interpolates electric
fields on the mesh points back to the atoms. It is closely related to
the particle-mesh Ewald technique (PME) <A HREF = "#Darden">(Darden)</A> used in
AMBER and CHARMM. The cost of traditional Ewald summation scales as
N^(3/2) where N is the number of atoms in the system. The PPPM solver
scales as Nlog(N) due to the FFTs, so it is almost always a faster
choice <A HREF = "#Pollock">(Pollock)</A>.
</P>
<P>The <I>pppm/cg</I> style is identical to the <I>pppm</I> style except that it
has an optimization for systems where most particles are uncharged.
The optional <I>smallq</I> argument defines the cutoff for the absolute
charge value which determines whether a particle is considered charged
or not. Its default value is 1.0e-5.
</P>
<P>The <I>pppm/tip4p</I> style is identical to the <I>pppm</I> style except that it
adds a charge at the massless 4th site in each TIP4P water molecule.
It should be used with <A HREF = "pair_style.html">pair styles</A> with a
<I>long/tip4p</I> in their style name.
</P>
<P>The <I>ewald/n</I> style augments <I>ewald</I> by adding long-range dispersion
sum capabilities for 1/r^N potentials and is useful for simulation of
interfaces <A HREF = "#Veld">(Veld)</A>. It also performs standard coulombic Ewald
summations, but in a more efficient manner than the <I>ewald</I> style.
The 1/r^N capability means that Lennard-Jones or Buckingham potentials
can be used with <I>ewald/n</I> without a cutoff, i.e. they become full
long-range potentials.
</P>
<P>Currently, only the <I>ewald/n</I> style can be used with non-orthogonal
(triclinic symmetry) simulation boxes.
</P>
+<P>The <I>pppm/proxy</I> style is a special variant for calculations
+in hybrid OpenMP/MPI parallel mode. It is functionally equivalent
+with <I>pppm</I>, but it its force computation is being executed
+as a single thread concurrently with a multi-threaded non-bonded
+calculation for a pair style with <I>pppm/omp</I> suffix. For calcuations
+across many multi-core nodes, this can have a performance benefit
+over performing the real and reciprocal space part separately,
+specifically when otherwise the time spent on the pair style
+would slightly less than in <I>pppm</I> without threading.
+</P>
<P>Note that the PPPM styles can be used with single-precision FFTs by
using the compiler switch -DFFT_SINGLE for the FFT_INC setting in your
lo-level Makefile. This setting also changes some of the PPPM
operations (e.g. mapping charge to mesh and interpolating electric
fields to particles) to be performed in single precision. This option
can speed-up long-range calulations, particularly in parallel or on
GPUs. The use of the -DFFT_SINGLE flag is discussed in <A HREF = "Section_start.html#start_2_4">this
section</A> of the manual.
</P>
<HR>
<P>When a kspace style is used, a pair style that includes the
short-range correction to the pairwise Coulombic or other 1/r^N forces
must also be selected. For Coulombic interactions, these styles are
ones that have a <I>coul/long</I> in their style name. For 1/r^6
dispersion forces in a Lennard-Jones or Buckingham potential, see the
<A HREF = "pair_lj_coul.html">pair_style lj/coul</A> or <A HREF = "pair_buck_coul.html">pair_style
buck/coul</A> commands.
</P>
<P>A precision value of 1.0e-4 means one part in 10000. This setting is
used in conjunction with the pairwise cutoff to determine the number
of K-space vectors for style <I>ewald</I> or the FFT grid size for style
<I>pppm</I>.
</P>
<P>See the <A HREF = "kspace_modify.html">kspace_modify</A> command for additional
options of the K-space solvers that can be set.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, or <I>opt</I> suffix are
-functionally the same as the corresponding style without the suffix.
-They have been optimized to run faster, depending on your available
-hardware, as discussed in <A HREF = "Section_accelerate.html">this section</A> of
-the manual. The accelerated styles take the same arguments and should
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
produce the same results, except for round-off and precision issues.
</P>
<P>More specifically, the <I>pppm/gpu</I> style performs charge assignment and
force interpolation calculations on the GPU. These processes are
performed either in single or double precision, depending on whether
the -DFFT_SINGLE setting was specified in your lo-level Makefile, as
discussed above. The FFTs themselves are still calculated on the CPU.
If <I>pppm/gpu</I> is used with a GPU-enabled pair style, part of the PPPM
calculation can be performed concurrently on the GPU while other
calculations for non-bonded and bonded force calculation are performed
on the CPU.
</P>
-<P>These accelerated styles are part of the USER-CUDA, GPU, and OPT
-packages respectively. They are only enabled if LAMMPS was built with
-those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP, and
+OPT packages respectively. They are only enabled if LAMMPS was built
+with those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<P><B>Restrictions:</B>
</P>
<P>A simulation must be 3d and periodic in all dimensions to use an Ewald
or PPPM solver. The only exception is if the slab option is set with
<A HREF = "kspace_modify.html">kspace_modify</A>, in which case the xy dimensions
must be periodic and the z dimension must be non-periodic.
</P>
<P>Kspace styles are part of the KSPACE package. They are only enabled
if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The <I>ewald/n</I> style is part of the USER-EWALDN package. It is only
enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>When using a long-range pairwise TIP4P potential, you must use kspace
style <I>pppm/tip4p</I> and vice versa.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "kspace_modify.html">kspace_modify</A>, <A HREF = "pair_lj.html">pair_style
lj/cut/coul/long</A>, <A HREF = "pair_charmm.html">pair_style
lj/charmm/coul/long</A>, <A HREF = "pair_lj_coul.html">pair_style
lj/coul</A>, <A HREF = "pair_buck.html">pair_style buck/coul/long</A>
</P>
<P><B>Default:</B>
</P>
<PRE>kspace_style none
</PRE>
<HR>
<A NAME = "Darden"></A>
<P><B>(Darden)</B> Darden, York, Pedersen, J Chem Phys, 98, 10089 (1993).
</P>
<A NAME = "Hockney"></A>
<P><B>(Hockney)</B> Hockney and Eastwood, Computer Simulation Using Particles,
Adam Hilger, NY (1989).
</P>
<A NAME = "Pollock"></A>
<P><B>(Pollock)</B> Pollock and Glosli, Comp Phys Comm, 95, 93 (1996).
</P>
<A NAME = "Veld"></A>
<P><B>(Veld)</B> In 't Veld, Ismail, Grest, J Chem Phys, in press (2007).
</P>
</HTML>
diff --git a/doc/kspace_style.txt b/doc/kspace_style.txt
index 21992d07a..d13dbf68d 100644
--- a/doc/kspace_style.txt
+++ b/doc/kspace_style.txt
@@ -1,178 +1,194 @@
"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
kspace_style command :h3
[Syntax:]
kspace_style style value :pre
-style = {none} or {ewald} or {pppm} or {pppm/cg} or {pppm/tip4p} or {ewald/n} or {pppm/gpu} :ulb,l
+style = {none} or {ewald} or {pppm} or {pppm/cg} or {pppm/tip4p} or {ewald/n} or {pppm/gpu} or {ewald/omp} or {pppm/omp} or {pppm/proxy} :ulb,l
{none} value = none
{ewald} value = precision
precision = desired accuracy
{pppm} value = precision
precision = desired accuracy
{pppm/cg} value = precision (smallq)
precision = desired accuracy
smallq = cutoff for charges to be considered (optional) (charge units)
{pppm/tip4p} value = precision
precision = desired accuracy
{ewald/n} value = precision
precision = desired accuracy
{pppm/gpu} value = precision
+ precision = desired accuracy
+ {ewald/omp} value = precision
+ precision = desired accuracy
+ {pppm/omp} value = precision
+ precision = desired accuracy
+ {pppm/proxy} value = precision
precision = desired accuracy :pre
:ule
[Examples:]
kspace_style pppm 1.0e-4
kspace_style pppm/cg 1.0e-5 1.0e-6
kspace_style none :pre
[Description:]
Define a K-space solver for LAMMPS to use each timestep to compute
long-range Coulombic interactions or long-range 1/r^N interactions.
When such a solver is used in conjunction with an appropriate pair
style, the cutoff for Coulombic or other 1/r^N interactions is
effectively infinite; each charge in the system interacts with charges
in an infinite array of periodic images of the simulation domain.
The {ewald} style performs a standard Ewald summation as described in
any solid-state physics text.
The {pppm} style invokes a particle-particle particle-mesh solver
"(Hockney)"_#Hockney which maps atom charge to a 3d mesh, uses 3d FFTs
to solve Poisson's equation on the mesh, then interpolates electric
fields on the mesh points back to the atoms. It is closely related to
the particle-mesh Ewald technique (PME) "(Darden)"_#Darden used in
AMBER and CHARMM. The cost of traditional Ewald summation scales as
N^(3/2) where N is the number of atoms in the system. The PPPM solver
scales as Nlog(N) due to the FFTs, so it is almost always a faster
choice "(Pollock)"_#Pollock.
The {pppm/cg} style is identical to the {pppm} style except that it
has an optimization for systems where most particles are uncharged.
The optional {smallq} argument defines the cutoff for the absolute
charge value which determines whether a particle is considered charged
or not. Its default value is 1.0e-5.
The {pppm/tip4p} style is identical to the {pppm} style except that it
adds a charge at the massless 4th site in each TIP4P water molecule.
It should be used with "pair styles"_pair_style.html with a
{long/tip4p} in their style name.
The {ewald/n} style augments {ewald} by adding long-range dispersion
sum capabilities for 1/r^N potentials and is useful for simulation of
interfaces "(Veld)"_#Veld. It also performs standard coulombic Ewald
summations, but in a more efficient manner than the {ewald} style.
The 1/r^N capability means that Lennard-Jones or Buckingham potentials
can be used with {ewald/n} without a cutoff, i.e. they become full
long-range potentials.
Currently, only the {ewald/n} style can be used with non-orthogonal
(triclinic symmetry) simulation boxes.
+The {pppm/proxy} style is a special variant for calculations
+in hybrid OpenMP/MPI parallel mode. It is functionally equivalent
+with {pppm}, but it its force computation is being executed
+as a single thread concurrently with a multi-threaded non-bonded
+calculation for a pair style with {pppm/omp} suffix. For calcuations
+across many multi-core nodes, this can have a performance benefit
+over performing the real and reciprocal space part separately,
+specifically when otherwise the time spent on the pair style
+would slightly less than in {pppm} without threading.
+
Note that the PPPM styles can be used with single-precision FFTs by
using the compiler switch -DFFT_SINGLE for the FFT_INC setting in your
lo-level Makefile. This setting also changes some of the PPPM
operations (e.g. mapping charge to mesh and interpolating electric
fields to particles) to be performed in single precision. This option
can speed-up long-range calulations, particularly in parallel or on
GPUs. The use of the -DFFT_SINGLE flag is discussed in "this
section"_Section_start.html#start_2_4 of the manual.
:line
When a kspace style is used, a pair style that includes the
short-range correction to the pairwise Coulombic or other 1/r^N forces
must also be selected. For Coulombic interactions, these styles are
ones that have a {coul/long} in their style name. For 1/r^6
dispersion forces in a Lennard-Jones or Buckingham potential, see the
"pair_style lj/coul"_pair_lj_coul.html or "pair_style
buck/coul"_pair_buck_coul.html commands.
A precision value of 1.0e-4 means one part in 10000. This setting is
used in conjunction with the pairwise cutoff to determine the number
of K-space vectors for style {ewald} or the FFT grid size for style
{pppm}.
See the "kspace_modify"_kspace_modify.html command for additional
options of the K-space solvers that can be set.
:line
-Styles with a {cuda}, {gpu}, or {opt} suffix are
-functionally the same as the corresponding style without the suffix.
-They have been optimized to run faster, depending on your available
-hardware, as discussed in "this section"_Section_accelerate.html of
-the manual. The accelerated styles take the same arguments and should
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
produce the same results, except for round-off and precision issues.
More specifically, the {pppm/gpu} style performs charge assignment and
force interpolation calculations on the GPU. These processes are
performed either in single or double precision, depending on whether
the -DFFT_SINGLE setting was specified in your lo-level Makefile, as
discussed above. The FFTs themselves are still calculated on the CPU.
If {pppm/gpu} is used with a GPU-enabled pair style, part of the PPPM
calculation can be performed concurrently on the GPU while other
calculations for non-bonded and bonded force calculation are performed
on the CPU.
-These accelerated styles are part of the USER-CUDA, GPU, and OPT
-packages respectively. They are only enabled if LAMMPS was built with
-those packages. See the "Making LAMMPS"_Section_start.html#start_3
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP, and
+OPT packages respectively. They are only enabled if LAMMPS was built
+with those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
[Restrictions:]
A simulation must be 3d and periodic in all dimensions to use an Ewald
or PPPM solver. The only exception is if the slab option is set with
"kspace_modify"_kspace_modify.html, in which case the xy dimensions
must be periodic and the z dimension must be non-periodic.
Kspace styles are part of the KSPACE package. They are only enabled
if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The {ewald/n} style is part of the USER-EWALDN package. It is only
enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
When using a long-range pairwise TIP4P potential, you must use kspace
style {pppm/tip4p} and vice versa.
[Related commands:]
"kspace_modify"_kspace_modify.html, "pair_style
lj/cut/coul/long"_pair_lj.html, "pair_style
lj/charmm/coul/long"_pair_charmm.html, "pair_style
lj/coul"_pair_lj_coul.html, "pair_style buck/coul/long"_pair_buck.html
[Default:]
kspace_style none :pre
:line
:link(Darden)
[(Darden)] Darden, York, Pedersen, J Chem Phys, 98, 10089 (1993).
:link(Hockney)
[(Hockney)] Hockney and Eastwood, Computer Simulation Using Particles,
Adam Hilger, NY (1989).
:link(Pollock)
[(Pollock)] Pollock and Glosli, Comp Phys Comm, 95, 93 (1996).
:link(Veld)
[(Veld)] In 't Veld, Ismail, Grest, J Chem Phys, in press (2007).
diff --git a/doc/log.html b/doc/log.html
index 2edfe3fcd..10db3c0b4 100644
--- a/doc/log.html
+++ b/doc/log.html
@@ -1,47 +1,47 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>log command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>log file
</PRE>
<UL><LI>file = name of new logfile
</UL>
<P><B>Examples:</B>
</P>
<PRE>log log.equil
</PRE>
<P><B>Description:</B>
</P>
<P>This command closes the current LAMMPS log file, opens a new file with
the specified name, and begins logging information to it. If the
specified file name is <I>none</I>, then no new log file is opened.
</P>
<P>If multiple processor partitions are being used, the file name should
be a variable, so that different processors do not attempt to write to
the same log file.
</P>
<P>The file "log.lammps" is the default log file for a LAMMPS run. The
name of the initial log file can also be set by the command-line
-switch -log. See <A HREF = "Section_start.html#start_6">this section</A> for
+switch -log. See <A HREF = "Section_start.html#start_6">Section_start 6</A> for
details.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B> none
</P>
<P><B>Default:</B>
</P>
<P>The default LAMMPS log file is named log.lammps
</P>
</HTML>
diff --git a/doc/log.txt b/doc/log.txt
index dc56bfcb6..bfd4462c4 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,42 +1,42 @@
"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
log command :h3
[Syntax:]
log file :pre
file = name of new logfile :ul
[Examples:]
log log.equil :pre
[Description:]
This command closes the current LAMMPS log file, opens a new file with
the specified name, and begins logging information to it. If the
specified file name is {none}, then no new log file is opened.
If multiple processor partitions are being used, the file name should
be a variable, so that different processors do not attempt to write to
the same log file.
The file "log.lammps" is the default log file for a LAMMPS run. The
name of the initial log file can also be set by the command-line
-switch -log. See "this section"_Section_start.html#start_6 for
+switch -log. See "Section_start 6"_Section_start.html#start_6 for
details.
[Restrictions:] none
[Related commands:] none
[Default:]
The default LAMMPS log file is named log.lammps
diff --git a/doc/neb.html b/doc/neb.html
index 25cc68b64..654953808 100644
--- a/doc/neb.html
+++ b/doc/neb.html
@@ -1,333 +1,333 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>neb command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>neb etol ftol N1 N2 Nevery filename
</PRE>
<UL><LI>etol = stopping tolerance for energy (energy units)
<LI>ftol = stopping tolerance for force (force units)
<LI>N1 = max # of iterations (timesteps) to run initial NEB
<LI>N2 = max # of iterations (timesteps) to run barrier-climbing NEB
<LI>Nevery = print replica energies and reaction coordinates every this many timesteps
<LI>filename = file specifying final atom coordinates on other side of barrier
</UL>
<P><B>Examples:</B>
</P>
<PRE>neb 0.1 0.0 1000 500 50 coords.final
neb 0.0 0.001 1000 500 50 coords.final
</PRE>
<P><B>Description:</B>
</P>
<P>Perform a nudged elastic band (NEB) calculation using multiple
replicas of a system. Two or more replicas must be used, two of which
are the end points of the transition path.
</P>
<P>NEB is a method for finding both the atomic configurations and height
of the energy barrier associated with a transition state, e.g. for an
atom to perform a diffusive hop from one energy basin to another in a
coordinated fashion with its neighbors. The implementation in LAMMPS
follows the discussion in these 3 papers: <A HREF = "#Henkelman1">(Henkelman1)</A>,
<A HREF = "#Henkelman2">(Henkelman2)</A>, and <A HREF = "#Nakano">(Nakano)</A>.
</P>
<P>Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see <A HREF = "Section_start.html#start_6">this section</A> of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. You will simply not get the performance speed-up you
+switch; see <A HREF = "Section_start.html#start_6">Section_start 6</A> of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. You will simply not get the performance speed-up you
would see with one or more physical processors per replica. See <A HREF = "Section_howto.html#howto_5">this
section</A> of the manual for further
discussion.
</P>
<P>NOTE: The current NEB implementation in LAMMPS restricts you to having
exactly one processor per replica.
</P>
<P>When a NEB calculation is performed, it is assumed that each replica
is running the same model, though LAMMPS does not check for this.
I.e. the simulation domain, the number of atoms, the interaction
potentials, and the starting configuration when the neb command is
issued should be the same for every replica.
</P>
<P>In a NEB calculation each atom in a replica is connected to the same
atom in adjacent replicas by springs, which induce inter-replica
forces. These forces are imposed by the <A HREF = "fix_neb.html">fix neb</A>
command, which must be used in conjunction with the neb command. The
group used to define the fix neb command specifies which atoms the
inter-replica springs are applied to. These are the NEB atoms.
Additional atoms can be present in your system, e.g. to provide a
background force field or simply to hold fixed during the NEB
procedure, but they will not be part of the barrier finding procedure.
</P>
<P>The "starting configuration" for NEB should be a state with the NEB
atoms (and all other atoms) having coordinates on one side of the
energy barrier. These coordinates will be assigned to the first
replica #1. The coordinates should be close to a local energy
minimum. A perfect energy minimum is not required, since NEB runs via
damped dynamics which will tend to drive the configuration of replica
#1 to a true energy minimum, but you will typically get better
convergence if the initial state is already at a minimum. For
example, for a system with a free surface, the surface should be fully
relaxed before attempting a NEB calculation.
</P>
<P>The final configuration is specified in the input <I>filename</I>, which is
formatted as described below. Only coordinates for NEB atoms or a
subset of them should be listed in the file; they represent the state
of the system on the other side of the barrier, at or near an energy
minimum. These coordinates will be assigned to the last replica #M.
The final coordinates of atoms not listed in <I>filename</I> are set equal
to their initial coordinates. Again, a perfect energy minimum is not
required for the final configuration, since the atoms in replica #M
will tend to move during the NEB procedure to the nearest energy
minimum. Also note that a final coordinate does not need to be
specified for a NEB atom if you expect it to only displace slightly
during the NEB procedure. For example, only the final coordinate of
the single atom diffusing into a vacancy need be specified if the
surrounding atoms will only relax slightly in the final configuration.
</P>
<P>The initial coordinates of all atoms (not just NEB atoms) in the
intermediate replicas #2,#3,...,#M-1 are set to values linearly
interpolated between the corresponding atoms in replicas #1 and #M.
</P>
<P>A NEB calculation has two stages, each of which is a minimization
procedure, performed via damped dynamics. To enable this, you must
first define an appropriate <A HREF = "min_style.html">min_style</A>, such as
<I>quickmin</I> or <I>fire</I>. The <I>cg</I>, <I>sd</I>, and <I>hftn</I> styles cannot be
used, since they perform iterative line searches in their inner loop,
which cannot be easily synchronized across multiple replicas.
</P>
<P>The minimizer tolerances for energy and force are set by <I>etol</I> and <I>ftol</I>,
the same as for
the <A HREF = "minimize.html">minimize</A> command.
</P>
<P>A non-zero <I>etol</I>
means that the NEB calculation will terminate if the energy criterion is met
by every replica. The energies being compared to
<I>etol</I> do not include any contribution from the inter-replica forces, since
these are non-conservative.
A non-zero <I>ftol</I>
means that the NEB calculation will terminate if the force criterion is met
by every replica. The forces being compared to
<I>ftol</I> include the inter-replica forces between an atom and its images
in adjacent replicas.
</P>
<P>The maximum number of iterations in each stage is set by <I>N1</I> and
<I>N2</I>. These are effectively timestep counts since each iteration of
damped dynamics is like a single timestep in a dynamics
<A HREF = "run.html">run</A>. During both stages, the potential energy of each
replica and its normalized distance along the reaction path (reaction
coordinate RD) will be printed to the screen and log file every
<I>Nevery</I> timesteps. The RD is 0 and 1 for the first and last replica.
For intermediate replicas, it is the cumulative distance (normalized
by the total cumulative distance) between adjacent replicas, where
"distance" is defined as the length of the 3N-vector of differences in
atomic coordinates, where N is the number of NEB atoms involved in the
transition. These outputs allow you to monitor NEB's progress in
finding a good energy barrier. <I>N1</I> and <I>N2</I> must both be multiples
of <I>Nevery</I>.
</P>
<P>In the first stage of NEB, the set of replicas should converge toward
the minimum energy path (MEP) of conformational states that transition
over the barrier. The MEP for a barrier is defined as a sequence of
3N-dimensional states that cross the barrier at its saddle point, each
of which has a potential energy gradient parallel to the MEP itself.
The replica states will also be roughly equally spaced along the MEP
due to the inter-replica spring force added by the <A HREF = "fix_neb.html">fix
neb</A> command.
</P>
<P>In the second stage of NEB, the replica with the highest energy
is selected and the inter-replica forces on it are converted to a
force that drives its atom coordinates to the top or saddle point of
the barrier, via the barrier-climbing calculation described in
<A HREF = "#Hinkelman2">(Henkelman2)</A>. As before, the other replicas rearrange
themselves along the MEP so as to be roughly equally spaced.
</P>
<P>When both stages are complete, if the NEB calculation was successful,
one of the replicas should be an atomic configuration at the top or
saddle point of the barrier, the potential energies for the set of
replicas should represent the energy profile of the barrier along the
MEP, and the configurations of the replicas should be a sequence of
configurations along the MEP.
</P>
<HR>
<P>A few other settings in your input script are required or advised to
perform a NEB calculation.
</P>
<P>An atom map must be defined which it is not by default for <A HREF = "atom_style.html">atom_style
atomic</A> problems. The <A HREF = "atom_modify.html">atom_modify
map</A> command can be used to do this.
</P>
<P>The "atom_modify sort 0 0.0" command should be used to turn off atom
sorting.
</P>
<P>NOTE: This sorting restriction will be removed in a future version of
NEB in LAMMPS.
</P>
<P>The minimizers in LAMMPS operate on all atoms in your system, even
non-NEB atoms, as defined above. To prevent non-NEB atoms from moving
during the minimization, you should use the <A HREF = "fix_setforce.html">fix
setforce</A> command to set the force on each of those
atoms to 0.0. This is not required, and may not even be desired in
some cases, but if those atoms move too far (e.g. because the initial
state of your system was not well-minimized), it can cause problems
for the NEB procedure.
</P>
<P>The damped dynamics <A HREF = "min_style.html">minimizers</A>, such as <I>quickmin</I>
and <I>fire</I>), adjust the position and velocity of the atoms via an
Euler integration step. Thus you must define an appropriate
<A HREF = "timestep.html">timestep</A> to use with NEB. Using the same timestep
that would be used for a dynamics <A HREF = "run.html">run</A> of your system is
advised.
</P>
<HR>
<P>The specified <I>filename</I> contains atom coordinates for the final
configuration. Only atoms with coordinates different than the initial
configuration need to be specified, i.e. those geometrically near the
barrier.
</P>
<P>The file can be ASCII text or a gzipped text file (detected by a .gz
suffix). The file should contain one line per atom, formatted
with the atom ID, followed by the final x,y,z coordinates:
</P>
<PRE>125 24.97311 1.69005 23.46956
126 1.94691 2.79640 1.92799
127 0.15906 3.46099 0.79121
...
</PRE>
<P>The lines can be listed in any order.
</P>
<HR>
<P>Four kinds of output can be generated during a NEB calculation: energy
barrier statistics, thermodynamic output by each replica, dump files,
and restart files.
</P>
<P>When running with multiple partitions (each of which is a replica in
this case), the print-out to the screen and master log.lammps file
contains a line of output, printed once every <I>Nevery</I> timesteps. It
contains the timestep, the maximum force per replica, the maximum
force per atom (in any replica), potential gradients in the initial,
final, and climbing replicas,
the forward and backward energy barriers,
the total reaction coordinate (RDT), and
the normalized reaction coordinate and potential energy of each replica.
</P>
<P>The "maximum force per replica" is
the two-norm of the 3N-length force vector for the atoms in each
replica, maximized across replicas, which is what the <I>ftol</I> setting
is checking against. In this case, N is all the atoms in each
replica. The "maximum force per atom" is the maximum force component
of any atom in any replica. The potential gradients are the two-norm
of the 3N-length force vector solely due to the interaction potential i.e.
without adding in inter-replica forces. Note that inter-replica forces
are zero in the initial and final replicas, and only affect
the direction in the climbing replica. For this reason, the "maximum
force per replica" is often equal to the potential gradient in the
climbing replica. In the first stage of NEB, there is no climbing
replica, and so the potential gradient in the highest energy replica
is reported, since this replica will become the climbing replica
in the second stage of NEB.
</P>
<P>The "reaction coordinate" (RD) for each
replica is the two-norm of the 3N-length vector of distances between
its atoms and the preceding replica's atoms, added to the RD of the
preceding replica. The RD of the first replica RD1 = 0.0;
the RD of the final replica RDN = RDT, the total reaction coordinate.
The normalized RDs are divided by RDT,
so that they form a monotonically increasing sequence
from zero to one. When computing RD, N only includes the atoms
being operated on by the fix neb command.
</P>
<P>The forward (reverse) energy barrier is the potential energy of the highest
replica minus the energy of the first (last) replica.
</P>
<P>When running on multiple partitions, LAMMPS produces additional log
files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For a
NEB calculation, these contain the thermodynamic output for each
replica.
</P>
<P>If <A HREF = "dump.html">dump</A> commands in the input script define a filename
that includes a <I>universe</I> or <I>uloop</I> style <A HREF = "variable.html">variable</A>,
then one dump file (per dump command) will be created for each
replica. At the end of the NEB calculation, the final snapshot in
each file will contain the sequence of snapshots that transition the
system over the energy barrier. Earlier snapshots will show the
convergence of the replicas to the MEP.
</P>
<P>Likewise, <A HREF = "restart.html">restart</A> filenames can be specified with a
<I>universe</I> or <I>uloop</I> style <A HREF = "variable.html">variable</A>, to generate
restart files for each replica. These may be useful if the NEB
calculation fails to converge properly to the MEP, and you wish to
restart the calculation from an intermediate point with altered
parameters.
</P>
<P>There are 2 Python scripts provided in the tools/python directory,
neb_combine.py and neb_final.py, which are useful in analyzing output
from a NEB calculation. Assume a NEB simulation with M replicas, and
the NEB atoms labelled with a specific atom type.
</P>
<P>The neb_combine.py script extracts atom coords for the NEB atoms from
all M dump files and creates a single dump file where each snapshot
contains the NEB atoms from all the replicas and one copy of non-NEB
atoms from the first replica (presumed to be identical in other
replicas). This can be visualized/animated to see how the NEB atoms
relax as the NEB calculation proceeds.
</P>
<P>The neb_final.py script extracts the final snapshot from each of the M
dump files to create a single dump file with M snapshots. This can be
visualized to watch the system make its transition over the energy
barrier.
</P>
<P>To illustrate, here are images from the final snapshot produced by the
neb_combine.py script run on the dump files produced by the two
example input scripts in examples/neb. Click on them to see a larger
image.
</P>
<A HREF = "JPG/hop1.jpg"><IMG SRC = "JPG/hop1_small.jpg"></A>
<A HREF = "JPG/hop2.jpg"><IMG SRC = "JPG/hop2_small.jpg"></A>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "prd.html">prd</A>, <A HREF = "temper.html">temper</A>, <A HREF = "fix_langevin.html">fix
langevin</A>, <A HREF = "fix_viscous.html">fix viscous</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Henkelman1"></A>
<P><B>(Henkelman1)</B> Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
</P>
<A NAME = "Henkelman2"></A>
<P><B>(Henkelman2)</B> Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
</P>
<A NAME = "Nakano"></A>
<P><B>(Nakano)</B> Nakano, Comp Phys Comm, 178, 280-289 (2008).
</P>
</HTML>
diff --git a/doc/neb.txt b/doc/neb.txt
index 1965f2334..78c3a927b 100644
--- a/doc/neb.txt
+++ b/doc/neb.txt
@@ -1,324 +1,324 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
neb command :h3
[Syntax:]
neb etol ftol N1 N2 Nevery filename :pre
etol = stopping tolerance for energy (energy units)
ftol = stopping tolerance for force (force units)
N1 = max # of iterations (timesteps) to run initial NEB
N2 = max # of iterations (timesteps) to run barrier-climbing NEB
Nevery = print replica energies and reaction coordinates every this many timesteps
filename = file specifying final atom coordinates on other side of barrier :ul
[Examples:]
neb 0.1 0.0 1000 500 50 coords.final
neb 0.0 0.001 1000 500 50 coords.final :pre
[Description:]
Perform a nudged elastic band (NEB) calculation using multiple
replicas of a system. Two or more replicas must be used, two of which
are the end points of the transition path.
NEB is a method for finding both the atomic configurations and height
of the energy barrier associated with a transition state, e.g. for an
atom to perform a diffusive hop from one energy basin to another in a
coordinated fashion with its neighbors. The implementation in LAMMPS
follows the discussion in these 3 papers: "(Henkelman1)"_#Henkelman1,
"(Henkelman2)"_#Henkelman2, and "(Nakano)"_#Nakano.
Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see "this section"_Section_start.html#start_6 of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. You will simply not get the performance speed-up you
+switch; see "Section_start 6"_Section_start.html#start_6 of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. You will simply not get the performance speed-up you
would see with one or more physical processors per replica. See "this
section"_Section_howto.html#howto_5 of the manual for further
discussion.
NOTE: The current NEB implementation in LAMMPS restricts you to having
exactly one processor per replica.
When a NEB calculation is performed, it is assumed that each replica
is running the same model, though LAMMPS does not check for this.
I.e. the simulation domain, the number of atoms, the interaction
potentials, and the starting configuration when the neb command is
issued should be the same for every replica.
In a NEB calculation each atom in a replica is connected to the same
atom in adjacent replicas by springs, which induce inter-replica
forces. These forces are imposed by the "fix neb"_fix_neb.html
command, which must be used in conjunction with the neb command. The
group used to define the fix neb command specifies which atoms the
inter-replica springs are applied to. These are the NEB atoms.
Additional atoms can be present in your system, e.g. to provide a
background force field or simply to hold fixed during the NEB
procedure, but they will not be part of the barrier finding procedure.
The "starting configuration" for NEB should be a state with the NEB
atoms (and all other atoms) having coordinates on one side of the
energy barrier. These coordinates will be assigned to the first
replica #1. The coordinates should be close to a local energy
minimum. A perfect energy minimum is not required, since NEB runs via
damped dynamics which will tend to drive the configuration of replica
#1 to a true energy minimum, but you will typically get better
convergence if the initial state is already at a minimum. For
example, for a system with a free surface, the surface should be fully
relaxed before attempting a NEB calculation.
The final configuration is specified in the input {filename}, which is
formatted as described below. Only coordinates for NEB atoms or a
subset of them should be listed in the file; they represent the state
of the system on the other side of the barrier, at or near an energy
minimum. These coordinates will be assigned to the last replica #M.
The final coordinates of atoms not listed in {filename} are set equal
to their initial coordinates. Again, a perfect energy minimum is not
required for the final configuration, since the atoms in replica #M
will tend to move during the NEB procedure to the nearest energy
minimum. Also note that a final coordinate does not need to be
specified for a NEB atom if you expect it to only displace slightly
during the NEB procedure. For example, only the final coordinate of
the single atom diffusing into a vacancy need be specified if the
surrounding atoms will only relax slightly in the final configuration.
The initial coordinates of all atoms (not just NEB atoms) in the
intermediate replicas #2,#3,...,#M-1 are set to values linearly
interpolated between the corresponding atoms in replicas #1 and #M.
A NEB calculation has two stages, each of which is a minimization
procedure, performed via damped dynamics. To enable this, you must
first define an appropriate "min_style"_min_style.html, such as
{quickmin} or {fire}. The {cg}, {sd}, and {hftn} styles cannot be
used, since they perform iterative line searches in their inner loop,
which cannot be easily synchronized across multiple replicas.
The minimizer tolerances for energy and force are set by {etol} and {ftol},
the same as for
the "minimize"_minimize.html command.
A non-zero {etol}
means that the NEB calculation will terminate if the energy criterion is met
by every replica. The energies being compared to
{etol} do not include any contribution from the inter-replica forces, since
these are non-conservative.
A non-zero {ftol}
means that the NEB calculation will terminate if the force criterion is met
by every replica. The forces being compared to
{ftol} include the inter-replica forces between an atom and its images
in adjacent replicas.
The maximum number of iterations in each stage is set by {N1} and
{N2}. These are effectively timestep counts since each iteration of
damped dynamics is like a single timestep in a dynamics
"run"_run.html. During both stages, the potential energy of each
replica and its normalized distance along the reaction path (reaction
coordinate RD) will be printed to the screen and log file every
{Nevery} timesteps. The RD is 0 and 1 for the first and last replica.
For intermediate replicas, it is the cumulative distance (normalized
by the total cumulative distance) between adjacent replicas, where
"distance" is defined as the length of the 3N-vector of differences in
atomic coordinates, where N is the number of NEB atoms involved in the
transition. These outputs allow you to monitor NEB's progress in
finding a good energy barrier. {N1} and {N2} must both be multiples
of {Nevery}.
In the first stage of NEB, the set of replicas should converge toward
the minimum energy path (MEP) of conformational states that transition
over the barrier. The MEP for a barrier is defined as a sequence of
3N-dimensional states that cross the barrier at its saddle point, each
of which has a potential energy gradient parallel to the MEP itself.
The replica states will also be roughly equally spaced along the MEP
due to the inter-replica spring force added by the "fix
neb"_fix_neb.html command.
In the second stage of NEB, the replica with the highest energy
is selected and the inter-replica forces on it are converted to a
force that drives its atom coordinates to the top or saddle point of
the barrier, via the barrier-climbing calculation described in
"(Henkelman2)"_#Hinkelman2. As before, the other replicas rearrange
themselves along the MEP so as to be roughly equally spaced.
When both stages are complete, if the NEB calculation was successful,
one of the replicas should be an atomic configuration at the top or
saddle point of the barrier, the potential energies for the set of
replicas should represent the energy profile of the barrier along the
MEP, and the configurations of the replicas should be a sequence of
configurations along the MEP.
:line
A few other settings in your input script are required or advised to
perform a NEB calculation.
An atom map must be defined which it is not by default for "atom_style
atomic"_atom_style.html problems. The "atom_modify
map"_atom_modify.html command can be used to do this.
The "atom_modify sort 0 0.0" command should be used to turn off atom
sorting.
NOTE: This sorting restriction will be removed in a future version of
NEB in LAMMPS.
The minimizers in LAMMPS operate on all atoms in your system, even
non-NEB atoms, as defined above. To prevent non-NEB atoms from moving
during the minimization, you should use the "fix
setforce"_fix_setforce.html command to set the force on each of those
atoms to 0.0. This is not required, and may not even be desired in
some cases, but if those atoms move too far (e.g. because the initial
state of your system was not well-minimized), it can cause problems
for the NEB procedure.
The damped dynamics "minimizers"_min_style.html, such as {quickmin}
and {fire}), adjust the position and velocity of the atoms via an
Euler integration step. Thus you must define an appropriate
"timestep"_timestep.html to use with NEB. Using the same timestep
that would be used for a dynamics "run"_run.html of your system is
advised.
:line
The specified {filename} contains atom coordinates for the final
configuration. Only atoms with coordinates different than the initial
configuration need to be specified, i.e. those geometrically near the
barrier.
The file can be ASCII text or a gzipped text file (detected by a .gz
suffix). The file should contain one line per atom, formatted
with the atom ID, followed by the final x,y,z coordinates:
125 24.97311 1.69005 23.46956
126 1.94691 2.79640 1.92799
127 0.15906 3.46099 0.79121
... :pre
The lines can be listed in any order.
:line
Four kinds of output can be generated during a NEB calculation: energy
barrier statistics, thermodynamic output by each replica, dump files,
and restart files.
When running with multiple partitions (each of which is a replica in
this case), the print-out to the screen and master log.lammps file
contains a line of output, printed once every {Nevery} timesteps. It
contains the timestep, the maximum force per replica, the maximum
force per atom (in any replica), potential gradients in the initial,
final, and climbing replicas,
the forward and backward energy barriers,
the total reaction coordinate (RDT), and
the normalized reaction coordinate and potential energy of each replica.
The "maximum force per replica" is
the two-norm of the 3N-length force vector for the atoms in each
replica, maximized across replicas, which is what the {ftol} setting
is checking against. In this case, N is all the atoms in each
replica. The "maximum force per atom" is the maximum force component
of any atom in any replica. The potential gradients are the two-norm
of the 3N-length force vector solely due to the interaction potential i.e.
without adding in inter-replica forces. Note that inter-replica forces
are zero in the initial and final replicas, and only affect
the direction in the climbing replica. For this reason, the "maximum
force per replica" is often equal to the potential gradient in the
climbing replica. In the first stage of NEB, there is no climbing
replica, and so the potential gradient in the highest energy replica
is reported, since this replica will become the climbing replica
in the second stage of NEB.
The "reaction coordinate" (RD) for each
replica is the two-norm of the 3N-length vector of distances between
its atoms and the preceding replica's atoms, added to the RD of the
preceding replica. The RD of the first replica RD1 = 0.0;
the RD of the final replica RDN = RDT, the total reaction coordinate.
The normalized RDs are divided by RDT,
so that they form a monotonically increasing sequence
from zero to one. When computing RD, N only includes the atoms
being operated on by the fix neb command.
The forward (reverse) energy barrier is the potential energy of the highest
replica minus the energy of the first (last) replica.
When running on multiple partitions, LAMMPS produces additional log
files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For a
NEB calculation, these contain the thermodynamic output for each
replica.
If "dump"_dump.html commands in the input script define a filename
that includes a {universe} or {uloop} style "variable"_variable.html,
then one dump file (per dump command) will be created for each
replica. At the end of the NEB calculation, the final snapshot in
each file will contain the sequence of snapshots that transition the
system over the energy barrier. Earlier snapshots will show the
convergence of the replicas to the MEP.
Likewise, "restart"_restart.html filenames can be specified with a
{universe} or {uloop} style "variable"_variable.html, to generate
restart files for each replica. These may be useful if the NEB
calculation fails to converge properly to the MEP, and you wish to
restart the calculation from an intermediate point with altered
parameters.
There are 2 Python scripts provided in the tools/python directory,
neb_combine.py and neb_final.py, which are useful in analyzing output
from a NEB calculation. Assume a NEB simulation with M replicas, and
the NEB atoms labelled with a specific atom type.
The neb_combine.py script extracts atom coords for the NEB atoms from
all M dump files and creates a single dump file where each snapshot
contains the NEB atoms from all the replicas and one copy of non-NEB
atoms from the first replica (presumed to be identical in other
replicas). This can be visualized/animated to see how the NEB atoms
relax as the NEB calculation proceeds.
The neb_final.py script extracts the final snapshot from each of the M
dump files to create a single dump file with M snapshots. This can be
visualized to watch the system make its transition over the energy
barrier.
To illustrate, here are images from the final snapshot produced by the
neb_combine.py script run on the dump files produced by the two
example input scripts in examples/neb. Click on them to see a larger
image.
:image(JPG/hop1_small.jpg,JPG/hop1.jpg)
:image(JPG/hop2_small.jpg,JPG/hop2.jpg)
:line
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"prd"_prd.html, "temper"_temper.html, "fix
langevin"_fix_langevin.html, "fix viscous"_fix_viscous.html
[Default:] none
:line
:link(Henkelman1)
[(Henkelman1)] Henkelman and Jonsson, J Chem Phys, 113, 9978-9985 (2000).
:link(Henkelman2)
[(Henkelman2)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113,
9901-9904 (2000).
:link(Nakano)
[(Nakano)] Nakano, Comp Phys Comm, 178, 280-289 (2008).
diff --git a/doc/package.html b/doc/package.html
index 50eb1657b..124ae4732 100644
--- a/doc/package.html
+++ b/doc/package.html
@@ -1,146 +1,269 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>package command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>package style args
</PRE>
<UL><LI>style = <I>gpu</I> or <I>cuda</I> or <I>omp</I>
<LI>args = arguments specific to the style
-<PRE> <I>gpu</I> args = mode first last split
+<PRE> <I>gpu</I> args = mode first last split keyword value ...
mode = force or force/neigh
first = ID of first GPU to be used on each node
last = ID of last GPU to be used on each node
split = fraction of particles assigned to the GPU
- <I>cuda</I> args = to be determined
- <I>omp</I> args = Nthreads
- Nthreads = # of OpenMP threads to associate with each MPI process
+ zero or more keyword/value pairs may be appended
+ keywords = <I>threads_per_atom</I>
+ <I>threads_per_atom</I> value = Nthreads
+ Nthreads = # of GPU threads used per atom
+ <I>cuda</I> args = keyword value ...
+ one or more keyword/value pairs may be appended
+ keywords = <I>gpu/node</I> or <I>gpu/node/special</I> or <I>timing</I> or <I>test</I> or <I>override/bpa</I>
+ <I>gpu/node</I> value = N
+ N = number of GPUs to be used per node
+ <I>gpu/node/special</I> values = N gpu1 .. gpuN
+ N = number of GPUs to be used per node
+ gpu1 .. gpuN = N IDs of the GPUs to use
+ <I>timing</I> values = none
+ <I>test</I> values = id
+ id = atom-ID of a test particle
+ <I>override/bpa</I> values = flag
+ flag = 0 for TpA algorithm, 1 for BpA algorithm
+ <I>omp</I> args = Nthreads mode
+ Nthreads = # of OpenMP threads to associate with each MPI process
+ mode = force or force/neigh (optional)
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>package gpu force 0 0 1.0
package gpu force 0 0 0.75
package gpu force/neigh 0 0 1.0
package gpu force/neigh 0 1 -1.0
-package cuda blah
-package omp 4
+package cuda gpu/node/special 2 0 2
+package cuda test 3948
+package omp * force/neigh
+package omp 4 force
</PRE>
<P><B>Description:</B>
</P>
<P>This command invokes package-specific settings. Currently the
following packages use it: GPU, USER-CUDA, and USER-OMP.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-details about using these various packages for accelerating
-a LAMMPS calculation.
+<P>To use the accelerated GPU and USER-OMP styles, the use of the package
+command is required. However, as described in the "Defaults" section
+below, if you use the "-sf gpu" or "-sf omp" <A HREF = "Section_start.html#start_6">command-line
+options</A> to enable use of these styles,
+then default package settings are enabled. In that case you only need
+to use the package command if you want to change the defaults.
+</P>
+<P>To use the accelerate USER-CUDA styles, the package command is not
+required as defaults are assigned internally. You only need to use
+the package command if you want to change the defaults.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more details about using these various packages for accelerating
+LAMMPS calculations.
</P>
<HR>
<P>The <I>gpu</I> style invokes options associated with the use of the GPU
-package. It allows you to select and initialize GPUs to be used for
-acceleration via this package and configure how the GPU acceleration
-is performed. These settings are required in order to use any style
-with GPU acceleration.
+package.
</P>
<P>The <I>mode</I> setting specifies where neighbor list calculations will be
performed. If <I>mode</I> is force, neighbor list calculation is performed
on the CPU. If <I>mode</I> is force/neigh, neighbor list calculation is
performed on the GPU. GPU neighbor list calculation currently cannot
be used with a triclinic box. GPU neighbor list calculation currently
cannot be used with <A HREF = "pair_hybrid.html">hybrid</A> pair styles. GPU
neighbor lists are not compatible with styles that are not
GPU-enabled. When a non-GPU enabled style requires a neighbor list,
it will also be built using CPU routines. In these cases, it will
typically be more efficient to only use CPU neighbor list builds.
</P>
<P>The <I>first</I> and <I>last</I> settings specify the GPUs that will be used for
simulation. On each node, the GPU IDs in the inclusive range from
<I>first</I> to <I>last</I> will be used.
</P>
<P>The <I>split</I> setting can be used for load balancing force calculation
work between CPU and GPU cores in GPU-enabled pair styles. If 0 <
<I>split</I> < 1.0, a fixed fraction of particles is offloaded to the GPU
while force calculation for the other particles occurs simulataneously
on the CPU. If <I>split</I><0, the optimal fraction (based on CPU and GPU
timings) is calculated every 25 timesteps. If <I>split</I> = 1.0, all force
calculations for GPU accelerated pair styles are performed on the
GPU. In this case, <A HREF = "pair_hybrid.html">hybrid</A>, <A HREF = "bond_style.html">bond</A>,
<A HREF = "angle_style.html">angle</A>, <A HREF = "dihedral_style.html">dihedral</A>,
<A HREF = "improper_style.html">improper</A>, and <A HREF = "kspace_style.html">long-range</A>
calculations can be performed on the CPU while the GPU is performing
force calculations for the GPU-enabled pair style. If all CPU force
computations complete before the GPU, LAMMPS will block until the GPU
has finished before continuing the timestep.
</P>
<P>As an example, if you have two GPUs per node and 8 CPU cores per node,
and would like to run on 4 nodes (32 cores) with dynamic balancing of
force calculation across CPU and GPU cores, you could specify
</P>
<PRE>package gpu force/neigh 0 1 -1
</PRE>
<P>In this case, all CPU cores and GPU devices on the nodes would be
utilized. Each GPU device would be shared by 4 CPU cores. The CPU
cores would perform force calculations for some fraction of the
particles at the same time the GPUs performed force calculation for
the other particles.
</P>
+<P>The <I>threads_per_atom</I> keyword allows control of the number of GPU
+threads used per-atom to perform the short range force calculation.
+By default, the value will be chosen based on the pair style, however,
+the value can be set with this keyword to fine-tune performance. For
+large cutoffs or with a small number of particles per GPU, increasing
+the value can improve performance. The number of threads per atom must
+be a power of 2 and currently cannot be greater than 32.
+</P>
<HR>
<P>The <I>cuda</I> style invokes options associated with the use of the
-USER-CUDA package. These still need to be documented.
+USER-CUDA package.
+</P>
+<P>The <I>gpu/node</I> keyword specifies the number <I>N</I> of GPUs to be used on
+each node. An MPI process with rank <I>K</I> will use the GPU (K mod N).
+This implies that processes should be assigned with successive ranks
+on each node, which is the default with most (or even all) MPI
+implementations. The default value for <I>N</I> is 2.
+</P>
+<P>The <I>gpu/node/special</I> keyword also specifies the number (N) of GPUs
+to be used on each node, but allows more control over their
+specification. An MPI process with rank <I>K</I> will use the GPU <I>gpuI</I>
+with l = (K mod N) + 1. This implies that processes should be assigned
+with successive ranks on each node, which is the default with most (or
+even all) MPI implementations. For example if you have three GPUs on
+a machine, one of which is used for the X-Server (the GPU with the ID
+1) while the others (with IDs 0 and 2) are used for computations you
+would specify:
+</P>
+<PRE>package cuda gpu/node/special 2 0 2
+</PRE>
+<P>A main purpose of the <I>gpu/node/special</I> optoin is to allow two (or
+more) simulations to be run on one workstation. In that case one
+would set the first simulation to use GPU 0 and the second to use GPU
+1. This is not necessary though, if the GPUs are in what is called
+<I>compute exclusive</I> mode. Using that setting, every process will get
+its own GPU automatically. This <I>compute exclusive</I> mode can be set
+as root using the <I>nvidia-smi</I> tool which is part of the CUDA
+installation.
+</P>
+<P>Note that if the <I>gpu/node/special</I> keyword is not used, the USER-CUDA
+package sorts existing GPUs on each node according to their number of
+multiprocessors. This way, compute GPUs will be priorized over
+X-Server GPUs.
+</P>
+<P>Use of the <I>timing</I> keyword will output detailed timing information
+for various subroutines.
+</P>
+<P>The <I>test</I> keyword will output info for the the specified atom at
+several points during each time step. This is mainly usefull for
+debugging purposes. Note that the simulation will be severly slowed
+down if this option is used.
+</P>
+<P>The <I>override/bpa</I> keyword can be used to specify which mode is used
+for pair-force evaluation. TpA = one thread per atom; BpA = one block
+per atom. If this keyword is not used, a short test at the begin of
+each run will determine which method is more effective (the result of
+this test is part of the LAMMPS output). Therefore it is usually not
+necessary to use this keyword.
</P>
<HR>
<P>The <I>omp</I> style invokes options associated with the use of the
USER-OMP package.
</P>
-<P>The only setting to make is the number of OpenMP threads to be
-allocated for each MPI process. For example, if your system has nodes
-with dual quad-core processors, it has a total of 8 cores per node.
-You could run MPI on 2 cores on each node (e.g. using options for the
-mpirun command), and set the <I>Nthreads</I> setting to 4. This would
-effectively use all 8 cores on each node. Since each MPI process
-would spawn 4 threads (one of which runs as part of the MPI process
-itself).
+<P>The first argument allows to explicitly set the number of OpenMP
+threads to be allocated for each MPI process. For example, if your
+system has nodes with dual quad-core processors, it has a total of 8
+cores per node. You could run MPI on 2 cores on each node (e.g. using
+options for the mpirun command), and set the <I>Nthreads</I> setting to 4.
+This would effectively use all 8 cores on each node. Since each MPI
+process would spawn 4 threads (one of which runs as part of the MPI
+process itself).
</P>
<P>For performance reasons, you should not set <I>Nthreads</I> to more threads
-than there are physical cores, but LAMMPS does not check for this.
+than there are physical cores (per MPI task), but LAMMPS cannot check
+for this.
+</P>
+<P>An <I>Nthreads</I> value of '*' instructs LAMMPS to use whatever is the
+default for the given OpenMP environment. This is usually determined
+via the <I>OMP_NUM_THREADS</I> environment variable or the compiler
+runtime. Please note that in most cases the default for OpenMP
+capable compilers is to use one thread for each available CPU core
+when <I>OMP_NUM_THREADS</I> is not set, which can lead to extremely bad
+performance.
+</P>
+<P>Which combination of threads and MPI tasks gives the best performance
+is difficult to predict and can depend on many components of your input.
+Not all features of LAMMPS support OpenMP and the parallel efficiency
+can be very different, too.
+</P>
+<P>The <I>mode</I> setting specifies where neighbor list calculations will be
+multi-threaded as well. If <I>mode</I> is force, neighbor list calculation
+is performed in serial. If <I>mode</I> is force/neigh, a multi-threaded
+neighbor list build is used. Using the force/neigh setting is almost
+always faster and should produce idential neighbor lists at the
+expense of using some more memory (neighbor list pages are always
+allocated for all threads at the same time and each thread works on
+its own pages).
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command cannot be used after the simulation box is defined by a
<A HREF = "read_data.html">read_data</A> or <A HREF = "create_box.html">create_box</A> command.
</P>
<P>The cuda style of this command can only be invoked if LAMMPS was built
with the USER-CUDA package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The gpu style of this command can only be invoked if LAMMPS was built
with the GPU package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The omp style of this command can only be invoked if LAMMPS was built
with the USER-OMP package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
-<P><B>Related commands:</B> none
+<P><B>Related commands:</B>
+</P>
+<P><A HREF = "suffix.html">suffix</A>
+</P>
+<P><B>Default:</B>
+</P>
+<P>If the "-sf gpu" <A HREF = "Section_start.html#start_6">command-line switch</A> is
+used then it is as if the command "package gpu force/neigh 0 0 1" were
+invoked, to specify default settings for the GPU package. If the
+command-line switch is not used, then no defaults are set, and you
+must specify the appropriate package command in your input script.
+</P>
+<P>The default settings for the USER CUDA package are "package cuda gpu
+2". This is the case whether the "-sf cuda" <A HREF = "Section_start.html#start_6">command-line
+switch</A> is used or not.
</P>
-<P><B>Default:</B> none
+<P>If the "-sf omp" <A HREF = "Section_start.html#start_6">command-line switch</A> is
+used then it is as if the command "package omp *" were invoked, to
+specify default settings for the USER-OMP package. If the
+command-line switch is not used, then no defaults are set, and you
+must specify the appropriate package command in your input script.
</P>
</HTML>
diff --git a/doc/package.txt b/doc/package.txt
index cce58abf0..c8b30217a 100644
--- a/doc/package.txt
+++ b/doc/package.txt
@@ -1,138 +1,262 @@
"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
package command :h3
[Syntax:]
package style args :pre
style = {gpu} or {cuda} or {omp} :ulb,l
args = arguments specific to the style :l
- {gpu} args = mode first last split
+ {gpu} args = mode first last split keyword value ...
mode = force or force/neigh
first = ID of first GPU to be used on each node
last = ID of last GPU to be used on each node
split = fraction of particles assigned to the GPU
- {cuda} args = to be determined
- {omp} args = Nthreads
- Nthreads = # of OpenMP threads to associate with each MPI process :pre
+ zero or more keyword/value pairs may be appended
+ keywords = {threads_per_atom}
+ {threads_per_atom} value = Nthreads
+ Nthreads = # of GPU threads used per atom
+ {cuda} args = keyword value ...
+ one or more keyword/value pairs may be appended
+ keywords = {gpu/node} or {gpu/node/special} or {timing} or {test} or {override/bpa}
+ {gpu/node} value = N
+ N = number of GPUs to be used per node
+ {gpu/node/special} values = N gpu1 .. gpuN
+ N = number of GPUs to be used per node
+ gpu1 .. gpuN = N IDs of the GPUs to use
+ {timing} values = none
+ {test} values = id
+ id = atom-ID of a test particle
+ {override/bpa} values = flag
+ flag = 0 for TpA algorithm, 1 for BpA algorithm
+ {omp} args = Nthreads mode
+ Nthreads = # of OpenMP threads to associate with each MPI process
+ mode = force or force/neigh (optional) :pre
:ule
[Examples:]
package gpu force 0 0 1.0
package gpu force 0 0 0.75
package gpu force/neigh 0 0 1.0
package gpu force/neigh 0 1 -1.0
-package cuda blah
-package omp 4 :pre
+package cuda gpu/node/special 2 0 2
+package cuda test 3948
+package omp * force/neigh
+package omp 4 force :pre
[Description:]
This command invokes package-specific settings. Currently the
following packages use it: GPU, USER-CUDA, and USER-OMP.
-See "this section"_Section_accelerate.html of the manual for more
-details about using these various packages for accelerating
-a LAMMPS calculation.
+To use the accelerated GPU and USER-OMP styles, the use of the package
+command is required. However, as described in the "Defaults" section
+below, if you use the "-sf gpu" or "-sf omp" "command-line
+options"_Section_start.html#start_6 to enable use of these styles,
+then default package settings are enabled. In that case you only need
+to use the package command if you want to change the defaults.
+
+To use the accelerate USER-CUDA styles, the package command is not
+required as defaults are assigned internally. You only need to use
+the package command if you want to change the defaults.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more details about using these various packages for accelerating
+LAMMPS calculations.
:line
The {gpu} style invokes options associated with the use of the GPU
-package. It allows you to select and initialize GPUs to be used for
-acceleration via this package and configure how the GPU acceleration
-is performed. These settings are required in order to use any style
-with GPU acceleration.
+package.
The {mode} setting specifies where neighbor list calculations will be
performed. If {mode} is force, neighbor list calculation is performed
on the CPU. If {mode} is force/neigh, neighbor list calculation is
performed on the GPU. GPU neighbor list calculation currently cannot
be used with a triclinic box. GPU neighbor list calculation currently
cannot be used with "hybrid"_pair_hybrid.html pair styles. GPU
neighbor lists are not compatible with styles that are not
GPU-enabled. When a non-GPU enabled style requires a neighbor list,
it will also be built using CPU routines. In these cases, it will
typically be more efficient to only use CPU neighbor list builds.
The {first} and {last} settings specify the GPUs that will be used for
simulation. On each node, the GPU IDs in the inclusive range from
{first} to {last} will be used.
The {split} setting can be used for load balancing force calculation
work between CPU and GPU cores in GPU-enabled pair styles. If 0 <
{split} < 1.0, a fixed fraction of particles is offloaded to the GPU
while force calculation for the other particles occurs simulataneously
on the CPU. If {split}<0, the optimal fraction (based on CPU and GPU
timings) is calculated every 25 timesteps. If {split} = 1.0, all force
calculations for GPU accelerated pair styles are performed on the
GPU. In this case, "hybrid"_pair_hybrid.html, "bond"_bond_style.html,
"angle"_angle_style.html, "dihedral"_dihedral_style.html,
"improper"_improper_style.html, and "long-range"_kspace_style.html
calculations can be performed on the CPU while the GPU is performing
force calculations for the GPU-enabled pair style. If all CPU force
computations complete before the GPU, LAMMPS will block until the GPU
has finished before continuing the timestep.
As an example, if you have two GPUs per node and 8 CPU cores per node,
and would like to run on 4 nodes (32 cores) with dynamic balancing of
force calculation across CPU and GPU cores, you could specify
package gpu force/neigh 0 1 -1 :pre
In this case, all CPU cores and GPU devices on the nodes would be
utilized. Each GPU device would be shared by 4 CPU cores. The CPU
cores would perform force calculations for some fraction of the
particles at the same time the GPUs performed force calculation for
the other particles.
+The {threads_per_atom} keyword allows control of the number of GPU
+threads used per-atom to perform the short range force calculation.
+By default, the value will be chosen based on the pair style, however,
+the value can be set with this keyword to fine-tune performance. For
+large cutoffs or with a small number of particles per GPU, increasing
+the value can improve performance. The number of threads per atom must
+be a power of 2 and currently cannot be greater than 32.
+
:line
The {cuda} style invokes options associated with the use of the
-USER-CUDA package. These still need to be documented.
+USER-CUDA package.
+
+The {gpu/node} keyword specifies the number {N} of GPUs to be used on
+each node. An MPI process with rank {K} will use the GPU (K mod N).
+This implies that processes should be assigned with successive ranks
+on each node, which is the default with most (or even all) MPI
+implementations. The default value for {N} is 2.
+
+The {gpu/node/special} keyword also specifies the number (N) of GPUs
+to be used on each node, but allows more control over their
+specification. An MPI process with rank {K} will use the GPU {gpuI}
+with l = (K mod N) + 1. This implies that processes should be assigned
+with successive ranks on each node, which is the default with most (or
+even all) MPI implementations. For example if you have three GPUs on
+a machine, one of which is used for the X-Server (the GPU with the ID
+1) while the others (with IDs 0 and 2) are used for computations you
+would specify:
+
+package cuda gpu/node/special 2 0 2 :pre
+
+A main purpose of the {gpu/node/special} optoin is to allow two (or
+more) simulations to be run on one workstation. In that case one
+would set the first simulation to use GPU 0 and the second to use GPU
+1. This is not necessary though, if the GPUs are in what is called
+{compute exclusive} mode. Using that setting, every process will get
+its own GPU automatically. This {compute exclusive} mode can be set
+as root using the {nvidia-smi} tool which is part of the CUDA
+installation.
+
+Note that if the {gpu/node/special} keyword is not used, the USER-CUDA
+package sorts existing GPUs on each node according to their number of
+multiprocessors. This way, compute GPUs will be priorized over
+X-Server GPUs.
+
+Use of the {timing} keyword will output detailed timing information
+for various subroutines.
+
+The {test} keyword will output info for the the specified atom at
+several points during each time step. This is mainly usefull for
+debugging purposes. Note that the simulation will be severly slowed
+down if this option is used.
+
+The {override/bpa} keyword can be used to specify which mode is used
+for pair-force evaluation. TpA = one thread per atom; BpA = one block
+per atom. If this keyword is not used, a short test at the begin of
+each run will determine which method is more effective (the result of
+this test is part of the LAMMPS output). Therefore it is usually not
+necessary to use this keyword.
:line
The {omp} style invokes options associated with the use of the
USER-OMP package.
-The only setting to make is the number of OpenMP threads to be
-allocated for each MPI process. For example, if your system has nodes
-with dual quad-core processors, it has a total of 8 cores per node.
-You could run MPI on 2 cores on each node (e.g. using options for the
-mpirun command), and set the {Nthreads} setting to 4. This would
-effectively use all 8 cores on each node. Since each MPI process
-would spawn 4 threads (one of which runs as part of the MPI process
-itself).
+The first argument allows to explicitly set the number of OpenMP
+threads to be allocated for each MPI process. For example, if your
+system has nodes with dual quad-core processors, it has a total of 8
+cores per node. You could run MPI on 2 cores on each node (e.g. using
+options for the mpirun command), and set the {Nthreads} setting to 4.
+This would effectively use all 8 cores on each node. Since each MPI
+process would spawn 4 threads (one of which runs as part of the MPI
+process itself).
For performance reasons, you should not set {Nthreads} to more threads
-than there are physical cores, but LAMMPS does not check for this.
+than there are physical cores (per MPI task), but LAMMPS cannot check
+for this.
+
+An {Nthreads} value of '*' instructs LAMMPS to use whatever is the
+default for the given OpenMP environment. This is usually determined
+via the {OMP_NUM_THREADS} environment variable or the compiler
+runtime. Please note that in most cases the default for OpenMP
+capable compilers is to use one thread for each available CPU core
+when {OMP_NUM_THREADS} is not set, which can lead to extremely bad
+performance.
+
+Which combination of threads and MPI tasks gives the best performance
+is difficult to predict and can depend on many components of your input.
+Not all features of LAMMPS support OpenMP and the parallel efficiency
+can be very different, too.
+
+The {mode} setting specifies where neighbor list calculations will be
+multi-threaded as well. If {mode} is force, neighbor list calculation
+is performed in serial. If {mode} is force/neigh, a multi-threaded
+neighbor list build is used. Using the force/neigh setting is almost
+always faster and should produce idential neighbor lists at the
+expense of using some more memory (neighbor list pages are always
+allocated for all threads at the same time and each thread works on
+its own pages).
:line
[Restrictions:]
This command cannot be used after the simulation box is defined by a
"read_data"_read_data.html or "create_box"_create_box.html command.
The cuda style of this command can only be invoked if LAMMPS was built
with the USER-CUDA package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The gpu style of this command can only be invoked if LAMMPS was built
with the GPU package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The omp style of this command can only be invoked if LAMMPS was built
with the USER-OMP package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
-[Related commands:] none
+[Related commands:]
+
+"suffix"_suffix.html
+
+[Default:]
+
+If the "-sf gpu" "command-line switch"_Section_start.html#start_6 is
+used then it is as if the command "package gpu force/neigh 0 0 1" were
+invoked, to specify default settings for the GPU package. If the
+command-line switch is not used, then no defaults are set, and you
+must specify the appropriate package command in your input script.
+
+The default settings for the USER CUDA package are "package cuda gpu
+2". This is the case whether the "-sf cuda" "command-line
+switch"_Section_start.html#start_6 is used or not.
+
+If the "-sf omp" "command-line switch"_Section_start.html#start_6 is
+used then it is as if the command "package omp *" were invoked, to
+specify default settings for the USER-OMP package. If the
+command-line switch is not used, then no defaults are set, and you
+must specify the appropriate package command in your input script.
-[Default:] none
diff --git a/doc/pair_adp.html b/doc/pair_adp.html
index 34bf49422..230d469cd 100644
--- a/doc/pair_adp.html
+++ b/doc/pair_adp.html
@@ -1,187 +1,187 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style adp command
</H3>
<H3>pair_style adp/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style adp
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style adp
pair_coeff * * Ta.adp Ta
pair_coeff * * ../potentials/AlCu.adp Al Al Cu
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>adp</I> computes pairwise interactions for metals and metal alloys
using the angular dependent potential (ADP) of <A HREF = "#Mishin">(Mishin)</A>,
which is a generalization of the <A HREF = "pair_eam.html">embedded atom method (EAM)
potential</A>. The LAMMPS implementation is discussed in
<A HREF = "#Singh">(Singh)</A>. The total energy Ei of an atom I is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_adp.jpg">
</CENTER>
<P>where F is the embedding energy which is a function of the atomic
electron density rho, phi is a pair potential interaction, alpha and
beta are the element types of atoms I and J, and s and t = 1,2,3 and
refer to the cartesian coordinates. The mu and lambda terms represent
the dipole and quadruple distortions of the local atomic environment
which extend the original EAM framework by introducing angular forces.
</P>
<P>Note that unlike for other potentials, cutoffs for ADP potentials are
not set in the pair_style or pair_coeff command; they are specified in
the ADP potential files themselves. Likewise, the ADP potential files
list atomic masses; thus you do not need to use the <A HREF = "mass.html">mass</A>
command to specify them.
</P>
<P>The NIST WWW site distributes and documents ADP potentials:
</P>
<PRE>http://www.ctcms.nist.gov/potentials
</PRE>
<P>Note that these must be converted into the extended DYNAMO <I>setfl</I>
format discussed below.
</P>
<P>The NIST site is maintained by Chandler Becker (cbecker at nist.gov)
who is good resource for info on interatomic potentials and file
formats.
</P>
<HR>
<P>Only a single pair_coeff command is used with the <I>adp</I> style which
specifies an extended DYNAMO <I>setfl</I> file, which contains information
for M elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of extended <I>setfl</I> elements to atom types
</UL>
<P>As an example, the potentials/AlCu.adp file, included in the
potentials directory of the LAMMPS distrbution, is an extended <I>setfl</I>
file which has tabulated ADP values for w elements and their alloy
interactions: Cu and Al. If your LAMMPS simulation has 4 atoms types
and you want the 1st 3 to be Al, and the 4th to be Cu, you would use
the following pair_coeff command:
</P>
<PRE>pair_coeff * * AlCu.adp Al Al Al Cu
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Al arguments map LAMMPS atom types 1,2,3 to the Al
element in the extended <I>setfl</I> file. The final Cu argument maps
LAMMPS atom type 4 to the Al element in the extended <I>setfl</I> file.
Note that there is no requirement that your simulation use all the
elements specified by the extended <I>setfl</I> file.
</P>
<P>If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an <I>adp</I> potential is used as part of the
<I>hybrid</I> pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
</P>
<P><I>Adp</I> files in the <I>potentials</I> directory of the LAMMPS distribution
have an ".adp" suffix. A DYNAMO <I>setfl</I> file extended for ADP is
formatted as follows. Basically it is the standard <I>setfl</I> format
with additional tabulated functions u and w added to the file after
the tabulated pair potentials. See the <A HREF = "pair_eam.html">pair_eam</A>
command for further details on the <I>setfl</I> format.
</P>
<UL><LI>lines 1,2,3 = comments (ignored)
<LI>line 4: Nelements Element1 Element2 ... ElementN
<LI>line 5: Nrho, drho, Nr, dr, cutoff
</UL>
<P>Following the 5 header lines are Nelements sections, one for each
element, each with the following format:
</P>
<UL><LI>line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
<LI>embedding function F(rho) (Nrho values)
<LI>density function rho(r) (Nr values)
</UL>
<P>Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed for all i,j element pairs in the same format
as other arrays. Since these interactions are symmetric (i,j = j,i)
only phi arrays with i >= j are listed, in the following order: i,j =
(1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), ..., (Nelements,
Nelements).
</P>
<P>After the phi(r) arrays, each of the u(r) arrays are listed in the
same order with the same assumptions of symmetry. Directly following
the u(r), the w(r) arrays are listed.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, no special mixing rules are needed, since
the ADP potential files specify alloy interactions explicitly.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in tabulated potential files.
Thus, you need to re-specify the pair_style and pair_coeff commands in
an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default).
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_eam.html">pair_eam</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Mishin"></A>
<P><B>(Mishin)</B> Mishin, Mehl, and Papaconstantopoulos, Acta Mater, 53, 4029
(2005).
</P>
<A NAME = "Singh"></A>
<P><B>(Singh)</B> Singh and Warner, Acta Mater, 58, 5797-5805 (2010),
</P>
</HTML>
diff --git a/doc/pair_adp.txt b/doc/pair_adp.txt
index 4eef1d675..4909d738b 100644
--- a/doc/pair_adp.txt
+++ b/doc/pair_adp.txt
@@ -1,179 +1,179 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style adp command :h3
pair_style adp/omp command :h3
[Syntax:]
pair_style adp :pre
[Examples:]
pair_style adp
pair_coeff * * Ta.adp Ta
pair_coeff * * ../potentials/AlCu.adp Al Al Cu :pre
[Description:]
Style {adp} computes pairwise interactions for metals and metal alloys
using the angular dependent potential (ADP) of "(Mishin)"_#Mishin,
which is a generalization of the "embedded atom method (EAM)
potential"_pair_eam.html. The LAMMPS implementation is discussed in
"(Singh)"_#Singh. The total energy Ei of an atom I is given by
:c,image(Eqs/pair_adp.jpg)
where F is the embedding energy which is a function of the atomic
electron density rho, phi is a pair potential interaction, alpha and
beta are the element types of atoms I and J, and s and t = 1,2,3 and
refer to the cartesian coordinates. The mu and lambda terms represent
the dipole and quadruple distortions of the local atomic environment
which extend the original EAM framework by introducing angular forces.
Note that unlike for other potentials, cutoffs for ADP potentials are
not set in the pair_style or pair_coeff command; they are specified in
the ADP potential files themselves. Likewise, the ADP potential files
list atomic masses; thus you do not need to use the "mass"_mass.html
command to specify them.
The NIST WWW site distributes and documents ADP potentials:
http://www.ctcms.nist.gov/potentials :pre
Note that these must be converted into the extended DYNAMO {setfl}
format discussed below.
The NIST site is maintained by Chandler Becker (cbecker at nist.gov)
who is good resource for info on interatomic potentials and file
formats.
:line
Only a single pair_coeff command is used with the {adp} style which
specifies an extended DYNAMO {setfl} file, which contains information
for M elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of extended {setfl} elements to atom types :ul
As an example, the potentials/AlCu.adp file, included in the
potentials directory of the LAMMPS distrbution, is an extended {setfl}
file which has tabulated ADP values for w elements and their alloy
interactions: Cu and Al. If your LAMMPS simulation has 4 atoms types
and you want the 1st 3 to be Al, and the 4th to be Cu, you would use
the following pair_coeff command:
pair_coeff * * AlCu.adp Al Al Al Cu :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Al arguments map LAMMPS atom types 1,2,3 to the Al
element in the extended {setfl} file. The final Cu argument maps
LAMMPS atom type 4 to the Al element in the extended {setfl} file.
Note that there is no requirement that your simulation use all the
elements specified by the extended {setfl} file.
If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an {adp} potential is used as part of the
{hybrid} pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
{Adp} files in the {potentials} directory of the LAMMPS distribution
have an ".adp" suffix. A DYNAMO {setfl} file extended for ADP is
formatted as follows. Basically it is the standard {setfl} format
with additional tabulated functions u and w added to the file after
the tabulated pair potentials. See the "pair_eam"_pair_eam.html
command for further details on the {setfl} format.
lines 1,2,3 = comments (ignored)
line 4: Nelements Element1 Element2 ... ElementN
line 5: Nrho, drho, Nr, dr, cutoff :ul
Following the 5 header lines are Nelements sections, one for each
element, each with the following format:
line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
embedding function F(rho) (Nrho values)
density function rho(r) (Nr values) :ul
Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed for all i,j element pairs in the same format
as other arrays. Since these interactions are symmetric (i,j = j,i)
only phi arrays with i >= j are listed, in the following order: i,j =
(1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), ..., (Nelements,
Nelements).
After the phi(r) arrays, each of the u(r) arrays are listed in the
same order with the same assumptions of symmetry. Directly following
the u(r), the w(r) arrays are listed.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, no special mixing rules are needed, since
the ADP potential files specify alloy interactions explicitly.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in tabulated potential files.
Thus, you need to re-specify the pair_style and pair_coeff commands in
an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default).
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_eam"_pair_eam.html
[Default:] none
:line
:link(Mishin)
[(Mishin)] Mishin, Mehl, and Papaconstantopoulos, Acta Mater, 53, 4029
(2005).
:link(Singh)
[(Singh)] Singh and Warner, Acta Mater, 58, 5797-5805 (2010),
diff --git a/doc/pair_airebo.html b/doc/pair_airebo.html
index 282e1affb..8bc7126e0 100644
--- a/doc/pair_airebo.html
+++ b/doc/pair_airebo.html
@@ -1,197 +1,197 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style airebo command
</H3>
<H3>pair_style airebo/omp command
</H3>
<H3>pair_style rebo command
</H3>
<H3>pair_style rebo/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style cutoff LJ_flag TORSION_flag
</PRE>
<UL><LI>style = <I>airebo</I> or <I>rebo</I>
<LI>cutoff = LJ cutoff (sigma scale factor) (AIREBO only)
<LI>LJ_flag = 0/1 to turn off/on the LJ term (AIREBO only, optional)
<LI>TORSION_flag = 0/1 to turn off/on the torsion term (AIREBO only, optional)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style airebo 3.0
pair_style airebo 2.5 1 0
pair_coeff * * ../potentials/CH.airebo H C
</PRE>
<PRE>pair_style rebo
pair_coeff * * ../potentials/CH.airebo H C
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>airebo</I> pair style computes the Adaptive Intermolecular Reactive
Empirical Bond Order (AIREBO) Potential of <A HREF = "#Stuart">(Stuart)</A> for a
system of carbon and/or hydrogen atoms. Note that this is the initial
formulation of AIREBO from 2000, not the later formulation. The
<I>rebo</I> pair style computes the Reactive Empirical Bond Order (REBO)
Potential of <A HREF = "#Brenner">(Brenner)</A>. Note that this is the so-called
2nd generation REBO from 2002, not the original REBO from 1990. As
discussed below, 2nd generation REBO is closely related to the intial
AIREBO; it is just a subset of the potential energy terms.
</P>
<P>The AIREBO potential consists of three terms:
</P>
<CENTER><IMG SRC = "Eqs/pair_airebo.jpg">
</CENTER>
<P>By default, all three terms are included. For the <I>airebo</I> style, if
the two optional flag arguments to the pair_style command are
included, the LJ and torsional terms can be turned off. Note that
both or neither of the flags must be included. If both of the LJ an
torsional terms are turned off, it becomes the 2nd-generation REBO
potential, with a small caveat on the spline fitting procedure
mentioned below. This can be specified directly as pair_style rebo
with no additional arguments.
</P>
<P>The detailed formulas for this potential are given in
<A HREF = "#Stuart">(Stuart)</A>; here we provide only a brief description.
</P>
<P>The E_REBO term has the same functional form as the hydrocarbon REBO
potential developed in <A HREF = "#Brenner">(Brenner)</A>. The coefficients for
E_REBO in AIREBO are essentially the same as Brenner's potential, but
a few fitted spline values are slightly different. For most cases the
E_REBO term in AIREBO will produce the same energies, forces and
statistical averages as the original REBO potential from which it was
derived. The E_REBO term in the AIREBO potential gives the model its
reactive capabilities and only describes short-ranged C-C, C-H and H-H
interactions (r < 2 Angstroms). These interactions have strong
coordination-dependence through a bond order parameter, which adjusts
the attraction between the I,J atoms based on the position of other
nearby atoms and thus has 3- and 4-body dependence.
</P>
<P>The E_LJ term adds longer-ranged interactions (2 < r < cutoff) using a
form similar to the standard <A HREF = "pair_lj.html">Lennard Jones potential</A>.
The E_LJ term in AIREBO contains a series of switching functions so
that the short-ranged LJ repulsion (1/r^12) does not interfere with
the energetics captured by the E_REBO term. The extent of the E_LJ
interactions is determined by the <I>cutoff</I> argument to the pair_style
command which is a scale factor. For each type pair (C-C, C-H, H-H)
the cutoff is obtained by multiplying the scale factor by the sigma
value defined in the potential file for that type pair. In the
standard AIREBO potential, sigma_CC = 3.4 Angstroms, so with a scale
factor of 3.0 (the argument in pair_style), the resulting E_LJ cutoff
would be 10.2 Angstroms.
</P>
<P>The E_TORSION term is an explicit 4-body potential that describes
various dihedral angle preferences in hydrocarbon configurations.
</P>
<P>Only a single pair_coeff command is used with the <I>airebo</I> or <I>rebo</I>
style which specifies an AIREBO potential file with parameters for C
and H. Note that the <I>rebo</I> style in LAMMPS uses the same
AIREBO-formatted potential file. These are mapped to LAMMPS atom
types by specifying N additional arguments after the filename in the
pair_coeff command, where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of AIREBO elements to atom types
</UL>
<P>As an example, if your LAMMPS simulation has 4 atom types and you want
the 1st 3 to be C, and the 4th to be H, you would use the following
pair_coeff command:
</P>
<PRE>pair_coeff * * CH.airebo C C C H
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three C arguments map LAMMPS atom types 1,2,3 to the C
element in the AIREBO file. The final H argument maps LAMMPS atom
type 4 to the H element in the SW file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a <I>airebo</I> potential is used as part of the <I>hybrid</I> pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
</P>
<P>The parameters/coefficients for the AIREBO potentials are listed in
the CH.airebo file to agree with the original <A HREF = "#Stuart">(Stuart)</A>
paper. Thus the parameters are specific to this potential and the way
it was fit, so modifying the file should be done cautiously.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
mix, shift, table, and tail options.
</P>
<P>These pair styles do not write their information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P><B>Restrictions:</B>
</P>
<P>These pair styles are part of the MANYBODY package. They are only
enabled if LAMMPS was built with that package (which it is by
default). See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info.
</P>
<P>These pair potentials require the <A HREF = "newton.html">newton</A> setting to be
"on" for pair interactions.
</P>
<P>The CH.airebo potential file provided with LAMMPS (see the potentials
directory) is parameterized for metal <A HREF = "units.html">units</A>. You can use
the AIREBO or REBO potential with any LAMMPS units, but you would need
to create your own AIREBO potential file with coefficients listed in
the appropriate units if your simulation doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Stuart"></A>
<P><B>(Stuart)</B> Stuart, Tutein, Harrison, J Chem Phys, 112, 6472-6486
(2000).
</P>
<A NAME = "Brenner"></A>
<P><B>(Brenner)</B> Brenner, Shenderova, Harrison, Stuart, Ni, Sinnott, J
Physics: Condensed Matter, 14, 783-802 (2002).
</P>
</HTML>
diff --git a/doc/pair_airebo.txt b/doc/pair_airebo.txt
index 71c7ea071..8239d42a3 100644
--- a/doc/pair_airebo.txt
+++ b/doc/pair_airebo.txt
@@ -1,187 +1,187 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style airebo command :h3
pair_style airebo/omp command :h3
pair_style rebo command :h3
pair_style rebo/omp command :h3
[Syntax:]
pair_style style cutoff LJ_flag TORSION_flag :pre
style = {airebo} or {rebo}
cutoff = LJ cutoff (sigma scale factor) (AIREBO only)
LJ_flag = 0/1 to turn off/on the LJ term (AIREBO only, optional)
TORSION_flag = 0/1 to turn off/on the torsion term (AIREBO only, optional) :ul
[Examples:]
pair_style airebo 3.0
pair_style airebo 2.5 1 0
pair_coeff * * ../potentials/CH.airebo H C :pre
pair_style rebo
pair_coeff * * ../potentials/CH.airebo H C :pre
[Description:]
The {airebo} pair style computes the Adaptive Intermolecular Reactive
Empirical Bond Order (AIREBO) Potential of "(Stuart)"_#Stuart for a
system of carbon and/or hydrogen atoms. Note that this is the initial
formulation of AIREBO from 2000, not the later formulation. The
{rebo} pair style computes the Reactive Empirical Bond Order (REBO)
Potential of "(Brenner)"_#Brenner. Note that this is the so-called
2nd generation REBO from 2002, not the original REBO from 1990. As
discussed below, 2nd generation REBO is closely related to the intial
AIREBO; it is just a subset of the potential energy terms.
The AIREBO potential consists of three terms:
:c,image(Eqs/pair_airebo.jpg)
By default, all three terms are included. For the {airebo} style, if
the two optional flag arguments to the pair_style command are
included, the LJ and torsional terms can be turned off. Note that
both or neither of the flags must be included. If both of the LJ an
torsional terms are turned off, it becomes the 2nd-generation REBO
potential, with a small caveat on the spline fitting procedure
mentioned below. This can be specified directly as pair_style rebo
with no additional arguments.
The detailed formulas for this potential are given in
"(Stuart)"_#Stuart; here we provide only a brief description.
The E_REBO term has the same functional form as the hydrocarbon REBO
potential developed in "(Brenner)"_#Brenner. The coefficients for
E_REBO in AIREBO are essentially the same as Brenner's potential, but
a few fitted spline values are slightly different. For most cases the
E_REBO term in AIREBO will produce the same energies, forces and
statistical averages as the original REBO potential from which it was
derived. The E_REBO term in the AIREBO potential gives the model its
reactive capabilities and only describes short-ranged C-C, C-H and H-H
interactions (r < 2 Angstroms). These interactions have strong
coordination-dependence through a bond order parameter, which adjusts
the attraction between the I,J atoms based on the position of other
nearby atoms and thus has 3- and 4-body dependence.
The E_LJ term adds longer-ranged interactions (2 < r < cutoff) using a
form similar to the standard "Lennard Jones potential"_pair_lj.html.
The E_LJ term in AIREBO contains a series of switching functions so
that the short-ranged LJ repulsion (1/r^12) does not interfere with
the energetics captured by the E_REBO term. The extent of the E_LJ
interactions is determined by the {cutoff} argument to the pair_style
command which is a scale factor. For each type pair (C-C, C-H, H-H)
the cutoff is obtained by multiplying the scale factor by the sigma
value defined in the potential file for that type pair. In the
standard AIREBO potential, sigma_CC = 3.4 Angstroms, so with a scale
factor of 3.0 (the argument in pair_style), the resulting E_LJ cutoff
would be 10.2 Angstroms.
The E_TORSION term is an explicit 4-body potential that describes
various dihedral angle preferences in hydrocarbon configurations.
Only a single pair_coeff command is used with the {airebo} or {rebo}
style which specifies an AIREBO potential file with parameters for C
and H. Note that the {rebo} style in LAMMPS uses the same
AIREBO-formatted potential file. These are mapped to LAMMPS atom
types by specifying N additional arguments after the filename in the
pair_coeff command, where N is the number of LAMMPS atom types:
filename
N element names = mapping of AIREBO elements to atom types :ul
As an example, if your LAMMPS simulation has 4 atom types and you want
the 1st 3 to be C, and the 4th to be H, you would use the following
pair_coeff command:
pair_coeff * * CH.airebo C C C H :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three C arguments map LAMMPS atom types 1,2,3 to the C
element in the AIREBO file. The final H argument maps LAMMPS atom
type 4 to the H element in the SW file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a {airebo} potential is used as part of the {hybrid} pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
The parameters/coefficients for the AIREBO potentials are listed in
the CH.airebo file to agree with the original "(Stuart)"_#Stuart
paper. Thus the parameters are specific to this potential and the way
it was fit, so modifying the file should be done cautiously.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support the "pair_modify"_pair_modify.html
mix, shift, table, and tail options.
These pair styles do not write their information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
[Restrictions:]
These pair styles are part of the MANYBODY package. They are only
enabled if LAMMPS was built with that package (which it is by
default). See the "Making LAMMPS"_Section_start.html#start_3 section
for more info.
These pair potentials require the "newton"_newton.html setting to be
"on" for pair interactions.
The CH.airebo potential file provided with LAMMPS (see the potentials
directory) is parameterized for metal "units"_units.html. You can use
the AIREBO or REBO potential with any LAMMPS units, but you would need
to create your own AIREBO potential file with coefficients listed in
the appropriate units if your simulation doesn't use "metal" units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Stuart)
[(Stuart)] Stuart, Tutein, Harrison, J Chem Phys, 112, 6472-6486
(2000).
:link(Brenner)
[(Brenner)] Brenner, Shenderova, Harrison, Stuart, Ni, Sinnott, J
Physics: Condensed Matter, 14, 783-802 (2002).
diff --git a/doc/pair_born.html b/doc/pair_born.html
index e5d4038a7..6d5ad8be7 100644
--- a/doc/pair_born.html
+++ b/doc/pair_born.html
@@ -1,164 +1,183 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style born command
</H3>
<H3>pair_style born/omp command
</H3>
<H3>pair_style born/coul/long command
</H3>
<H3>pair_style born/coul/long/cuda command
</H3>
<H3>pair_style born/coul/long/omp command
</H3>
+<H3>pair_style born/coul/wolf command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
-<UL><LI>style = <I>born</I> or <I>born/coul/long</I>
+<UL><LI>style = <I>born</I> or <I>born/coul/long</I> or <I>born/coul/wolf</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>born</I> args = cutoff
cutoff = global cutoff for non-Coulombic interactions (distance units)
<I>born/coul/long</I> args = cutoff (cutoff2)
+ cutoff = global cutoff for non-Coulombic (and Coulombic if only 1 arg) (distance units)
+ cutoff2 = global cutoff for Coulombic (optional) (distance units)
+ <I>born/coul/wolf</I> args = alpha cutoff (cutoff2)
+ alpha = damping parameter (inverse distance units)
cutoff = global cutoff for non-Coulombic (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style born 10.0
pair_coeff * * 6.08 0.317 2.340 24.18 11.51
pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51
</PRE>
<PRE>pair_style born/coul/long 10.0
pair_style born/coul/long 10.0 8.0
pair_coeff * * 6.08 0.317 2.340 24.18 11.51
pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51
</PRE>
+<PRE>pair_style born/coul/wolf 0.25 10.0
+pair_style born/coul/wolf 0.25 10.0 9.0
+pair_coeff * * 6.08 0.317 2.340 24.18 11.51
+pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51
+</PRE>
<P><B>Description:</B>
</P>
<P>The <I>born</I> style computes the Born-Mayer-Huggins or Tosi/Fumi
potential described in <A HREF = "#FumiTosi">(Fumi and Tosi)</A>, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_born.jpg">
</CENTER>
<P>where sigma is an interaction-dependent length parameter, rho is an
ionic-pair dependent length parameter, and Rc is the cutoff.
</P>
<P>The <I>born/coul/long</I> style adds a Coulombic term as described for the
-<A HREF = "pair_lj.html">lj/cut</A> pair styles. An additional damping factor is
-applied to the Coulombic term so it can be used in conjunction with
+<A HREF = "pair_coul.html">coul/long</A> pair style. An additional damping factor
+is applied to the Coulombic term so it can be used in conjunction with
the <A HREF = "kspace_style.html">kspace_style</A> command and its <I>ewald</I> or <I>pppm</I>
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
</P>
+<P>If one cutoff is specified for the <I>born/coul/long</I> style, it is used
+for both the A,C,D and Coulombic terms. If two cutoffs are specified,
+the first is used as the cutoff for the A,C,D terms, and the second is
+the cutoff for the Coulombic term.
+</P>
+<P>The <I>born/coul/wolf</I> style adds a Coulombic term as described for the
+Wolf potential in the <A HREF = "pair_coul.html">coul/wolf</A> pair style.
+</P>
<P>If one cutoff is specified for the <I>born/coulk/long</I> style, it is used
for both the A,C,D and Coulombic terms. If two cutoffs are specified,
the first is used as the cutoff for the A,C,D terms, and the second is
the cutoff for the Coulombic term.
</P>
<P>Note that these potentials are related to the <A HREF = "pair_born.html">Buckingham
potential</A>.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>A (energy units)
<LI>rho (distance units)
<LI>sigma (distance units)
<LI>C (energy units * distance units^6)
<LI>D (energy units * distance units^8)
<LI>cutoff (distance units)
</UL>
<P>The second coefficient, rho, must be greater than zero.
</P>
<P>The last coefficient is optional. If not specified, the global A,C,D
cutoff specified in the pair_style command is used.
</P>
-<P>For <I>buck/coul/long</I> no Coulombic cutoff can be specified for an
-individual I,J type pair. All type pairs use the same global
-Coulombic cutoff specified in the pair_style command.
+<P>For <I>buck/coul/long</I> and <I>born/coul/wolf</I> no Coulombic cutoff can be
+specified for an individual I,J type pair. All type pairs use the
+same global Coulombic cutoff specified in the pair_style command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>These styles support the <A HREF = "pair_modify.html">pair_modify</A> shift option
for the energy of the exp(), 1/r^6, and 1/r^8 portion of the pair
interaction.
</P>
<P>The <I>born/coul/long</I> pair style does not support the
<A HREF = "pair_modify.html">pair_modify</A> table option since a tabulation
capability has not yet been added to this potential.
</P>
<P>These styles support the pair_modify tail option for adding long-range
tail corrections to energy and pressure.
</P>
<P>Thess styles writes thei information to binary <A HREF = "restart.html">restart</A>
files, so pair_style and pair_coeff commands do not need to be
specified in an input script that reads a restart file.
</P>
<P>These styles can only be used via the <I>pair</I> keyword of the <A HREF = "run_style.html">run_style
respa</A> command. They do not support the <I>inner</I>,
<I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>born/coul/long</I> style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_buck.html">pair_style buck</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "FumiTosi"></A>
<P>Fumi and Tosi, J Phys Chem Solids, 25, 31 (1964),
Fumi and Tosi, J Phys Chem Solids, 25, 45 (1964).
</P>
</HTML>
diff --git a/doc/pair_born.txt b/doc/pair_born.txt
index 652e7b4dd..99b0a56c2 100644
--- a/doc/pair_born.txt
+++ b/doc/pair_born.txt
@@ -1,154 +1,172 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style born command :h3
pair_style born/omp command :h3
pair_style born/coul/long command :h3
pair_style born/coul/long/cuda command :h3
pair_style born/coul/long/omp command :h3
+pair_style born/coul/wolf command :h3
[Syntax:]
pair_style style args :pre
-style = {born} or {born/coul/long}
+style = {born} or {born/coul/long} or {born/coul/wolf}
args = list of arguments for a particular style :ul
{born} args = cutoff
cutoff = global cutoff for non-Coulombic interactions (distance units)
{born/coul/long} args = cutoff (cutoff2)
+ cutoff = global cutoff for non-Coulombic (and Coulombic if only 1 arg) (distance units)
+ cutoff2 = global cutoff for Coulombic (optional) (distance units)
+ {born/coul/wolf} args = alpha cutoff (cutoff2)
+ alpha = damping parameter (inverse distance units)
cutoff = global cutoff for non-Coulombic (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
[Examples:]
pair_style born 10.0
pair_coeff * * 6.08 0.317 2.340 24.18 11.51
pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51 :pre
pair_style born/coul/long 10.0
pair_style born/coul/long 10.0 8.0
pair_coeff * * 6.08 0.317 2.340 24.18 11.51
pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51 :pre
+pair_style born/coul/wolf 0.25 10.0
+pair_style born/coul/wolf 0.25 10.0 9.0
+pair_coeff * * 6.08 0.317 2.340 24.18 11.51
+pair_coeff 1 1 6.08 0.317 2.340 24.18 11.51 :pre
+
[Description:]
The {born} style computes the Born-Mayer-Huggins or Tosi/Fumi
potential described in "(Fumi and Tosi)"_#FumiTosi, given by
:c,image(Eqs/pair_born.jpg)
where sigma is an interaction-dependent length parameter, rho is an
ionic-pair dependent length parameter, and Rc is the cutoff.
The {born/coul/long} style adds a Coulombic term as described for the
-"lj/cut"_pair_lj.html pair styles. An additional damping factor is
-applied to the Coulombic term so it can be used in conjunction with
+"coul/long"_pair_coul.html pair style. An additional damping factor
+is applied to the Coulombic term so it can be used in conjunction with
the "kspace_style"_kspace_style.html command and its {ewald} or {pppm}
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
+If one cutoff is specified for the {born/coul/long} style, it is used
+for both the A,C,D and Coulombic terms. If two cutoffs are specified,
+the first is used as the cutoff for the A,C,D terms, and the second is
+the cutoff for the Coulombic term.
+
+The {born/coul/wolf} style adds a Coulombic term as described for the
+Wolf potential in the "coul/wolf"_pair_coul.html pair style.
+
If one cutoff is specified for the {born/coulk/long} style, it is used
for both the A,C,D and Coulombic terms. If two cutoffs are specified,
the first is used as the cutoff for the A,C,D terms, and the second is
the cutoff for the Coulombic term.
Note that these potentials are related to the "Buckingham
potential"_pair_born.html.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
A (energy units)
rho (distance units)
sigma (distance units)
C (energy units * distance units^6)
D (energy units * distance units^8)
cutoff (distance units) :ul
The second coefficient, rho, must be greater than zero.
The last coefficient is optional. If not specified, the global A,C,D
cutoff specified in the pair_style command is used.
-For {buck/coul/long} no Coulombic cutoff can be specified for an
-individual I,J type pair. All type pairs use the same global
-Coulombic cutoff specified in the pair_style command.
+For {buck/coul/long} and {born/coul/wolf} no Coulombic cutoff can be
+specified for an individual I,J type pair. All type pairs use the
+same global Coulombic cutoff specified in the pair_style command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
These styles support the "pair_modify"_pair_modify.html shift option
for the energy of the exp(), 1/r^6, and 1/r^8 portion of the pair
interaction.
The {born/coul/long} pair style does not support the
"pair_modify"_pair_modify.html table option since a tabulation
capability has not yet been added to this potential.
These styles support the pair_modify tail option for adding long-range
tail corrections to energy and pressure.
Thess styles writes thei information to binary "restart"_restart.html
files, so pair_style and pair_coeff commands do not need to be
specified in an input script that reads a restart file.
These styles can only be used via the {pair} keyword of the "run_style
respa"_run_style.html command. They do not support the {inner},
{middle}, {outer} keywords.
:line
[Restrictions:]
The {born/coul/long} style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the "Making LAMMPS"_Section_start.html#start_3 section
for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_style buck"_pair_buck.html
[Default:] none
:line
:link(FumiTosi)
Fumi and Tosi, J Phys Chem Solids, 25, 31 (1964),
Fumi and Tosi, J Phys Chem Solids, 25, 45 (1964).
diff --git a/doc/pair_buck.html b/doc/pair_buck.html
index a7b8c76aa..8c0d4f27f 100644
--- a/doc/pair_buck.html
+++ b/doc/pair_buck.html
@@ -1,178 +1,178 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style buck command
</H3>
<H3>pair_style buck/cuda command
</H3>
<H3>pair_style buck/omp command
</H3>
<H3>pair_style buck/coul/cut command
</H3>
<H3>pair_style buck/coul/cut/cuda command
</H3>
<H3>pair_style buck/coul/cut/omp command
</H3>
<H3>pair_style buck/coul/long command
</H3>
<H3>pair_style buck/coul/long/cuda command
</H3>
<H3>pair_style buck/coul/long/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = <I>buck</I> or <I>buck/coul/cut</I> or <I>buck/coul/long</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>buck</I> args = cutoff
cutoff = global cutoff for Buckingham interactions (distance units)
<I>buck/coul/cut</I> args = cutoff (cutoff2)
cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
<I>buck/coul/long</I> args = cutoff (cutoff2)
cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style buck 2.5
pair_coeff * * 100.0 1.5 200.0
pair_coeff * * 100.0 1.5 200.0 3.0
</PRE>
<PRE>pair_style buck/coul/cut 10.0
pair_style buck/coul/cut 10.0 8.0
pair_coeff * * 100.0 1.5 200.0
pair_coeff 1 1 100.0 1.5 200.0 9.0
pair_coeff 1 1 100.0 1.5 200.0 9.0 8.0
</PRE>
<PRE>pair_style buck/coul/long 10.0
pair_style buck/coul/long 10.0 8.0
pair_coeff * * 100.0 1.5 200.0
pair_coeff 1 1 100.0 1.5 200.0 9.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>buck</I> style computes a Buckingham potential (exp/6 instead of
Lennard-Jones 12/6) given by
</P>
<CENTER><IMG SRC = "Eqs/pair_buck.jpg">
</CENTER>
<P>where rho is an ionic-pair dependent length parameter, and Rc is the
cutoff.
</P>
<P>The <I>buck/coul/cut</I> and <I>buck/coul/long</I> styles add a Coulombic term
as described for the <A HREF = "pair_lj.html">lj/cut</A> pair styles. For
<I>buck/coul/long</I>, an additional damping factor is applied to the
Coulombic term so it can be used in conjunction with the
<A HREF = "kspace_style.html">kspace_style</A> command and its <I>ewald</I> or <I>pppm</I>
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
</P>
<P>If one cutoff is specified for the <I>born/coul/cut</I> and
<I>born/coulk/long</I> styles, it is used for both the A,C and Coulombic
terms. If two cutoffs are specified, the first is used as the cutoff
for the A,C terms, and the second is the cutoff for the Coulombic
term.
</P>
<P>Note that these potentials are related to the <A HREF = "pair_born.html">Born-Mayer-Huggins
potential</A>.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>A (energy units)
<LI>rho (distance units)
<LI>C (energy-distance^6 units)
<LI>cutoff (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>The second coefficient, rho, must be greater than zero.
</P>
<P>The latter 2 coefficients are optional. If not specified, the global
A,C and Coulombic cutoffs are used. If only one cutoff is specified,
it is used as the cutoff for both A,C and Coulombic interactions for
this type pair. If both coefficients are specified, they are used as
the A,C and Coulombic cutoffs for this type pair. You cannot specify
2 cutoffs for style <I>buck</I>, since it has no Coulombic terms.
</P>
<P>For <I>buck/coul/long</I> only the LJ cutoff can be specified since a
Coulombic cutoff cannot be specified for an individual I,J type pair.
All type pairs use the same global Coulombic cutoff specified in the
pair_style command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>These styles support the <A HREF = "pair_modify.html">pair_modify</A> shift option
for the energy of the exp() and 1/r^6 portion of the pair interaction.
</P>
<P>The <I>buck/coul/long</I> pair style does not support the
<A HREF = "pair_modify.html">pair_modify</A> table option since a tabulation
capability has not yet been added to this potential.
</P>
<P>These styles support the pair_modify tail option for adding long-range
tail corrections to energy and pressure for the A,C terms in the
pair interaction.
</P>
<P>These styles write their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>These styles can only be used via the <I>pair</I> keyword of the <A HREF = "run_style.html">run_style
respa</A> command. They do not support the <I>inner</I>,
<I>middle</I>, <I>outer</I> keywords.
</P>
<P><B>Restrictions:</B>
</P>
<P>The <I>buck/coul/long</I> style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_born.html">pair_style born</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_buck.txt b/doc/pair_buck.txt
index 1f875f9ac..94e42ac20 100644
--- a/doc/pair_buck.txt
+++ b/doc/pair_buck.txt
@@ -1,164 +1,164 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style buck command :h3
pair_style buck/cuda command :h3
pair_style buck/omp command :h3
pair_style buck/coul/cut command :h3
pair_style buck/coul/cut/cuda command :h3
pair_style buck/coul/cut/omp command :h3
pair_style buck/coul/long command :h3
pair_style buck/coul/long/cuda command :h3
pair_style buck/coul/long/omp command :h3
[Syntax:]
pair_style style args :pre
style = {buck} or {buck/coul/cut} or {buck/coul/long}
args = list of arguments for a particular style :ul
{buck} args = cutoff
cutoff = global cutoff for Buckingham interactions (distance units)
{buck/coul/cut} args = cutoff (cutoff2)
cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
{buck/coul/long} args = cutoff (cutoff2)
cutoff = global cutoff for Buckingham (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
[Examples:]
pair_style buck 2.5
pair_coeff * * 100.0 1.5 200.0
pair_coeff * * 100.0 1.5 200.0 3.0 :pre
pair_style buck/coul/cut 10.0
pair_style buck/coul/cut 10.0 8.0
pair_coeff * * 100.0 1.5 200.0
pair_coeff 1 1 100.0 1.5 200.0 9.0
pair_coeff 1 1 100.0 1.5 200.0 9.0 8.0 :pre
pair_style buck/coul/long 10.0
pair_style buck/coul/long 10.0 8.0
pair_coeff * * 100.0 1.5 200.0
pair_coeff 1 1 100.0 1.5 200.0 9.0 :pre
[Description:]
The {buck} style computes a Buckingham potential (exp/6 instead of
Lennard-Jones 12/6) given by
:c,image(Eqs/pair_buck.jpg)
where rho is an ionic-pair dependent length parameter, and Rc is the
cutoff.
The {buck/coul/cut} and {buck/coul/long} styles add a Coulombic term
as described for the "lj/cut"_pair_lj.html pair styles. For
{buck/coul/long}, an additional damping factor is applied to the
Coulombic term so it can be used in conjunction with the
"kspace_style"_kspace_style.html command and its {ewald} or {pppm}
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
If one cutoff is specified for the {born/coul/cut} and
{born/coulk/long} styles, it is used for both the A,C and Coulombic
terms. If two cutoffs are specified, the first is used as the cutoff
for the A,C terms, and the second is the cutoff for the Coulombic
term.
Note that these potentials are related to the "Born-Mayer-Huggins
potential"_pair_born.html.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
A (energy units)
rho (distance units)
C (energy-distance^6 units)
cutoff (distance units)
cutoff2 (distance units) :ul
The second coefficient, rho, must be greater than zero.
The latter 2 coefficients are optional. If not specified, the global
A,C and Coulombic cutoffs are used. If only one cutoff is specified,
it is used as the cutoff for both A,C and Coulombic interactions for
this type pair. If both coefficients are specified, they are used as
the A,C and Coulombic cutoffs for this type pair. You cannot specify
2 cutoffs for style {buck}, since it has no Coulombic terms.
For {buck/coul/long} only the LJ cutoff can be specified since a
Coulombic cutoff cannot be specified for an individual I,J type pair.
All type pairs use the same global Coulombic cutoff specified in the
pair_style command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
These styles support the "pair_modify"_pair_modify.html shift option
for the energy of the exp() and 1/r^6 portion of the pair interaction.
The {buck/coul/long} pair style does not support the
"pair_modify"_pair_modify.html table option since a tabulation
capability has not yet been added to this potential.
These styles support the pair_modify tail option for adding long-range
tail corrections to energy and pressure for the A,C terms in the
pair interaction.
These styles write their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
These styles can only be used via the {pair} keyword of the "run_style
respa"_run_style.html command. They do not support the {inner},
{middle}, {outer} keywords.
[Restrictions:]
The {buck/coul/long} style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the "Making LAMMPS"_Section_start.html#start_3 section
for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_style born"_pair_born.html
[Default:] none
diff --git a/doc/pair_buck_coul.html b/doc/pair_buck_coul.html
index 149fe36e3..863850dbc 100644
--- a/doc/pair_buck_coul.html
+++ b/doc/pair_buck_coul.html
@@ -1,178 +1,178 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style buck/coul command
</H3>
<H3>pair_style buck/coul/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style buck/coul flag_buck flag_coul cutoff (cutoff2)
</PRE>
<UL><LI>flag_buck = <I>long</I> or <I>cut</I>
<PRE> <I>long</I> = use Kspace long-range summation for the dispersion term 1/r^6
<I>cut</I> = use a cutoff
</PRE>
<LI>flag_coul = <I>long</I> or <I>off</I>
<PRE> <I>long</I> = use Kspace long-range summation for the Coulombic term 1/r
<I>off</I> = omit the Coulombic term
</PRE>
<LI>cutoff = global cutoff for Buckingham (and Coulombic if only 1 cutoff) (distance units)
<LI>cutoff2 = global cutoff for Coulombic (optional) (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style buck/coul cut off 2.5
pair_style buck/coul cut long 2.5 4.0
pair_style buck/coul long long 2.5 4.0
pair_coeff * * 1 1
pair_coeff 1 1 1 3 4
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>buck/coul</I> style computes a Buckingham potential (exp/6 instead of
Lennard-Jones 12/6) and Coulombic potential, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_buck.jpg">
</CENTER>
<CENTER><IMG SRC = "Eqs/pair_coulomb.jpg">
</CENTER>
<P>Rc is the cutoff. If one cutoff is specified in the pair_style
command, it is used for both the Buckingham and Coulombic terms. If
two cutoffs are specified, they are used as cutoffs for the Buckingham
and Coulombic terms respectively.
</P>
<P>The purpose of this pair style is to capture long-range interactions
resulting from both attractive 1/r^6 Buckingham and Coulombic 1/r
interactions. This is done by use of the <I>flag_buck</I> and <I>flag_coul</I>
settings. The "<A HREF = "#Ismail">Ismail</A> paper has more details on when it is
appropriate to include long-range 1/r^6 interactions, using this
potential.
</P>
<P>If <I>flag_buck</I> is set to <I>long</I>, no cutoff is used on the Buckingham
1/r^6 dispersion term. The long-range portion is calculated by using
the <A HREF = "kspace_style.html">kspace_style ewald/n</A> command. The specified
Buckingham cutoff then determines which portion of the Buckingham
interactions are computed directly by the pair potential versus which
part is computed in reciprocal space via the Kspace style. If
<I>flag_buck</I> is set to <I>cut</I>, the Buckingham interactions are simply
cutoff, as with <A HREF = "pair_buck.html">pair_style buck</A>.
</P>
<P>If <I>flag_coul</I> is set to <I>long</I>, no cutoff is used on the Coulombic
interactions. The long-range portion is calculated by using any
style, including <I>ewald/n</I> of the <A HREF = "kspace_style.html">kspace_style</A>
command. Note that if <I>flag_buck</I> is also set to long, then only the
<I>ewald/n</I> Kspace style can perform the long-range calculations for
both the Buckingham and Coulombic interactions. If <I>flag_coul</I> is set
to <I>off</I>, Coulombic interactions are not computed.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>A (energy units)
<LI>rho (distance units)
<LI>C (energy-distance^6 units)
<LI>cutoff (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>The second coefficient, rho, must be greater than zero.
</P>
<P>The latter 2 coefficients are optional. If not specified, the global
Buckingham and Coulombic cutoffs specified in the pair_style command
are used. If only one cutoff is specified, it is used as the cutoff
for both Buckingham and Coulombic interactions for this type pair. If
both coefficients are specified, they are used as the Buckingham and
Coulombic cutoffs for this type pair. Note that if you are using
<I>flag_buck</I> set to <I>long</I>, you cannot specify a Buckingham cutoff for
an atom type pair, since only one global Buckingham cutoff is allowed.
Similarly, if you are using <I>flag_coul</I> set to <I>long</I>, you cannot
specify a Coulombic cutoff for an atom type pair, since only one
global Coulombic cutoff is allowed.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>This pair styles does not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the exp() and 1/r^6 portion of the pair
interaction, assuming <I>flag_buck</I> is <I>cut</I>.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option for the energy of the Buckingham portion of the pair
interaction.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
table option since a tabulation capability has not yet been added to
this potential.
</P>
<P>This pair style write its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style supports the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I>
keywords of the <A HREF = "run_style.html">run_style respa</A> command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the <A HREF = "run_style.html">run_style</A> command for
details.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the USER-EWALDN package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Ismail"></A>
<P><B>(Ismail)</B> Ismail, Tsige, In 't Veld, Grest, Molecular Physics
(accepted) (2007).
</P>
</HTML>
diff --git a/doc/pair_buck_coul.txt b/doc/pair_buck_coul.txt
index 4db211709..e6eaf14ba 100644
--- a/doc/pair_buck_coul.txt
+++ b/doc/pair_buck_coul.txt
@@ -1,166 +1,166 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style buck/coul command :h3
pair_style buck/coul/omp command :h3
[Syntax:]
pair_style buck/coul flag_buck flag_coul cutoff (cutoff2) :pre
flag_buck = {long} or {cut} :ulb,l
{long} = use Kspace long-range summation for the dispersion term 1/r^6
{cut} = use a cutoff :pre
flag_coul = {long} or {off} :l
{long} = use Kspace long-range summation for the Coulombic term 1/r
{off} = omit the Coulombic term :pre
cutoff = global cutoff for Buckingham (and Coulombic if only 1 cutoff) (distance units) :l
cutoff2 = global cutoff for Coulombic (optional) (distance units) :l,ule
[Examples:]
pair_style buck/coul cut off 2.5
pair_style buck/coul cut long 2.5 4.0
pair_style buck/coul long long 2.5 4.0
pair_coeff * * 1 1
pair_coeff 1 1 1 3 4 :pre
[Description:]
The {buck/coul} style computes a Buckingham potential (exp/6 instead of
Lennard-Jones 12/6) and Coulombic potential, given by
:c,image(Eqs/pair_buck.jpg)
:c,image(Eqs/pair_coulomb.jpg)
Rc is the cutoff. If one cutoff is specified in the pair_style
command, it is used for both the Buckingham and Coulombic terms. If
two cutoffs are specified, they are used as cutoffs for the Buckingham
and Coulombic terms respectively.
The purpose of this pair style is to capture long-range interactions
resulting from both attractive 1/r^6 Buckingham and Coulombic 1/r
interactions. This is done by use of the {flag_buck} and {flag_coul}
settings. The ""Ismail"_#Ismail paper has more details on when it is
appropriate to include long-range 1/r^6 interactions, using this
potential.
If {flag_buck} is set to {long}, no cutoff is used on the Buckingham
1/r^6 dispersion term. The long-range portion is calculated by using
the "kspace_style ewald/n"_kspace_style.html command. The specified
Buckingham cutoff then determines which portion of the Buckingham
interactions are computed directly by the pair potential versus which
part is computed in reciprocal space via the Kspace style. If
{flag_buck} is set to {cut}, the Buckingham interactions are simply
cutoff, as with "pair_style buck"_pair_buck.html.
If {flag_coul} is set to {long}, no cutoff is used on the Coulombic
interactions. The long-range portion is calculated by using any
style, including {ewald/n} of the "kspace_style"_kspace_style.html
command. Note that if {flag_buck} is also set to long, then only the
{ewald/n} Kspace style can perform the long-range calculations for
both the Buckingham and Coulombic interactions. If {flag_coul} is set
to {off}, Coulombic interactions are not computed.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
A (energy units)
rho (distance units)
C (energy-distance^6 units)
cutoff (distance units)
cutoff2 (distance units) :ul
The second coefficient, rho, must be greater than zero.
The latter 2 coefficients are optional. If not specified, the global
Buckingham and Coulombic cutoffs specified in the pair_style command
are used. If only one cutoff is specified, it is used as the cutoff
for both Buckingham and Coulombic interactions for this type pair. If
both coefficients are specified, they are used as the Buckingham and
Coulombic cutoffs for this type pair. Note that if you are using
{flag_buck} set to {long}, you cannot specify a Buckingham cutoff for
an atom type pair, since only one global Buckingham cutoff is allowed.
Similarly, if you are using {flag_coul} set to {long}, you cannot
specify a Coulombic cutoff for an atom type pair, since only one
global Coulombic cutoff is allowed.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
This pair styles does not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the exp() and 1/r^6 portion of the pair
interaction, assuming {flag_buck} is {cut}.
This pair style does not support the "pair_modify"_pair_modify.html
shift option for the energy of the Buckingham portion of the pair
interaction.
This pair style does not support the "pair_modify"_pair_modify.html
table option since a tabulation capability has not yet been added to
this potential.
This pair style write its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style supports the use of the {inner}, {middle}, and {outer}
keywords of the "run_style respa"_run_style.html command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the "run_style"_run_style.html command for
details.
:line
[Restrictions:]
This style is part of the USER-EWALDN package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Ismail)
[(Ismail)] Ismail, Tsige, In 't Veld, Grest, Molecular Physics
(accepted) (2007).
diff --git a/doc/pair_charmm.html b/doc/pair_charmm.html
index 50dcbe5e7..43fb29de6 100644
--- a/doc/pair_charmm.html
+++ b/doc/pair_charmm.html
@@ -1,204 +1,212 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/charmm/coul/charmm command
</H3>
<H3>pair_style lj/charmm/coul/charmm/cuda command
</H3>
<H3>pair_style lj/charmm/coul/charmm/omp command
</H3>
<H3>pair_style lj/charmm/coul/charmm/implicit command
</H3>
<H3>pair_style lj/charmm/coul/charmm/implicit/cuda command
</H3>
<H3>pair_style lj/charmm/coul/charmm/implicit/omp command
</H3>
<H3>pair_style lj/charmm/coul/long command
</H3>
<H3>pair_style lj/charmm/coul/long/cuda command
</H3>
<H3>pair_style lj/charmm/coul/long/gpu command
</H3>
<H3>pair_style lj/charmm/coul/long/opt command
</H3>
<H3>pair_style lj/charmm/coul/long/omp command
</H3>
+<H3>pair_style lj/charmm/coul/pppm/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = <I>lj/charmm/coul/charmm</I> or <I>lj/charmm/coul/charmm/implicit</I> or <I>lj/charmm/coul/long</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>lj/charmm/coul/charmm</I> args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for Lennard Jones (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional)
<I>lj/charmm/coul/charmm/implicit</I> args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for LJ (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional)
<I>lj/charmm/coul/long</I> args = inner outer (cutoff)
inner, outer = global switching cutoffs for LJ (and Coulombic if only 2 args)
cutoff = global cutoff for Coulombic (optional, outer is Coulombic cutoff if only 2 args)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/charmm/coul/charmm 8.0 10.0
pair_style lj/charmm/coul/charmm 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5
</PRE>
<PRE>pair_style lj/charmm/coul/charmm/implicit 8.0 10.0
pair_style lj/charmm/coul/charmm/implicit 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5
</PRE>
<PRE>pair_style lj/charmm/coul/long 8.0 10.0
pair_style lj/charmm/coul/long 8.0 10.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/charmm</I> styles compute LJ and Coulombic interactions with an
additional switching function S(r) that ramps the energy and force
smoothly to zero between an inner and outer cutoff. It is a widely
used potential in the <A HREF = "http://www.scripps.edu/brooks">CHARMM</A> MD code.
See <A HREF = "#MacKerell">(MacKerell)</A> for a description of the CHARMM force
field.
</P>
<CENTER><IMG SRC = "Eqs/pair_charmm.jpg">
</CENTER>
<P>Both the LJ and Coulombic terms require an inner and outer cutoff.
They can be the same for both formulas or different depending on
whether 2 or 4 arguments are used in the pair_style command. In each
case, the inner cutoff distance must be less than the outer cutoff.
It it typical to make the difference between the 2 cutoffs about 1.0
Angstrom.
</P>
<P>Style <I>lj/charmm/coul/charmm/implicit</I> computes the same formulas as
style <I>lj/charmm/coul/charmm</I> except that an additional 1/r term is
included in the Coulombic formula. The Coulombic energy thus varies
as 1/r^2. This is effectively a distance-dependent dielectric term
which is a simple model for an implicit solvent with additional
screening. It is designed for use in a simulation of an unsolvated
biomolecule (no explicit water molecules).
</P>
-<P>Style <I>lj/charmm/coul/long</I> computes the same formulas as style
-<I>lj/charmm/coul/charmm</I> except that an additional damping factor is
-applied to the Coulombic term, as in the discussion for pair style
-<I>lj/cut/coul/long</I>. Only one Coulombic cutoff is specified for
-<I>lj/charmm/coul/long</I>; if only 2 arguments are used in the pair_style
-command, then the outer LJ cutoff is used as the single Coulombic
-cutoff.
+<P>Styles <I>lj/charmm/coul/long</I> and <I>lj/charmm/coul/pppm/omp</I> compute
+the same formulas as style <I>lj/charmm/coul/charmm</I> except that an
+additional damping factor is applied to the Coulombic term, as in
+the discussion for pair style <I>lj/cut/coul/long</I>. Only one Coulombic
+cutoff is specified for <I>lj/charmm/coul/long</I>; if only 2 arguments
+are used in the pair_style command, then the outer LJ cutoff is
+used as the single Coulombic cutoff. Style <I>lj/charmm/coul/pppm/omp</I>
+is a variant for use with K-space style <A HREF = "kspace_style.html"><I>pppm/proxy</I></A>
+and OpenMP multi-threading and will perform the corresponding
+reciprocal space calculation concurrently with the pair calculation
+in a separate thread. For certain parallel setups, this may have
+a performance benefit over performing k-space style and pair style
+separately and one after the other.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>epsilon_14 (energy units)
<LI>sigma_14 (distance units)
</UL>
<P>Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
</P>
<P>The latter 2 coefficients are optional. If they are specified, they
are used in the LJ formula between 2 atoms of these types which are
also first and fourth atoms in any dihedral. No cutoffs are specified
because this CHARMM force field does not allow varying cutoffs for
individual atom pairs; all pairs use the global cutoff(s) specified in
the pair_style command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon, sigma, epsilon_14,
and sigma_14 coefficients for all of the lj/charmm pair styles can be
mixed. The default mix value is <I>arithmetic</I> to coincide with the
usual settings for the CHARMM force field. See the "pair_modify"
command for details.
</P>
<P>None of the lj/charmm pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> shift option, since the Lennard-Jones
portion of the pair interaction is smoothed to 0.0 at the cutoff.
</P>
<P>The <I>lj/charmm/coul/long</I> style supports the
<A HREF = "pair_modify.html">pair_modify</A> table option since it can tabulate the
short-range portion of the long-range Coulombic interaction.
</P>
<P>None of the lj/charmm pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> tail option for adding long-range tail
corrections to energy and pressure, since the Lennard-Jones portion of
the pair interaction is smoothed to 0.0 at the cutoff.
</P>
<P>All of the lj/charmm pair styles write their information to <A HREF = "restart.html">binary
restart files</A>, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
</P>
<P>The lj/charmm/coul/long pair style supports the use of the <I>inner</I>,
<I>middle</I>, and <I>outer</I> keywords of the <A HREF = "run_style.html">run_style respa</A>
command, meaning the pairwise forces can be partitioned by distance at
different levels of the rRESPA hierarchy. The other styles only
support the <I>pair</I> keyword of run_style respa. See the
<A HREF = "run_style.html">run_style</A> command for details.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>lj/charmm/coul/charmm</I> and <I>lj/charmm/coul/charmm/implicit</I>
styles are part of the MOLECULE package. The <I>lj/charmm/coul/long</I>
style is part of the KSPACE package. They are only enabled if LAMMPS
was built with those packages. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info. Note that
the MOLECULE and KSPACE packages are installed by default.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "MacKerell"></A>
<P><B>(MacKerell)</B> MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
</P>
</HTML>
diff --git a/doc/pair_charmm.txt b/doc/pair_charmm.txt
index 08fe29257..bafeed18d 100644
--- a/doc/pair_charmm.txt
+++ b/doc/pair_charmm.txt
@@ -1,187 +1,194 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/charmm/coul/charmm command :h3
pair_style lj/charmm/coul/charmm/cuda command :h3
pair_style lj/charmm/coul/charmm/omp command :h3
pair_style lj/charmm/coul/charmm/implicit command :h3
pair_style lj/charmm/coul/charmm/implicit/cuda command :h3
pair_style lj/charmm/coul/charmm/implicit/omp command :h3
pair_style lj/charmm/coul/long command :h3
pair_style lj/charmm/coul/long/cuda command :h3
pair_style lj/charmm/coul/long/gpu command :h3
pair_style lj/charmm/coul/long/opt command :h3
pair_style lj/charmm/coul/long/omp command :h3
+pair_style lj/charmm/coul/pppm/omp command :h3
[Syntax:]
pair_style style args :pre
style = {lj/charmm/coul/charmm} or {lj/charmm/coul/charmm/implicit} or {lj/charmm/coul/long}
args = list of arguments for a particular style :ul
{lj/charmm/coul/charmm} args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for Lennard Jones (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional)
{lj/charmm/coul/charmm/implicit} args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for LJ (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional)
{lj/charmm/coul/long} args = inner outer (cutoff)
inner, outer = global switching cutoffs for LJ (and Coulombic if only 2 args)
cutoff = global cutoff for Coulombic (optional, outer is Coulombic cutoff if only 2 args) :pre
[Examples:]
pair_style lj/charmm/coul/charmm 8.0 10.0
pair_style lj/charmm/coul/charmm 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5 :pre
pair_style lj/charmm/coul/charmm/implicit 8.0 10.0
pair_style lj/charmm/coul/charmm/implicit 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5 :pre
pair_style lj/charmm/coul/long 8.0 10.0
pair_style lj/charmm/coul/long 8.0 10.0 9.0
pair_coeff * * 100.0 2.0
pair_coeff 1 1 100.0 2.0 150.0 3.5 :pre
[Description:]
The {lj/charmm} styles compute LJ and Coulombic interactions with an
additional switching function S(r) that ramps the energy and force
smoothly to zero between an inner and outer cutoff. It is a widely
used potential in the "CHARMM"_http://www.scripps.edu/brooks MD code.
See "(MacKerell)"_#MacKerell for a description of the CHARMM force
field.
:c,image(Eqs/pair_charmm.jpg)
Both the LJ and Coulombic terms require an inner and outer cutoff.
They can be the same for both formulas or different depending on
whether 2 or 4 arguments are used in the pair_style command. In each
case, the inner cutoff distance must be less than the outer cutoff.
It it typical to make the difference between the 2 cutoffs about 1.0
Angstrom.
Style {lj/charmm/coul/charmm/implicit} computes the same formulas as
style {lj/charmm/coul/charmm} except that an additional 1/r term is
included in the Coulombic formula. The Coulombic energy thus varies
as 1/r^2. This is effectively a distance-dependent dielectric term
which is a simple model for an implicit solvent with additional
screening. It is designed for use in a simulation of an unsolvated
biomolecule (no explicit water molecules).
-Style {lj/charmm/coul/long} computes the same formulas as style
-{lj/charmm/coul/charmm} except that an additional damping factor is
-applied to the Coulombic term, as in the discussion for pair style
-{lj/cut/coul/long}. Only one Coulombic cutoff is specified for
-{lj/charmm/coul/long}; if only 2 arguments are used in the pair_style
-command, then the outer LJ cutoff is used as the single Coulombic
-cutoff.
+Styles {lj/charmm/coul/long} and {lj/charmm/coul/pppm/omp} compute
+the same formulas as style {lj/charmm/coul/charmm} except that an
+additional damping factor is applied to the Coulombic term, as in
+the discussion for pair style {lj/cut/coul/long}. Only one Coulombic
+cutoff is specified for {lj/charmm/coul/long}; if only 2 arguments
+are used in the pair_style command, then the outer LJ cutoff is
+used as the single Coulombic cutoff. Style {lj/charmm/coul/pppm/omp}
+is a variant for use with K-space style "{pppm/proxy}"_kspace_style.html
+and OpenMP multi-threading and will perform the corresponding
+reciprocal space calculation concurrently with the pair calculation
+in a separate thread. For certain parallel setups, this may have
+a performance benefit over performing k-space style and pair style
+separately and one after the other.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
epsilon_14 (energy units)
sigma_14 (distance units) :ul
Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
The latter 2 coefficients are optional. If they are specified, they
are used in the LJ formula between 2 atoms of these types which are
also first and fourth atoms in any dihedral. No cutoffs are specified
because this CHARMM force field does not allow varying cutoffs for
individual atom pairs; all pairs use the global cutoff(s) specified in
the pair_style command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon, sigma, epsilon_14,
and sigma_14 coefficients for all of the lj/charmm pair styles can be
mixed. The default mix value is {arithmetic} to coincide with the
usual settings for the CHARMM force field. See the "pair_modify"
command for details.
None of the lj/charmm pair styles support the
"pair_modify"_pair_modify.html shift option, since the Lennard-Jones
portion of the pair interaction is smoothed to 0.0 at the cutoff.
The {lj/charmm/coul/long} style supports the
"pair_modify"_pair_modify.html table option since it can tabulate the
short-range portion of the long-range Coulombic interaction.
None of the lj/charmm pair styles support the
"pair_modify"_pair_modify.html tail option for adding long-range tail
corrections to energy and pressure, since the Lennard-Jones portion of
the pair interaction is smoothed to 0.0 at the cutoff.
All of the lj/charmm pair styles write their information to "binary
restart files"_restart.html, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
The lj/charmm/coul/long pair style supports the use of the {inner},
{middle}, and {outer} keywords of the "run_style respa"_run_style.html
command, meaning the pairwise forces can be partitioned by distance at
different levels of the rRESPA hierarchy. The other styles only
support the {pair} keyword of run_style respa. See the
"run_style"_run_style.html command for details.
:line
[Restrictions:]
The {lj/charmm/coul/charmm} and {lj/charmm/coul/charmm/implicit}
styles are part of the MOLECULE package. The {lj/charmm/coul/long}
style is part of the KSPACE package. They are only enabled if LAMMPS
was built with those packages. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info. Note that
the MOLECULE and KSPACE packages are installed by default.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(MacKerell)
[(MacKerell)] MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
diff --git a/doc/pair_class2.html b/doc/pair_class2.html
index b4fc59715..3afbdf6f7 100644
--- a/doc/pair_class2.html
+++ b/doc/pair_class2.html
@@ -1,187 +1,187 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/class2 command
</H3>
<H3>pair_style lj/class2/cuda command
</H3>
<H3>pair_style lj/class2/gpu command
</H3>
<H3>pair_style lj/class2/omp command
</H3>
<H3>pair_style lj/class2/coul/cut command
</H3>
<H3>pair_style lj/class2/coul/cut/cuda command
</H3>
<H3>pair_style lj/class2/coul/cut/omp command
</H3>
<H3>pair_style lj/class2/coul/long command
</H3>
<H3>pair_style lj/class2/coul/long/cuda command
</H3>
<H3>pair_style lj/class2/coul/long/gpu command
</H3>
<H3>pair_style lj/class2/coul/long/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = <I>lj/class2</I> or <I>lj/class2/coul/cut</I> or <I>lj/class2/coul/long</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>lj/class2</I> args = cutoff
cutoff = global cutoff for class 2 interactions (distance units)
<I>lj/class2/coul/cut</I> args = cutoff (cutoff2)
cutoff = global cutoff for class 2 (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
<I>lj/class2/coul/long</I> args = cutoff (cutoff2)
cutoff = global cutoff for class 2 (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/class2 10.0
pair_coeff * * 100.0 2.5
pair_coeff 1 2* 100.0 2.5 9.0
</PRE>
<PRE>pair_style lj/class2/coul/cut 10.0
pair_style lj/class2/coul/cut 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
pair_coeff 1 1 100.0 3.5 9.0 9.0
</PRE>
<PRE>pair_style lj/class2/coul/long 10.0
pair_style lj/class2/coul/long 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/class2</I> styles compute a 6/9 Lennard-Jones potential given by
</P>
<CENTER><IMG SRC = "Eqs/pair_class2.jpg">
</CENTER>
<P>Rc is the cutoff.
</P>
<P>The <I>lj/class2/coul/cut</I> and <I>lj/class2/coul/long</I> styles add a
Coulombic term as described for the <A HREF = "pair_lj.html">lj/cut</A> pair
styles.
</P>
<P>See <A HREF = "#Sun">(Sun)</A> for a description of the COMPASS class2 force field.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff1 (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>The latter 2 coefficients are optional. If not specified, the global
class 2 and Coulombic cutoffs are used. If only one cutoff is
specified, it is used as the cutoff for both class 2 and Coulombic
interactions for this type pair. If both coefficients are specified,
they are used as the class 2 and Coulombic cutoffs for this type pair.
You cannot specify 2 cutoffs for style <I>lj/class2</I>, since it has no
Coulombic terms.
</P>
<P>For <I>lj/class2/coul/long</I> only the class 2 cutoff can be specified
since a Coulombic cutoff cannot be specified for an individual I,J
type pair. All type pairs use the same global Coulombic cutoff
specified in the pair_style command.
</P>
<HR>
<P>If the pair_coeff command is not used to define coefficients for a
particular I != J type pair, the mixing rule for epsilon and sigma for
all class2 potentials is to use the <I>sixthpower</I> formulas documented
by the <A HREF = "pair_modify.html">pair_modify</A> command. The <A HREF = "pair_modify.html">pair_modify
mix</A> setting is thus ignored for class2 potentials
for epsilon and sigma. However it is still followed for mixing the
cutoff distance.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/class2 pair styles can be mixed.
Epsilon and sigma are always mixed with the value <I>sixthpower</I>. The
cutoff distance is mixed by whatever option is set by the pair_modify
command (default = geometric). See the "pair_modify" command for
details.
</P>
<P>All of the lj/class2 pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> shift option for the energy of the
Lennard-Jones portion of the pair interaction.
</P>
<P>The <I>lj/class2/coul/long</I> pair style does not support the
<A HREF = "pair_modify.html">pair_modify</A> table option since a tabulation
capability has not yet been added to this potential.
</P>
<P>All of the lj/class2 pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> tail option for adding a long-range
tail correction to the energy and pressure of the Lennard-Jones
portion of the pair interaction.
</P>
<P>All of the lj/class2 pair styles write their information to <A HREF = "restart.html">binary
restart files</A>, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
</P>
<P>All of the lj/class2 pair styles can only be used via the <I>pair</I>
keyword of the <A HREF = "run_style.html">run_style respa</A> command. They do not
support the <I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P><B>Restrictions:</B>
</P>
<P>These styles are part of the CLASS2 package. They are only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Sun"></A>
<P><B>(Sun)</B> Sun, J Phys Chem B 102, 7338-7364 (1998).
</P>
</HTML>
diff --git a/doc/pair_class2.txt b/doc/pair_class2.txt
index 301372749..d7b376a60 100644
--- a/doc/pair_class2.txt
+++ b/doc/pair_class2.txt
@@ -1,170 +1,170 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/class2 command :h3
pair_style lj/class2/cuda command :h3
pair_style lj/class2/gpu command :h3
pair_style lj/class2/omp command :h3
pair_style lj/class2/coul/cut command :h3
pair_style lj/class2/coul/cut/cuda command :h3
pair_style lj/class2/coul/cut/omp command :h3
pair_style lj/class2/coul/long command :h3
pair_style lj/class2/coul/long/cuda command :h3
pair_style lj/class2/coul/long/gpu command :h3
pair_style lj/class2/coul/long/omp command :h3
[Syntax:]
pair_style style args :pre
style = {lj/class2} or {lj/class2/coul/cut} or {lj/class2/coul/long}
args = list of arguments for a particular style :ul
{lj/class2} args = cutoff
cutoff = global cutoff for class 2 interactions (distance units)
{lj/class2/coul/cut} args = cutoff (cutoff2)
cutoff = global cutoff for class 2 (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
{lj/class2/coul/long} args = cutoff (cutoff2)
cutoff = global cutoff for class 2 (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
[Examples:]
pair_style lj/class2 10.0
pair_coeff * * 100.0 2.5
pair_coeff 1 2* 100.0 2.5 9.0 :pre
pair_style lj/class2/coul/cut 10.0
pair_style lj/class2/coul/cut 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
pair_coeff 1 1 100.0 3.5 9.0 9.0 :pre
pair_style lj/class2/coul/long 10.0
pair_style lj/class2/coul/long 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0 :pre
[Description:]
The {lj/class2} styles compute a 6/9 Lennard-Jones potential given by
:c,image(Eqs/pair_class2.jpg)
Rc is the cutoff.
The {lj/class2/coul/cut} and {lj/class2/coul/long} styles add a
Coulombic term as described for the "lj/cut"_pair_lj.html pair
styles.
See "(Sun)"_#Sun for a description of the COMPASS class2 force field.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff1 (distance units)
cutoff2 (distance units) :ul
The latter 2 coefficients are optional. If not specified, the global
class 2 and Coulombic cutoffs are used. If only one cutoff is
specified, it is used as the cutoff for both class 2 and Coulombic
interactions for this type pair. If both coefficients are specified,
they are used as the class 2 and Coulombic cutoffs for this type pair.
You cannot specify 2 cutoffs for style {lj/class2}, since it has no
Coulombic terms.
For {lj/class2/coul/long} only the class 2 cutoff can be specified
since a Coulombic cutoff cannot be specified for an individual I,J
type pair. All type pairs use the same global Coulombic cutoff
specified in the pair_style command.
:line
If the pair_coeff command is not used to define coefficients for a
particular I != J type pair, the mixing rule for epsilon and sigma for
all class2 potentials is to use the {sixthpower} formulas documented
by the "pair_modify"_pair_modify.html command. The "pair_modify
mix"_pair_modify.html setting is thus ignored for class2 potentials
for epsilon and sigma. However it is still followed for mixing the
cutoff distance.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/class2 pair styles can be mixed.
Epsilon and sigma are always mixed with the value {sixthpower}. The
cutoff distance is mixed by whatever option is set by the pair_modify
command (default = geometric). See the "pair_modify" command for
details.
All of the lj/class2 pair styles support the
"pair_modify"_pair_modify.html shift option for the energy of the
Lennard-Jones portion of the pair interaction.
The {lj/class2/coul/long} pair style does not support the
"pair_modify"_pair_modify.html table option since a tabulation
capability has not yet been added to this potential.
All of the lj/class2 pair styles support the
"pair_modify"_pair_modify.html tail option for adding a long-range
tail correction to the energy and pressure of the Lennard-Jones
portion of the pair interaction.
All of the lj/class2 pair styles write their information to "binary
restart files"_restart.html, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
All of the lj/class2 pair styles can only be used via the {pair}
keyword of the "run_style respa"_run_style.html command. They do not
support the {inner}, {middle}, {outer} keywords.
[Restrictions:]
These styles are part of the CLASS2 package. They are only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Sun)
[(Sun)] Sun, J Phys Chem B 102, 7338-7364 (1998).
diff --git a/doc/pair_cmm.html b/doc/pair_cmm.html
deleted file mode 100644
index 766904a07..000000000
--- a/doc/pair_cmm.html
+++ /dev/null
@@ -1,203 +0,0 @@
-<HTML>
-<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
-</CENTER>
-
-
-
-
-
-
-<HR>
-
-<H3>pair_style cg/cmm command
-</H3>
-<H3>pair_style cg/cmm/cuda command
-</H3>
-<H3>pair_style cg/cmm/gpu command
-</H3>
-<H3>pair_style cg/cmm/coul/cut command
-</H3>
-<H3>pair_style cg/cmm/coul/cut/cuda command
-</H3>
-<H3>pair_style cg/cmm/coul/debye/cuda command
-</H3>
-<H3>pair_style cg/cmm/coul/long command
-</H3>
-<H3>pair_style cg/cmm/coul/long/gpu command
-</H3>
-<H3>pair_style cg/cmm/coul/long/cuda command
-</H3>
-<P><B>Syntax:</B>
-</P>
-<PRE>pair_style style args
-</PRE>
-<UL><LI>style = <I>cg/cmm</I> or <I>cg/cmm/coul/cut</I> or <I>cg/cmm/coul/long</I>
-<LI>args = list of arguments for a particular style
-</UL>
-<PRE> <I>cg/cmm</I> args = cutoff
- cutoff = global cutoff for Lennard Jones interactions (distance units)
- <I>cg/cmm/coul/cut</I> args = cutoff (cutoff2) (kappa)
- cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
- cutoff2 = global cutoff for Coulombic (optional) (distance units)
- kappa = Debye length (optional, defaults to 0.0 = disabled) (inverse distance units)
- <I>cg/cmm/coul/long</I> args = cutoff (cutoff2)
- cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
- cutoff2 = global cutoff for Coulombic (optional) (distance units)
-</PRE>
-<P><B>Examples:</B>
-</P>
-<PRE>pair_style cg/cmm 2.5
-pair_coeff 1 1 lj12_6 1 1.1 2.8
-</PRE>
-<PRE>pair_style cg/cmm/coul/cut 10.0 12.0
-pair_coeff 1 1 lj9_6 100.0 3.5 9.0
-pair_coeff 1 1 lj12_4 100.0 3.5 9.0 9.0
-</PRE>
-<PRE>pair_style cg/cmm/coul/long 10.0
-pair_style cg/cmm/coul/long 10.0 8.0
-pair_coeff 1 1 lj9_6 100.0 3.5 9.0
-</PRE>
-<P><B>Description:</B>
-</P>
-<P>The <I>cg/cmm</I> styles compute a 9/6, 12/4, or 12/6 Lennard-Jones potential,
-given by
-</P>
-<CENTER><IMG SRC = "Eqs/pair_cmm.jpg">
-</CENTER>
-<P>as required for the CMM Coarse-grained MD parametrization discussed in
-<A HREF = "#Shinoda">(Shinoda)</A> and <A HREF = "#DeVane">(DeVane)</A>. Rc is the cutoff.
-</P>
-<P>Style <I>cg/cmm/coul/cut</I> adds a Coulombic pairwise interaction given by
-</P>
-<CENTER><IMG SRC = "Eqs/pair_coulomb.jpg">
-</CENTER>
-<P>where C is an energy-conversion constant, Qi and Qj are the charges on
-the 2 atoms, and epsilon is the dielectric constant which can be set
-by the <A HREF = "dielectric.html">dielectric</A> command. If one cutoff is
-specified in the pair_style command, it is used for both the LJ and
-Coulombic terms. If two cutoffs are specified, they are used as
-cutoffs for the LJ and Coulombic terms respectively.
-</P>
-<P>This style also contains an additional exp() damping factor
-to the Coulombic term, given by
-</P>
-<CENTER><IMG SRC = "Eqs/pair_debye.jpg">
-</CENTER>
-<P>where kappa is the Debye length (kappa=0.0 is the unscreened coulomb).
-This potential is another way to mimic the screening effect of a polar
-solvent.
-</P>
-<P>Style <I>cg/cmm/coul/long</I> computes the same Coulombic interactions as
-style <I>cg/cmm/coul/cut</I> except that an additional damping factor is
-applied to the Coulombic term so it can be used in conjunction with
-the <A HREF = "kspace_style.html">kspace_style</A> command and its <I>ewald</I> or <I>pppm</I>
-option. The Coulombic cutoff specified for this style means that
-pairwise interactions within this distance are computed directly;
-interactions outside that distance are computed in reciprocal space.
-</P>
-<P>The following coefficients must be defined for each pair of atoms
-types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
-above, or in the data file or restart files read by the
-<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
-commands, or by mixing as described below:
-</P>
-<UL><LI>cg_type (lj9_6, lj12_4, or lj12_6)
-<LI>epsilon (energy units)
-<LI>sigma (distance units)
-<LI>cutoff1 (distance units)
-<LI>cutoff2 (distance units)
-</UL>
-<P>Note that sigma is defined in the LJ formula as the zero-crossing
-distance for the potential, not as the energy minimum. The prefactors
-are chosen so that the potential minimum is at -epsilon.
-</P>
-<P>The latter 2 coefficients are optional. If not specified, the global
-LJ and Coulombic cutoffs specified in the pair_style command are used.
-If only one cutoff is specified, it is used as the cutoff for both LJ
-and Coulombic interactions for this type pair. If both coefficients
-are specified, they are used as the LJ and Coulombic cutoffs for this
-type pair.
-</P>
-<P>For <I>cg/cmm/coul/long</I> only the LJ cutoff can be specified since a
-Coulombic cutoff cannot be specified for an individual I,J type pair.
-All type pairs use the same global Coulombic cutoff specified in the
-pair_style command.
-</P>
-<HR>
-
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, or <I>opt</I> suffix are functionally the same
-as the corresponding style without the suffix. They have been
-optimized to run faster, depending on your available hardware, as
-discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
-</P>
-<P>These accelerated styles are part of the USER-CUDA, GPU, and OPT
-packages respectively. They are only enabled if LAMMPS was built with
-those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
-section for more info.
-</P>
-<P>You can specify the accelerated styles explicitly in your input script
-by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
-switch</A> when you invoke LAMMPS, or you can
-use the <A HREF = "suffix.html">suffix</A> command in your input script.
-</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
-</P>
-<HR>
-
-<P><B>Mixing, shift, table, tail correction, restart, and rRESPA info</B>:
-</P>
-<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of the cg/cmm pair styles <I>cannot</I> be mixed,
-since different pairs may have different exponents. So all parameters
-for all pairs have to be specified explicitly through the "pair_coeff"
-command. Defining then in a data file is also not supported, due to
-limitations of that file format.
-</P>
-<P>All of the cg/cmm pair styles support the
-<A HREF = "pair_modify.html">pair_modify</A> shift option for the energy of the
-Lennard-Jones portion of the pair interaction.
-</P>
-<P>The <I>cg/cmm/coul/long</I> pair styles support the
-<A HREF = "pair_modify.html">pair_modify</A> table option since they can tabulate
-the short-range portion of the long-range Coulombic interaction.
-</P>
-<P>All of the cg/cmm pair styles write their information to <A HREF = "restart.html">binary
-restart files</A>, so pair_style and pair_coeff commands do
-not need to be specified in an input script that reads a restart file.
-</P>
-<P>The cg/cmm, cg/cmm/coul/cut and lj/cut/coul/long pair styles support
-the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I> keywords of the <A HREF = "run_style.html">run_style
-respa</A> command, meaning the pairwise forces can be
-partitioned by distance at different levels of the rRESPA hierarchy.
-See the <A HREF = "run_style.html">run_style</A> command for details.
-</P>
-<HR>
-
-<P><B>Restrictions:</B>
-</P>
-<P>All of the cg/cmm pair styles are part of the USER-CG-CMM package.
-The <I>cg/cmm/coul/long</I> style also requires the KSPACE package to be
-built (which is enabled by default). They are only enabled if LAMMPS
-was built with that package. See the <A HREF = "Section_start.html#start_3">Making
-LAMMPS</A> section for more info.
-</P>
-<P><B>Related commands:</B>
-</P>
-<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "angle_cmm.html">angle_style cg/cmm</A>
-</P>
-<P><B>Default:</B> none
-</P>
-<HR>
-
-<A NAME = "Shinoda"></A>
-
-<P><B>(Shinoda)</B> Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007).
-</P>
-<A NAME = "DeVane"></A>
-
-<P><B>(DeVane)</B> Shinoda, DeVane, Klein, Soft Matter, 4, 2453-2462 (2008).
-</P>
-</HTML>
diff --git a/doc/pair_cmm.txt b/doc/pair_cmm.txt
deleted file mode 100644
index b330de491..000000000
--- a/doc/pair_cmm.txt
+++ /dev/null
@@ -1,188 +0,0 @@
-"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
-
-:link(lws,http://lammps.sandia.gov)
-:link(ld,Manual.html)
-:link(lc,Section_commands.html#comm)
-
-:line
-
-pair_style cg/cmm command :h3
-pair_style cg/cmm/cuda command :h3
-pair_style cg/cmm/gpu command :h3
-pair_style cg/cmm/coul/cut command :h3
-pair_style cg/cmm/coul/cut/cuda command :h3
-pair_style cg/cmm/coul/debye/cuda command :h3
-pair_style cg/cmm/coul/long command :h3
-pair_style cg/cmm/coul/long/gpu command :h3
-pair_style cg/cmm/coul/long/cuda command :h3
-
-[Syntax:]
-
-pair_style style args :pre
-
-style = {cg/cmm} or {cg/cmm/coul/cut} or {cg/cmm/coul/long}
-args = list of arguments for a particular style :ul
- {cg/cmm} args = cutoff
- cutoff = global cutoff for Lennard Jones interactions (distance units)
- {cg/cmm/coul/cut} args = cutoff (cutoff2) (kappa)
- cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
- cutoff2 = global cutoff for Coulombic (optional) (distance units)
- kappa = Debye length (optional, defaults to 0.0 = disabled) (inverse distance units)
- {cg/cmm/coul/long} args = cutoff (cutoff2)
- cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
- cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
-
-[Examples:]
-
-pair_style cg/cmm 2.5
-pair_coeff 1 1 lj12_6 1 1.1 2.8 :pre
-
-pair_style cg/cmm/coul/cut 10.0 12.0
-pair_coeff 1 1 lj9_6 100.0 3.5 9.0
-pair_coeff 1 1 lj12_4 100.0 3.5 9.0 9.0 :pre
-
-pair_style cg/cmm/coul/long 10.0
-pair_style cg/cmm/coul/long 10.0 8.0
-pair_coeff 1 1 lj9_6 100.0 3.5 9.0 :pre
-
-[Description:]
-
-The {cg/cmm} styles compute a 9/6, 12/4, or 12/6 Lennard-Jones potential,
-given by
-
-:c,image(Eqs/pair_cmm.jpg)
-
-as required for the CMM Coarse-grained MD parametrization discussed in
-"(Shinoda)"_#Shinoda and "(DeVane)"_#DeVane. Rc is the cutoff.
-
-Style {cg/cmm/coul/cut} adds a Coulombic pairwise interaction given by
-
-:c,image(Eqs/pair_coulomb.jpg)
-
-where C is an energy-conversion constant, Qi and Qj are the charges on
-the 2 atoms, and epsilon is the dielectric constant which can be set
-by the "dielectric"_dielectric.html command. If one cutoff is
-specified in the pair_style command, it is used for both the LJ and
-Coulombic terms. If two cutoffs are specified, they are used as
-cutoffs for the LJ and Coulombic terms respectively.
-
-This style also contains an additional exp() damping factor
-to the Coulombic term, given by
-
-:c,image(Eqs/pair_debye.jpg)
-
-where kappa is the Debye length (kappa=0.0 is the unscreened coulomb).
-This potential is another way to mimic the screening effect of a polar
-solvent.
-
-Style {cg/cmm/coul/long} computes the same Coulombic interactions as
-style {cg/cmm/coul/cut} except that an additional damping factor is
-applied to the Coulombic term so it can be used in conjunction with
-the "kspace_style"_kspace_style.html command and its {ewald} or {pppm}
-option. The Coulombic cutoff specified for this style means that
-pairwise interactions within this distance are computed directly;
-interactions outside that distance are computed in reciprocal space.
-
-The following coefficients must be defined for each pair of atoms
-types via the "pair_coeff"_pair_coeff.html command as in the examples
-above, or in the data file or restart files read by the
-"read_data"_read_data.html or "read_restart"_read_restart.html
-commands, or by mixing as described below:
-
-cg_type (lj9_6, lj12_4, or lj12_6)
-epsilon (energy units)
-sigma (distance units)
-cutoff1 (distance units)
-cutoff2 (distance units) :ul
-
-Note that sigma is defined in the LJ formula as the zero-crossing
-distance for the potential, not as the energy minimum. The prefactors
-are chosen so that the potential minimum is at -epsilon.
-
-The latter 2 coefficients are optional. If not specified, the global
-LJ and Coulombic cutoffs specified in the pair_style command are used.
-If only one cutoff is specified, it is used as the cutoff for both LJ
-and Coulombic interactions for this type pair. If both coefficients
-are specified, they are used as the LJ and Coulombic cutoffs for this
-type pair.
-
-For {cg/cmm/coul/long} only the LJ cutoff can be specified since a
-Coulombic cutoff cannot be specified for an individual I,J type pair.
-All type pairs use the same global Coulombic cutoff specified in the
-pair_style command.
-
-:line
-
-Styles with a {cuda}, {gpu}, or {opt} suffix are functionally the same
-as the corresponding style without the suffix. They have been
-optimized to run faster, depending on your available hardware, as
-discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
-
-These accelerated styles are part of the USER-CUDA, GPU, and OPT
-packages respectively. They are only enabled if LAMMPS was built with
-those packages. See the "Making LAMMPS"_Section_start.html#start_3
-section for more info.
-
-You can specify the accelerated styles explicitly in your input script
-by including their suffix, or you can use the "-suffix command-line
-switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
-use the "suffix"_suffix.html command in your input script.
-
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
-
-:line
-
-[Mixing, shift, table, tail correction, restart, and rRESPA info]:
-
-For atom type pairs I,J and I != J, the epsilon and sigma coefficients
-and cutoff distance for all of the cg/cmm pair styles {cannot} be mixed,
-since different pairs may have different exponents. So all parameters
-for all pairs have to be specified explicitly through the "pair_coeff"
-command. Defining then in a data file is also not supported, due to
-limitations of that file format.
-
-All of the cg/cmm pair styles support the
-"pair_modify"_pair_modify.html shift option for the energy of the
-Lennard-Jones portion of the pair interaction.
-
-The {cg/cmm/coul/long} pair styles support the
-"pair_modify"_pair_modify.html table option since they can tabulate
-the short-range portion of the long-range Coulombic interaction.
-
-All of the cg/cmm pair styles write their information to "binary
-restart files"_restart.html, so pair_style and pair_coeff commands do
-not need to be specified in an input script that reads a restart file.
-
-The cg/cmm, cg/cmm/coul/cut and lj/cut/coul/long pair styles support
-the use of the {inner}, {middle}, and {outer} keywords of the "run_style
-respa"_run_style.html command, meaning the pairwise forces can be
-partitioned by distance at different levels of the rRESPA hierarchy.
-See the "run_style"_run_style.html command for details.
-
-:line
-
-[Restrictions:]
-
-All of the cg/cmm pair styles are part of the USER-CG-CMM package.
-The {cg/cmm/coul/long} style also requires the KSPACE package to be
-built (which is enabled by default). They are only enabled if LAMMPS
-was built with that package. See the "Making
-LAMMPS"_Section_start.html#start_3 section for more info.
-
-[Related commands:]
-
-"pair_coeff"_pair_coeff.html, "angle_style cg/cmm"_angle_cmm.html
-
-[Default:] none
-
-:line
-
-:link(Shinoda)
-[(Shinoda)] Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007).
-
-:link(DeVane)
-[(DeVane)] Shinoda, DeVane, Klein, Soft Matter, 4, 2453-2462 (2008).
-
diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html
index 1c9c6777e..0ac1a684b 100644
--- a/doc/pair_coeff.html
+++ b/doc/pair_coeff.html
@@ -1,182 +1,184 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_coeff command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_coeff I J args
</PRE>
<UL><LI>I,J = atom types (see asterisk form below)
<LI>args = coefficients for one or more pairs of atom types
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_coeff 1 2 1.0 1.0 2.5
pair_coeff 2 * 1.0 1.0
pair_coeff 3* 1*2 1.0 1.0 2.5
pair_coeff * * 1.0 1.0
pair_coeff * * nialhjea 1 1 2
pair_coeff * 3 morse.table ENTRY1
pair_coeff 1 2 lj/cut 1.0 1.0 2.5 (for pair_style hybrid)
</PRE>
<P><B>Description:</B>
</P>
<P>Specify the pairwise force field coefficients for one or more pairs of
atom types. The number and meaning of the coefficients depends on the
pair style. Pair coefficients can also be set in the data file read
by the <A HREF = "read_data.html">read_data</A> command or in a restart file.
</P>
<P>I and J can be specified in one of two ways. Explicit numeric values
can be used for each, as in the 1st example above. I <= J is
required. LAMMPS sets the coefficients for the symmetric J,I
interaction to the same values.
</P>
<P>A wildcard asterisk can be used in place of or in conjunction with the
I,J arguments to set the coefficients for multiple pairs 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). Note that only type pairs with I <= J are considered; if
asterisks imply type pairs where J < I, they are ignored.
</P>
<P>Note that a pair_coeff command can override a previous setting for the
same I,J pair. For example, these commands set the coeffs for all I,J
pairs, then overwrite the coeffs for just the I,J = 2,3 pair:
</P>
<PRE>pair_coeff * * 1.0 1.0 2.5
pair_coeff 2 3 2.0 1.0 1.12
</PRE>
<P>A line in a data file that specifies pair coefficients uses the exact
same format as the arguments of the pair_coeff command in an input
script, with the exception of the I,J type arguments. In each line of
the "Pair Coeffs" section of a data file, only a single type I is
specified, which sets the coefficients for type I interacting with
type I. This is because the section has exactly N lines, where N =
the number of atom types. For this reason, the wild-card asterisk
should also not be used as part of the I argument. Thus in a data
file, the line corresponding to the 1st example above would be listed
as
</P>
<PRE>2 1.0 1.0 2.5
</PRE>
<P>For many potentials, if coefficients for type pairs with I != J are
not set explicitly by a pair_coeff command, the values are inferred
from the I,I and J,J settings by mixing rules; see the
<A HREF = "pair_modify.html">pair_modify</A> command for a discussion. Details on
this option as it pertains to individual potentials are described on
the doc page for the potential.
</P>
<HR>
<P>Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
<A HREF = "pair_coeff.html">pair_coeff</A> command:
</P>
<UL><LI><A HREF = "pair_hybrid.html">pair_style hybrid</A> - multiple styles of pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid/overlay</A> - multiple styles of superposed pairwise interactions
</UL>
<UL><LI><A HREF = "pair_adp.html">pair_style adp</A> - angular dependent potential (ADP) of Mishin
<LI><A HREF = "pair_airebo.html">pair_style airebo</A> - AIREBO potential of Stuart
<LI><A HREF = "pair_born.html">pair_style born</A> - Born-Mayer-Huggins potential
-<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulomb
+<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulombics
+<LI><A HREF = "pair_born.html">pair_style born/coul/wolf</A> - Born-Mayer-Huggins with Coulombics via Wolf potential
<LI><A HREF = "pair_brownian.html">pair_style brownian</A> - Brownian potential for Fast Lubrication Dynamics
<LI><A HREF = "pair_brownian.html">pair_style brownian/poly</A> - Brownian potential for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_buck.html">pair_style buck</A> - Buckingham potential
<LI><A HREF = "pair_buck.html">pair_style buck/coul/cut</A> - Buckingham with cutoff Coulomb
<LI><A HREF = "pair_buck.html">pair_style buck/coul/long</A> - Buckingham with long-range Coulomb
<LI><A HREF = "pair_colloid.html">pair_style colloid</A> - integrated colloidal potential
<LI><A HREF = "pair_comb.html">pair_style comb</A> - charge-optimized many-body (COMB) potential
<LI><A HREF = "pair_coul.html">pair_style coul/cut</A> - cutoff Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/debye</A> - cutoff Coulombic potential with Debye screening
<LI><A HREF = "pair_coul.html">pair_style coul/long</A> - long-range Coulombic potential
+<LI><A HREF = "pair_coul.html">pair_style coul/wolf</A> - Coulombics via Wolf potential
<LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A> - point dipoles with cutoff
<LI><A HREF = "pair_dpd.html">pair_style dpd</A> - dissipative particle dynamics (DPD)
<LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A> - DPD thermostatting
<LI><A HREF = "pair_dsmc.html">pair_style dsmc</A> - Direct Simulation Monte Carlo (DSMC)
<LI><A HREF = "pair_eam.html">pair_style eam</A> - embedded atom method (EAM)
<LI><A HREF = "pair_eam.html">pair_style eam/alloy</A> - alloy EAM
<LI><A HREF = "pair_eam.html">pair_style eam/fs</A> - Finnis-Sinclair EAM
<LI><A HREF = "pair_eim.html">pair_style eim</A> - embedded ion method (EIM)
<LI><A HREF = "pair_gauss.html">pair_style gauss</A> - Gaussian potential
<LI><A HREF = "pair_gayberne.html">pair_style gayberne</A> - Gay-Berne ellipsoidal potential
<LI><A HREF = "pair_gran.html">pair_style gran/hertz/history</A> - granular potential with Hertzian interactions
<LI><A HREF = "pair_gran.html">pair_style gran/hooke</A> - granular potential with history effects
<LI><A HREF = "pair_gran.html">pair_style gran/hooke/history</A> - granular potential without history effects
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/lj</A> - DREIDING hydrogen bonding LJ potential
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/morse</A> - DREIDING hydrogen bonding Morse potential
<LI><A HREF = "pair_line_lj.html">pair_style line/lj</A> - LJ potential between line segments
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm</A> - CHARMM potential with cutoff Coulomb
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm/implicit</A> - CHARMM for implicit solvent
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/long</A> - CHARMM with long-range Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2</A> - COMPASS (class 2) force field with no Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/cut</A> - COMPASS with cutoff Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/long</A> - COMPASS with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut</A> - cutoff Lennard-Jones potential with no Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/cut</A> - LJ with cutoff Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/debye</A> - LJ with Debye screening added to Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long</A> - LJ with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long/tip4p</A> - LJ with long-range Coulomb for TIP4P water
<LI><A HREF = "pair_lj_expand.html">pair_style lj/expand</A> - Lennard-Jones for variable size particles
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs</A> - GROMACS-style Lennard-Jones potential
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs/coul/gromacs</A> - GROMACS-style LJ and Coulombic potential
<LI><A HREF = "pair_lj_smooth.html">pair_style lj/smooth</A> - smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj96.html">pair_style lj96/cut</A> - Lennard-Jones 9/6 potential
<LI><A HREF = "pair_lubricate.html">pair_style lubricate</A> - hydrodynamic lubrication forces
<LI><A HREF = "pair_lubricate.html">pair_style lubricate/poly</A> - hydrodynamic lubrication forces with polydispersity
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU/poly</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_meam.html">pair_style meam</A> - modified embedded atom method (MEAM)
<LI><A HREF = "pair_morse.html">pair_style morse</A> - Morse potential
<LI><A HREF = "pair_peri.html">pair_style peri/lps</A> - peridynamic LPS potential
<LI><A HREF = "pair_peri.html">pair_style peri/pmb</A> - peridynamic PMB potential
<LI><A HREF = "pair_reax.html">pair_style reax</A> - ReaxFF potential
<LI><A HREF = "pair_airebo.html">pair_style rebo</A> - 2nd-generation REBO potential of Brenner
<LI><A HREF = "pair_resquared.html">pair_style resquared</A> - Everaers RE-Squared ellipsoidal potential
<LI><A HREF = "pair_soft.html">pair_style soft</A> - Soft (cosine) potential
<LI><A HREF = "pair_sw.html">pair_style sw</A> - Stillinger-Weber 3-body potential
<LI><A HREF = "pair_table.html">pair_style table</A> - tabulated pair potential
<LI><A HREF = "pair_tersoff.html">pair_style tersoff</A> - Tersoff 3-body potential
<LI><A HREF = "pair_tersoff_zbl.html">pair_style tersoff/zbl</A> - Tersoff/ZBL 3-body potential
<LI><A HREF = "pair_tri_lj.html">pair_style tri/lj</A> - LJ potential between triangles
<LI><A HREF = "pair_yukawa.html">pair_style yukawa</A> - Yukawa potential
<LI><A HREF = "pair_yukawa_colloid.html">pair_style yukawa/colloid</A> - screened Yukawa potential for finite-size particles
</UL>
<P>There are also additional pair styles submitted by users which are
included in the LAMMPS distribution. The list of these with links to
the individual styles are given in the pair section of <A HREF = "Section_commands.html#cmd_5">this
page</A>.
</P>
<P>There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command must come after the simulation box is defined by a
<A HREF = "read_data.html">read_data</A>, <A HREF = "read_restart.html">read_restart</A>, or
<A HREF = "create_box.html">create_box</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_style.html">pair_style</A>, <A HREF = "pair_modify.html">pair_modify</A>,
<A HREF = "read_data.html">read_data</A>, <A HREF = "read_restart.html">read_restart</A>,
<A HREF = "pair_write.html">pair_write</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt
index 4c8ca53f5..1b66fe2a3 100644
--- a/doc/pair_coeff.txt
+++ b/doc/pair_coeff.txt
@@ -1,177 +1,179 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_coeff command :h3
[Syntax:]
pair_coeff I J args :pre
I,J = atom types (see asterisk form below)
args = coefficients for one or more pairs of atom types :ul
[Examples:]
pair_coeff 1 2 1.0 1.0 2.5
pair_coeff 2 * 1.0 1.0
pair_coeff 3* 1*2 1.0 1.0 2.5
pair_coeff * * 1.0 1.0
pair_coeff * * nialhjea 1 1 2
pair_coeff * 3 morse.table ENTRY1
pair_coeff 1 2 lj/cut 1.0 1.0 2.5 (for pair_style hybrid) :pre
[Description:]
Specify the pairwise force field coefficients for one or more pairs of
atom types. The number and meaning of the coefficients depends on the
pair style. Pair coefficients can also be set in the data file read
by the "read_data"_read_data.html command or in a restart file.
I and J can be specified in one of two ways. Explicit numeric values
can be used for each, as in the 1st example above. I <= J is
required. LAMMPS sets the coefficients for the symmetric J,I
interaction to the same values.
A wildcard asterisk can be used in place of or in conjunction with the
I,J arguments to set the coefficients for multiple pairs 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). Note that only type pairs with I <= J are considered; if
asterisks imply type pairs where J < I, they are ignored.
Note that a pair_coeff command can override a previous setting for the
same I,J pair. For example, these commands set the coeffs for all I,J
pairs, then overwrite the coeffs for just the I,J = 2,3 pair:
pair_coeff * * 1.0 1.0 2.5
pair_coeff 2 3 2.0 1.0 1.12 :pre
A line in a data file that specifies pair coefficients uses the exact
same format as the arguments of the pair_coeff command in an input
script, with the exception of the I,J type arguments. In each line of
the "Pair Coeffs" section of a data file, only a single type I is
specified, which sets the coefficients for type I interacting with
type I. This is because the section has exactly N lines, where N =
the number of atom types. For this reason, the wild-card asterisk
should also not be used as part of the I argument. Thus in a data
file, the line corresponding to the 1st example above would be listed
as
2 1.0 1.0 2.5 :pre
For many potentials, if coefficients for type pairs with I != J are
not set explicitly by a pair_coeff command, the values are inferred
from the I,I and J,J settings by mixing rules; see the
"pair_modify"_pair_modify.html command for a discussion. Details on
this option as it pertains to individual potentials are described on
the doc page for the potential.
:line
Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
"pair_coeff"_pair_coeff.html command:
"pair_style hybrid"_pair_hybrid.html - multiple styles of pairwise interactions
"pair_style hybrid/overlay"_pair_hybrid.html - multiple styles of superposed pairwise interactions :ul
"pair_style adp"_pair_adp.html - angular dependent potential (ADP) of Mishin
"pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart
"pair_style born"_pair_born.html - Born-Mayer-Huggins potential
-"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulomb
+"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulombics
+"pair_style born/coul/wolf"_pair_born.html - Born-Mayer-Huggins with Coulombics via Wolf potential
"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics
"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity
"pair_style buck"_pair_buck.html - Buckingham potential
"pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb
"pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb
"pair_style colloid"_pair_colloid.html - integrated colloidal potential
"pair_style comb"_pair_comb.html - charge-optimized many-body (COMB) potential
"pair_style coul/cut"_pair_coul.html - cutoff Coulombic potential
"pair_style coul/debye"_pair_coul.html - cutoff Coulombic potential with Debye screening
"pair_style coul/long"_pair_coul.html - long-range Coulombic potential
+"pair_style coul/wolf"_pair_coul.html - Coulombics via Wolf potential
"pair_style dipole/cut"_pair_dipole.html - point dipoles with cutoff
"pair_style dpd"_pair_dpd.html - dissipative particle dynamics (DPD)
"pair_style dpd/tstat"_pair_dpd.html - DPD thermostatting
"pair_style dsmc"_pair_dsmc.html - Direct Simulation Monte Carlo (DSMC)
"pair_style eam"_pair_eam.html - embedded atom method (EAM)
"pair_style eam/alloy"_pair_eam.html - alloy EAM
"pair_style eam/fs"_pair_eam.html - Finnis-Sinclair EAM
"pair_style eim"_pair_eim.html - embedded ion method (EIM)
"pair_style gauss"_pair_gauss.html - Gaussian potential
"pair_style gayberne"_pair_gayberne.html - Gay-Berne ellipsoidal potential
"pair_style gran/hertz/history"_pair_gran.html - granular potential with Hertzian interactions
"pair_style gran/hooke"_pair_gran.html - granular potential with history effects
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
"pair_style lj/class2"_pair_class2.html - COMPASS (class 2) force field with no Coulomb
"pair_style lj/class2/coul/cut"_pair_class2.html - COMPASS with cutoff Coulomb
"pair_style lj/class2/coul/long"_pair_class2.html - COMPASS with long-range Coulomb
"pair_style lj/cut"_pair_lj.html - cutoff Lennard-Jones potential with no Coulomb
"pair_style lj/cut/coul/cut"_pair_lj.html - LJ with cutoff Coulomb
"pair_style lj/cut/coul/debye"_pair_lj.html - LJ with Debye screening added to Coulomb
"pair_style lj/cut/coul/long"_pair_lj.html - LJ with long-range Coulomb
"pair_style lj/cut/coul/long/tip4p"_pair_lj.html - LJ with long-range Coulomb for TIP4P water
"pair_style lj/expand"_pair_lj_expand.html - Lennard-Jones for variable size particles
"pair_style lj/gromacs"_pair_gromacs.html - GROMACS-style Lennard-Jones potential
"pair_style lj/gromacs/coul/gromacs"_pair_gromacs.html - GROMACS-style LJ and Coulombic potential
"pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential
"pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential
"pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces
"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity
"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics
"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity
"pair_style meam"_pair_meam.html - modified embedded atom method (MEAM)
"pair_style morse"_pair_morse.html - Morse potential
"pair_style peri/lps"_pair_peri.html - peridynamic LPS potential
"pair_style peri/pmb"_pair_peri.html - peridynamic PMB potential
"pair_style reax"_pair_reax.html - ReaxFF potential
"pair_style rebo"_pair_airebo.html - 2nd-generation REBO potential of Brenner
"pair_style resquared"_pair_resquared.html - Everaers RE-Squared ellipsoidal potential
"pair_style soft"_pair_soft.html - Soft (cosine) potential
"pair_style sw"_pair_sw.html - Stillinger-Weber 3-body potential
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
There are also additional pair styles submitted by users which are
included in the LAMMPS distribution. The list of these with links to
the individual styles are given in the pair section of "this
page"_Section_commands.html#cmd_5.
There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of "this page"_Section_commands.html#cmd_5.
:line
[Restrictions:]
This command must come after the simulation box is defined by a
"read_data"_read_data.html, "read_restart"_read_restart.html, or
"create_box"_create_box.html command.
[Related commands:]
"pair_style"_pair_style.html, "pair_modify"_pair_modify.html,
"read_data"_read_data.html, "read_restart"_read_restart.html,
"pair_write"_pair_write.html
[Default:] none
diff --git a/doc/pair_colloid.html b/doc/pair_colloid.html
index a1754fd5d..b8ebae042 100644
--- a/doc/pair_colloid.html
+++ b/doc/pair_colloid.html
@@ -1,210 +1,210 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style colloid command
</H3>
<H3>pair_style colloid/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style colloid cutoff
</PRE>
<UL><LI>cutoff = global cutoff for colloidal interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style colloid 10.0
pair_coeff * * 25 1.0 10.0 10.0
pair_coeff 1 1 144 1.0 0.0 0.0 3.0
pair_coeff 1 2 75.398 1.0 0.0 10.0 9.0
pair_coeff 2 2 39.478 1.0 10.0 10.0 25.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>colloid</I> computes pairwise interactions between large colloidal
particles and small solvent particles using 3 formulas. A colloidal
particle has a size > sigma; a solvent particle is the usual
Lennard-Jones particle of size sigma.
</P>
<P>The colloid-colloid interaction energy is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_colloid_cc.jpg">
</CENTER>
<P>where A_cc is the Hamaker constant, a1 and a2 are the radii of the two
colloidal particles, and Rc is the cutoff. This equation results from
describing each colloidal particle as an integrated collection of
Lennard-Jones particles of size sigma and is derived in
<A HREF = "#Everaers">(Everaers)</A>.
</P>
<P>The colloid-solvent interaction energy is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_colloid_cs.jpg">
</CENTER>
<P>where A_cs is the Hamaker constant, a is the radius of the colloidal
particle, and Rc is the cutoff. This formula is derived from the
colloid-colloid interaction, letting one of the particle sizes go to
zero.
</P>
<P>The solvent-solvent interaction energy is given by the usual
Lennard-Jones formula
</P>
<CENTER><IMG SRC = "Eqs/pair_colloid_ss.jpg">
</CENTER>
<P>with A_ss set appropriately, which results from letting both particle
sizes go to zero.
</P>
<P>When used in combination with <A HREF = "pair_colloid.html">pair_style
yukawa/colloid</A>, the two terms become the so-called
DLVO potential, which combines electrostatic repulsion and van der
Waals attraction.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>A (energy units)
<LI>sigma (distance units)
<LI>d1 (distance units)
<LI>d2 (distance units)
<LI>cutoff (distance units)
</UL>
<P>A is the Hamaker energy prefactor and should typically be set as
follows:
</P>
<UL><LI>A_cc = colloid/colloid = 4 pi^2 = 39.5
<LI>A_cs = colloid/solvent = sqrt(A_cc*A_ss)
<LI>A_ss = solvent/solvent = 144 (assuming epsilon = 1, so that 144/36 = 4)
</UL>
<P>Sigma is the size of the solvent particle or the constituent particles
integrated over in the colloidal particle and should typically be set
as follows:
</P>
<UL><LI>Sigma_cc = colloid/colloid = 1.0
<LI>Sigma_cs = colloid/solvent = arithmetic mixing between colloid sigma and solvent sigma
<LI>Sigma_ss = solvent/solvent = 1.0 or whatever size the solvent particle is
</UL>
<P>Thus typically Sigma_cs = 1.0, unless the solvent particle's size !=
1.0.
</P>
<P>D1 and d2 are particle diameters, so that d1 = 2*a1 and d2 = 2*a2 in
the formulas above. Both d1 and d2 must be values >= 0. If d1 > 0
and d2 > 0, then the pair interacts via the colloid-colloid formula
above. If d1 = 0 and d2 = 0, then the pair interacts via the
solvent-solvent formula. I.e. a d value of 0 is a Lennard-Jones
particle of size sigma. If either d1 = 0 or d2 = 0 and the other is
larger, then the pair interacts via the colloid-solvent formula.
</P>
<P>Note that the diameter of a particular particle type may appear in
multiple pair_coeff commands, as it interacts with other particle
types. You should insure the particle diameter is specified
consistently each time it appears.
</P>
<P>The last coefficient is optional. If not specified, the global cutoff
specified in the pair_style command is used. However, you typically
want different cutoffs for interactions between different particle
sizes. E.g. if colloidal particles of diameter 10 are used with
solvent particles of diameter 1, then a solvent-solvent cutoff of 2.5
would correspond to a colloid-colloid cutoff of 25. A good
rule-of-thumb is to use a colloid-solvent cutoff that is half the big
diameter + 4 times the small diameter. I.e. 9 = 5 + 4 for the
colloid-solvent cutoff in this case.
</P>
<P>IMPORTANT NOTE: When using pair_style colloid for a mixture with 2 (or
more) widely different particles sizes (e.g. sigma=10 colloids in a
background sigam=1 LJ fluid), you will likely want to use these
commands for efficiency: <A HREF = "neighbor.html">neighbor multi</A> and
<A HREF = "communicate.html">communicate multi</A>.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the A, sigma, d1, and d2
coefficients and cutoff distance for this pair style can be mixed. A
is an energy value mixed like a LJ epsilon. D1 and d2 are distance
values and are mixed like sigma. The default mix value is
<I>geometric</I>. See the "pair_modify" command for details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the COLLOID package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>Normally, this pair style should be used with finite-size particles
which have a diameter, e.g. see the <A HREF = "atom_style.html">atom_style
sphere</A> command. However, this is not a requirement,
since the only definition of particle size is via the pair_coeff
parameters for each type. In other words, the physical radius of the
particle is ignored. Thus you should insure that the d1,d2 parameters
you specify are consistent with the physical size of the particles of
that type.
</P>
<P>Per-particle polydispersity is not yet supported by this pair style;
only per-type polydispersity is enabled via the pair_coeff parameters.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Everaers"></A>
<P><B>(Everaers)</B> Everaers, Ejtehadi, Phys Rev E, 67, 041710 (2003).
</P>
</HTML>
diff --git a/doc/pair_colloid.txt b/doc/pair_colloid.txt
index 8a442ea07..b68f8d9d6 100644
--- a/doc/pair_colloid.txt
+++ b/doc/pair_colloid.txt
@@ -1,203 +1,203 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style colloid command :h3
pair_style colloid/omp command :h3
[Syntax:]
pair_style colloid cutoff :pre
cutoff = global cutoff for colloidal interactions (distance units) :ul
[Examples:]
pair_style colloid 10.0
pair_coeff * * 25 1.0 10.0 10.0
pair_coeff 1 1 144 1.0 0.0 0.0 3.0
pair_coeff 1 2 75.398 1.0 0.0 10.0 9.0
pair_coeff 2 2 39.478 1.0 10.0 10.0 25.0 :pre
[Description:]
Style {colloid} computes pairwise interactions between large colloidal
particles and small solvent particles using 3 formulas. A colloidal
particle has a size > sigma; a solvent particle is the usual
Lennard-Jones particle of size sigma.
The colloid-colloid interaction energy is given by
:c,image(Eqs/pair_colloid_cc.jpg)
where A_cc is the Hamaker constant, a1 and a2 are the radii of the two
colloidal particles, and Rc is the cutoff. This equation results from
describing each colloidal particle as an integrated collection of
Lennard-Jones particles of size sigma and is derived in
"(Everaers)"_#Everaers.
The colloid-solvent interaction energy is given by
:c,image(Eqs/pair_colloid_cs.jpg)
where A_cs is the Hamaker constant, a is the radius of the colloidal
particle, and Rc is the cutoff. This formula is derived from the
colloid-colloid interaction, letting one of the particle sizes go to
zero.
The solvent-solvent interaction energy is given by the usual
Lennard-Jones formula
:c,image(Eqs/pair_colloid_ss.jpg)
with A_ss set appropriately, which results from letting both particle
sizes go to zero.
When used in combination with "pair_style
yukawa/colloid"_pair_colloid.html, the two terms become the so-called
DLVO potential, which combines electrostatic repulsion and van der
Waals attraction.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
A (energy units)
sigma (distance units)
d1 (distance units)
d2 (distance units)
cutoff (distance units) :ul
A is the Hamaker energy prefactor and should typically be set as
follows:
A_cc = colloid/colloid = 4 pi^2 = 39.5
A_cs = colloid/solvent = sqrt(A_cc*A_ss)
A_ss = solvent/solvent = 144 (assuming epsilon = 1, so that 144/36 = 4) :ul
Sigma is the size of the solvent particle or the constituent particles
integrated over in the colloidal particle and should typically be set
as follows:
Sigma_cc = colloid/colloid = 1.0
Sigma_cs = colloid/solvent = arithmetic mixing between colloid sigma and solvent sigma
Sigma_ss = solvent/solvent = 1.0 or whatever size the solvent particle is :ul
Thus typically Sigma_cs = 1.0, unless the solvent particle's size !=
1.0.
D1 and d2 are particle diameters, so that d1 = 2*a1 and d2 = 2*a2 in
the formulas above. Both d1 and d2 must be values >= 0. If d1 > 0
and d2 > 0, then the pair interacts via the colloid-colloid formula
above. If d1 = 0 and d2 = 0, then the pair interacts via the
solvent-solvent formula. I.e. a d value of 0 is a Lennard-Jones
particle of size sigma. If either d1 = 0 or d2 = 0 and the other is
larger, then the pair interacts via the colloid-solvent formula.
Note that the diameter of a particular particle type may appear in
multiple pair_coeff commands, as it interacts with other particle
types. You should insure the particle diameter is specified
consistently each time it appears.
The last coefficient is optional. If not specified, the global cutoff
specified in the pair_style command is used. However, you typically
want different cutoffs for interactions between different particle
sizes. E.g. if colloidal particles of diameter 10 are used with
solvent particles of diameter 1, then a solvent-solvent cutoff of 2.5
would correspond to a colloid-colloid cutoff of 25. A good
rule-of-thumb is to use a colloid-solvent cutoff that is half the big
diameter + 4 times the small diameter. I.e. 9 = 5 + 4 for the
colloid-solvent cutoff in this case.
IMPORTANT NOTE: When using pair_style colloid for a mixture with 2 (or
more) widely different particles sizes (e.g. sigma=10 colloids in a
background sigam=1 LJ fluid), you will likely want to use these
commands for efficiency: "neighbor multi"_neighbor.html and
"communicate multi"_communicate.html.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the A, sigma, d1, and d2
coefficients and cutoff distance for this pair style can be mixed. A
is an energy value mixed like a LJ epsilon. D1 and d2 are distance
values and are mixed like sigma. The default mix value is
{geometric}. See the "pair_modify" command for details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This style is part of the COLLOID package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
Normally, this pair style should be used with finite-size particles
which have a diameter, e.g. see the "atom_style
sphere"_atom_style.html command. However, this is not a requirement,
since the only definition of particle size is via the pair_coeff
parameters for each type. In other words, the physical radius of the
particle is ignored. Thus you should insure that the d1,d2 parameters
you specify are consistent with the physical size of the particles of
that type.
Per-particle polydispersity is not yet supported by this pair style;
only per-type polydispersity is enabled via the pair_coeff parameters.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Everaers)
[(Everaers)] Everaers, Ejtehadi, Phys Rev E, 67, 041710 (2003).
diff --git a/doc/pair_comb.html b/doc/pair_comb.html
index 71e245c9e..62c64c55e 100644
--- a/doc/pair_comb.html
+++ b/doc/pair_comb.html
@@ -1,263 +1,263 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style comb command
</H3>
<H3>pair_style comb/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style comb
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style comb
pair_coeff * * ../potentials/ffield.comb Si
pair_coeff * * ../potentials/ffield.comb Hf Si O
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>comb</I> computes a variable charge COMB (Charge-Optimized
Many-Body) potential as described in <A HREF = "#COMB_1">(COMB_1)</A> and
<A HREF = "#COMB_2">(COMB_2)</A>. The energy E of a system of atoms
is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_comb1.jpg">
</CENTER>
<P>where <I>E<sub>T</sub></I> is the total potential energy of the system,
<I>E<sup>S</sup><sub>i</sub></I> is the self-energy term of atom <I>i</I>,
<I>V<sub>ij</sub></I> is the interatomic potential between the <I>i</I>th and
<I>j</I>th atoms, <I>r<sub>ij</sub></I> is the distance of the atoms <I>i</I> and
<I>j</I>, and <I>q<sub>i</sub></I> and <I>q<sub>j</sub></I> are charges of the atoms,
and <I>E<sup>BB</sup><sub>i</sub></I> is the bond-bending term of atom <I>i</I>.
</P>
<P>The interatomic potential energy <I>V<sub>ij</sub></I> consists of four
components: two-body short-range repulsion,
<I>U<sup>R</sup><sub>ij</sub></I>, many-body short-range attraction,
<I>U<sup>A</sup><sub>ij</sub></I>, long-range Coulombic electrostatic
interaction, <I>U<sup>I</sup><sub>ij</sub></I>, and van der Waals energy,
<I>U<sup>V</sup><sub>ij</sub></I>, which are defined as:
</P>
<CENTER><IMG SRC = "Eqs/pair_comb2.jpg">
</CENTER>
<P>The short-range repulsion and attraction are based on the
<A HREF = "#Tersoff">Tersoff</A> potential (see the <A HREF = "pair_tersoff.html">pair_style
tersoff</A> command); thus for a zero-charge pure
element system with no van der Waals interaction, the COMB potential
reduces to Tersoff potential, typically truncated at a short cutoff,
e.g. 3 to 4 Angstroms. The long-range Coulombic term uses the Wolf
summation method described in <A HREF = "#Wolf">Wolf</A>, spherically truncated at a
longer cutoff, e.g. 12 Angstroms.
</P>
<P>The COMB potential is a variable charge potential. The equilibrium
charge on each atom is calculated by the electronegativity
equalization (QEq) method. See <A HREF = "#Rick">Rick</A> for further details.
This is implemented by the <A HREF = "fix_qeq_comb.html">fix qeq/comb</A> command,
which should normally be specified in the input script when running a
model with the COMB potential. The <A HREF = "fix_qeq_comb.html">fix qeq/comb</A>
command has options that determine how often charge equilibration is
performed, its convergence criterion, and which atoms are included in
the calculation.
</P>
<P>Only a single pair_coeff command is used with the <I>comb</I> style which
specifies the COMB potential file with parameters for all needed
elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the potential file in the pair_coeff
command, where N is the number of LAMMPS atom types. The provided
potential file <I>ffield.comb</I> contains all currently-available COMB
parameterizations: for Si, Cu, Hf, Ti, O, their oxides and Zr, Zn and
U metals.
</P>
<P>For example, if your LAMMPS simulation of a Si/SiO<sub>2</sub>/
HfO<sub>2</sub> interface has 4 atom types, and you want the 1st and
last to be Si, the 2nd to be Hf, and the 3rd to be O, and you would
use the following pair_coeff command:
</P>
<PRE>pair_coeff * * ../potentials/ffield.comb Si Hf O Si
</PRE>
<P>The first two arguments must be * * so as to span all LAMMPS atom
types. The first and last Si arguments map LAMMPS atom types 1 and 4
to the Si element in the <I>ffield.comb</I> file. The second Hf argument
maps LAMMPS atom type 2 to the Hf element, and the third O argument
maps LAMMPS atom type 3 to the O element in the potential file. If a
mapping value is specified as NULL, the mapping is not performed.
This can be used when a <I>comb</I> potential is used as part of the
<I>hybrid</I> pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
</P>
<P>The <I>ffield.comb</I> potential file is in the <I>potentials</I> directory of
the LAMMPS distribution. Lines that are not blank or comments
(starting with #) define parameters for a triplet of elements. The 49
parameters in a single entry correspond to coefficients in the formula
above:
</P>
<UL><LI>element 1 (the center atom in a 3-body interaction)
<LI>element 2 (the atom bonded to the center atom)
<LI>element 3 (the atom influencing the 1-2 bond in a bond-order sense)
<LI>m
<LI>c
<LI>d
<LI>h (cos_theta0 (can be a value -1 or 1))
<LI>n
<LI>beta
<LI>lambda21, lambda2 of element 1 (1/distance units)
<LI>lambda22, lambda2 of element 2 (1/distance units)
<LI>B of element 1 (energy units)
<LI>B of element 2 (energy units)
<LI>R (cutoff, distance units, 0.5*(r_outer + r_inner))
<LI>D (cutoff, distance units, R - r_inner)
<LI>lambda11, lambda1 of element 1 (1/distance units)
<LI>lambda12, lambda1 of element 2 (1/distance units)
<LI>A of element 1 (energy units)
<LI>A of element 2 (energy units)
<LI>K_LP_1 (energy units, 1st order Legendre polynomial coefficient)
<LI>K_LP_3 (energy units, 3rd order Legendre polynomial coefficient)
<LI>K_LP_6 (energy units, 6th order Legendre polynomial coefficient)
<LI>A123 (cos_theta, theta = equilibrium MOM or OMO bond angles)
<LI>Aconf (cos_theta, theta = equilibrium MOM or OMO bond-bending coefficient)
<LI>addrep (energy units, additional repulsion)
<LI>R_omiga_a (unit-less scaler for A)
<LI>R_omiga_b (unit-less scaler for B)
<LI>R_omiga_c (unit-less scaler for 0.5*(lambda21+lambda22))
<LI>R_omiga_d (unit-less scaler for 0.5*(lambda11+lambda12))
<LI>QL1 (charge units, lower charge limit for element 1)
<LI>QU1 (charge units, upper charge limit for element 1)
<LI>DL1 (distance units, ion radius of element 1 with charge QL1)
<LI>DU1 (distance units, ion radius of element 1 with charge QU1)
<LI>QL2 (charge units, lower charge limit for element 2)
<LI>QU2 (charge units, upper charge limit for element 2)
<LI>DL2 (distance units, ion radius of element 2 with charge QL2)
<LI>DU2 (distance units, ion radius of element 2 with charge QU2)
<LI>chi (energy units, self energy 1st power term)
<LI>dJ (energy units, self energy 2nd power term)
<LI>dK (energy units, self energy 3rd power term)
<LI>dL (energy units, self energy 4th power term)
<LI>dM (energy units, self energy 6th power term)
<LI>esm (distance units, orbital exponent)
<LI>cmn1 (self energy penalty, rho 1 of element 1)
<LI>cml1 (self energy penalty, rho 1 of element 2)
<LI>cmn2 (self energy penalty, rho 2 of element 1)
<LI>cmn2 (self energy penalty, rho 2 of element 2)
<LI>coulcut (long range Coulombic cutoff, distance units)
<LI>hfocor (coordination term)
</UL>
<P>The parameterization of COMB potentials start with a pure element
(e.g. Si, Cu) then extend to its oxide and polymorphs
(e.g. SiO<sub>2</sub>, Cu<sub>2</sub>O). For interactions not
involving oxygen (e.g. Si-Cu or Hf-Zr), the COMB potential uses a
mixing rule to generate these parameters. For furthur details on the
parameterization and parameters, see the <A HREF = "pair_tersoff.html">Tersoff</A>
doc page and the COMB publications <A HREF = "#COMB_1">(COMB_1)</A> and
<A HREF = "#COMB_2">(COMB_2)</A>. For more details on 3-body interaction types
(e.g. SiSiO vs SiOSi), the mixing rule, and how to generate the
potential file, please see the <A HREF = "pair_tersoff.html">Tersoff</A> doc page.
</P>
<P>In the potentials directory, the file <I>ffield.comb</I> provides the
LAMMPS parameters for COMB's Si, Cu, Ti, Hf and their oxides, as well
as pure U, Zn and Zr metals. This file can be used for pure elements
(e.g. Si, Zr), binary oxides, binary alloys (e.g. SiCu, TiZr), and
complex systems. Note that alloys and complex systems require all
3-body entries be pre-defined in the potential file.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style, pair_coeff, and <A HREF = "fix_qeq_comb.html">fix
qeq/comb</A> commands in an input script that reads a
restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more info.
</P>
<P>This pair style requires the <A HREF = "newton.html">newton</A> setting to be "on"
for pair interactions.
</P>
<P>The COMB potentials in the <I>ffield.comb</I> file provided with LAMMPS
(see the potentials directory) are parameterized for metal
<A HREF = "units.html">units</A>. You can use the COMB potential with any LAMMPS
units, but you would need to create your own COMB potential file with
coefficients listed in the appropriate units if your simulation
doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_style.html">pair_style</A>, <A HREF = "pair_coeff.html">pair_coeff</A>,
<A HREF = "fix_qeq_comb.html">fix_qeq/comb</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "COMB_1"></A>
<P><B>(COMB_1)</B> J. Yu, S. B. Sinnott, S. R. Phillpot, Phys Rev B, 75, 085311 (2007),
</P>
<A NAME = "COMB_2"></A>
<P><B>(COMB_2)</B> T.-R. Shan, B. D. Devine, T. W. Kemper, S. B. Sinnott, S. R.
Phillpot, Phys Rev B, 81, 125328 (2010).
</P>
<A NAME = "Tersoff"></A>
<P><B>(Tersoff)</B> J. Tersoff, Phys Rev B, 37, 6991 (1988).
</P>
<A NAME = "Rick"></A>
-<P><B>(Rick)</B> S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys 101, 16141
+<P><B>(Rick)</B> S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys 101, 6141
(1994).
</P>
<A NAME = "Wolf"></A>
<P><B>(Wolf)</B> D. Wolf, P. Keblinski, S. R. Phillpot, J. Eggebrecht, J Chem
Phys, 110, 8254 (1999).
</P>
</HTML>
diff --git a/doc/pair_comb.txt b/doc/pair_comb.txt
index ed625ba62..2ea8f2fc7 100644
--- a/doc/pair_comb.txt
+++ b/doc/pair_comb.txt
@@ -1,252 +1,252 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style comb command :h3
pair_style comb/omp command :h3
[Syntax:]
pair_style comb :pre
[Examples:]
pair_style comb
pair_coeff * * ../potentials/ffield.comb Si
pair_coeff * * ../potentials/ffield.comb Hf Si O :pre
[Description:]
Style {comb} computes a variable charge COMB (Charge-Optimized
Many-Body) potential as described in "(COMB_1)"_#COMB_1 and
"(COMB_2)"_#COMB_2. The energy E of a system of atoms
is given by
:c,image(Eqs/pair_comb1.jpg)
where {E<sub>T</sub>} is the total potential energy of the system,
{E<sup>S</sup><sub>i</sub>} is the self-energy term of atom {i},
{V<sub>ij</sub>} is the interatomic potential between the {i}th and
{j}th atoms, {r<sub>ij</sub>} is the distance of the atoms {i} and
{j}, and {q<sub>i</sub>} and {q<sub>j</sub>} are charges of the atoms,
and {E<sup>BB</sup><sub>i</sub>} is the bond-bending term of atom {i}.
The interatomic potential energy {V<sub>ij</sub>} consists of four
components: two-body short-range repulsion,
{U<sup>R</sup><sub>ij</sub>}, many-body short-range attraction,
{U<sup>A</sup><sub>ij</sub>}, long-range Coulombic electrostatic
interaction, {U<sup>I</sup><sub>ij</sub>}, and van der Waals energy,
{U<sup>V</sup><sub>ij</sub>}, which are defined as:
:c,image(Eqs/pair_comb2.jpg)
The short-range repulsion and attraction are based on the
"Tersoff"_#Tersoff potential (see the "pair_style
tersoff"_pair_tersoff.html command); thus for a zero-charge pure
element system with no van der Waals interaction, the COMB potential
reduces to Tersoff potential, typically truncated at a short cutoff,
e.g. 3 to 4 Angstroms. The long-range Coulombic term uses the Wolf
summation method described in "Wolf"_#Wolf, spherically truncated at a
longer cutoff, e.g. 12 Angstroms.
The COMB potential is a variable charge potential. The equilibrium
charge on each atom is calculated by the electronegativity
equalization (QEq) method. See "Rick"_#Rick for further details.
This is implemented by the "fix qeq/comb"_fix_qeq_comb.html command,
which should normally be specified in the input script when running a
model with the COMB potential. The "fix qeq/comb"_fix_qeq_comb.html
command has options that determine how often charge equilibration is
performed, its convergence criterion, and which atoms are included in
the calculation.
Only a single pair_coeff command is used with the {comb} style which
specifies the COMB potential file with parameters for all needed
elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the potential file in the pair_coeff
command, where N is the number of LAMMPS atom types. The provided
potential file {ffield.comb} contains all currently-available COMB
parameterizations: for Si, Cu, Hf, Ti, O, their oxides and Zr, Zn and
U metals.
For example, if your LAMMPS simulation of a Si/SiO<sub>2</sub>/
HfO<sub>2</sub> interface has 4 atom types, and you want the 1st and
last to be Si, the 2nd to be Hf, and the 3rd to be O, and you would
use the following pair_coeff command:
pair_coeff * * ../potentials/ffield.comb Si Hf O Si :pre
The first two arguments must be * * so as to span all LAMMPS atom
types. The first and last Si arguments map LAMMPS atom types 1 and 4
to the Si element in the {ffield.comb} file. The second Hf argument
maps LAMMPS atom type 2 to the Hf element, and the third O argument
maps LAMMPS atom type 3 to the O element in the potential file. If a
mapping value is specified as NULL, the mapping is not performed.
This can be used when a {comb} potential is used as part of the
{hybrid} pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
The {ffield.comb} potential file is in the {potentials} directory of
the LAMMPS distribution. Lines that are not blank or comments
(starting with #) define parameters for a triplet of elements. The 49
parameters in a single entry correspond to coefficients in the formula
above:
element 1 (the center atom in a 3-body interaction)
element 2 (the atom bonded to the center atom)
element 3 (the atom influencing the 1-2 bond in a bond-order sense)
m
c
d
h (cos_theta0 (can be a value -1 or 1))
n
beta
lambda21, lambda2 of element 1 (1/distance units)
lambda22, lambda2 of element 2 (1/distance units)
B of element 1 (energy units)
B of element 2 (energy units)
R (cutoff, distance units, 0.5*(r_outer + r_inner))
D (cutoff, distance units, R - r_inner)
lambda11, lambda1 of element 1 (1/distance units)
lambda12, lambda1 of element 2 (1/distance units)
A of element 1 (energy units)
A of element 2 (energy units)
K_LP_1 (energy units, 1st order Legendre polynomial coefficient)
K_LP_3 (energy units, 3rd order Legendre polynomial coefficient)
K_LP_6 (energy units, 6th order Legendre polynomial coefficient)
A123 (cos_theta, theta = equilibrium MOM or OMO bond angles)
Aconf (cos_theta, theta = equilibrium MOM or OMO bond-bending coefficient)
addrep (energy units, additional repulsion)
R_omiga_a (unit-less scaler for A)
R_omiga_b (unit-less scaler for B)
R_omiga_c (unit-less scaler for 0.5*(lambda21+lambda22))
R_omiga_d (unit-less scaler for 0.5*(lambda11+lambda12))
QL1 (charge units, lower charge limit for element 1)
QU1 (charge units, upper charge limit for element 1)
DL1 (distance units, ion radius of element 1 with charge QL1)
DU1 (distance units, ion radius of element 1 with charge QU1)
QL2 (charge units, lower charge limit for element 2)
QU2 (charge units, upper charge limit for element 2)
DL2 (distance units, ion radius of element 2 with charge QL2)
DU2 (distance units, ion radius of element 2 with charge QU2)
chi (energy units, self energy 1st power term)
dJ (energy units, self energy 2nd power term)
dK (energy units, self energy 3rd power term)
dL (energy units, self energy 4th power term)
dM (energy units, self energy 6th power term)
esm (distance units, orbital exponent)
cmn1 (self energy penalty, rho 1 of element 1)
cml1 (self energy penalty, rho 1 of element 2)
cmn2 (self energy penalty, rho 2 of element 1)
cmn2 (self energy penalty, rho 2 of element 2)
coulcut (long range Coulombic cutoff, distance units)
hfocor (coordination term) :ul
The parameterization of COMB potentials start with a pure element
(e.g. Si, Cu) then extend to its oxide and polymorphs
(e.g. SiO<sub>2</sub>, Cu<sub>2</sub>O). For interactions not
involving oxygen (e.g. Si-Cu or Hf-Zr), the COMB potential uses a
mixing rule to generate these parameters. For furthur details on the
parameterization and parameters, see the "Tersoff"_pair_tersoff.html
doc page and the COMB publications "(COMB_1)"_#COMB_1 and
"(COMB_2)"_#COMB_2. For more details on 3-body interaction types
(e.g. SiSiO vs SiOSi), the mixing rule, and how to generate the
potential file, please see the "Tersoff"_pair_tersoff.html doc page.
In the potentials directory, the file {ffield.comb} provides the
LAMMPS parameters for COMB's Si, Cu, Ti, Hf and their oxides, as well
as pure U, Zn and Zr metals. This file can be used for pure elements
(e.g. Si, Zr), binary oxides, binary alloys (e.g. SiCu, TiZr), and
complex systems. Note that alloys and complex systems require all
3-body entries be pre-defined in the potential file.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style, pair_coeff, and "fix
qeq/comb"_fix_qeq_comb.html commands in an input script that reads a
restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the "Making LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires the "newton"_newton.html setting to be "on"
for pair interactions.
The COMB potentials in the {ffield.comb} file provided with LAMMPS
(see the potentials directory) are parameterized for metal
"units"_units.html. You can use the COMB potential with any LAMMPS
units, but you would need to create your own COMB potential file with
coefficients listed in the appropriate units if your simulation
doesn't use "metal" units.
[Related commands:]
"pair_style"_pair_style.html, "pair_coeff"_pair_coeff.html,
"fix_qeq/comb"_fix_qeq_comb.html
[Default:] none
:line
:link(COMB_1)
[(COMB_1)] J. Yu, S. B. Sinnott, S. R. Phillpot, Phys Rev B, 75, 085311 (2007),
:link(COMB_2)
[(COMB_2)] T.-R. Shan, B. D. Devine, T. W. Kemper, S. B. Sinnott, S. R.
Phillpot, Phys Rev B, 81, 125328 (2010).
:link(Tersoff)
[(Tersoff)] J. Tersoff, Phys Rev B, 37, 6991 (1988).
:link(Rick)
-[(Rick)] S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys 101, 16141
+[(Rick)] S. W. Rick, S. J. Stuart, B. J. Berne, J Chem Phys 101, 6141
(1994).
:link(Wolf)
[(Wolf)] D. Wolf, P. Keblinski, S. R. Phillpot, J. Eggebrecht, J Chem
Phys, 110, 8254 (1999).
diff --git a/doc/pair_coul.html b/doc/pair_coul.html
index 6b6af2345..5aad58b33 100644
--- a/doc/pair_coul.html
+++ b/doc/pair_coul.html
@@ -1,163 +1,196 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style coul/cut command
</H3>
<H3>pair_style coul/cut/omp command
</H3>
<H3>pair_style coul/debye command
</H3>
<H3>pair_style coul/debye/omp command
</H3>
<H3>pair_style coul/long command
</H3>
+<H3>pair_style coul/long/omp command
+</H3>
<H3>pair_style coul/long/gpu command
</H3>
-<H3>pair_style coul/long/omp command
+<H3>pair_style coul/wolf command
</H3>
<P><B>Syntax:</B>
</P>
-<P>pair_style coul/cut cutoff
+<PRE>pair_style coul/cut cutoff
pair_style coul/debye kappa cutoff
pair_style coul/long cutoff
-</P>
+pair_style coul/long/gpu cutoff
+pair_sytle coul/wolf alpha cutoff
+</PRE>
<UL><LI>cutoff = global cutoff for Coulombic interactions
<LI>kappa = Debye length (inverse distance units)
+<LI>alpha = damping parameter (inverse distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style coul/cut 2.5
pair_coeff * *
pair_coeff 2 2 3.5
</PRE>
<PRE>pair_style coul/debye 1.4 3.0
pair_coeff * *
pair_coeff 2 2 3.5
</PRE>
<PRE>pair_style coul/long 10.0
pair_coeff * *
</PRE>
+<P>pair_style coul/wolf 0.2 9.0
+pair_coeff * *
+</P>
<P><B>Description:</B>
</P>
<P>The <I>coul/cut</I> style computes the standard Coulombic interaction
potential given by
</P>
<CENTER><IMG SRC = "Eqs/pair_coulomb.jpg">
</CENTER>
<P>where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, and epsilon is the dielectric constant which can be set
by the <A HREF = "dielectric.html">dielectric</A> command. The cutoff Rc truncates
the interaction distance.
</P>
<P>Style <I>coul/debye</I> adds an additional exp() damping factor to the
Coulombic term, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_debye.jpg">
</CENTER>
<P>where kappa is the Debye length. This potential is another way to
mimic the screening effect of a polar solvent.
</P>
+<P>Style <I>coul/wolf</I> computes Coulombic interactions via the Wolf
+summation method, described in <A HREF = "#Wolf">Wolf</A>, given by:
+</P>
+<CENTER><IMG SRC = "Eqs/pair_coul_wolf.jpg">
+</CENTER>
+<P>where <I>alpha</I> is the damping parameter, and erc() and erfc() are
+error-fuction and complementary error-function terms. This potential
+is essentially a short-range, spherically-truncated,
+charge-neutralized, shifted, pairwise <I>1/r</I> summation. With a
+manipulation of adding and substracting a self term (for i = j) to the
+first and second term on the right-hand-side, respectively, and a
+small enough <I>alpha</I> damping parameter, the second term shrinks and
+the potential becomes a rapidly-converging real-space summation. With
+a long enough cutoff and small enough alpha parameter, the energy and
+forces calcluated by the Wolf summation method approach those of the
+Ewald sum. So it is a means of getting effective long-range
+interactions with a short-range potential.
+</P>
<P>Style <I>coul/long</I> computes the same Coulombic interactions as style
<I>coul/cut</I> except that an additional damping factor is applied so it
can be used in conjunction with the <A HREF = "kspace_style.html">kspace_style</A>
command and its <I>ewald</I> or <I>pppm</I> option. The Coulombic cutoff
specified for this style means that pairwise interactions within this
distance are computed directly; interactions outside that distance are
computed in reciprocal space.
</P>
<P>These potentials are designed to be combined with other pair
potentials via the <A HREF = "pair_hybrid.html">pair_style hybrid/overlay</A>
command. This is because they have no repulsive core. Hence if they
are used by themselves, there will be no repulsion to keep two
oppositely charged particles from overlapping each other.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>cutoff (distance units)
</UL>
<P>For <I>coul/cut</I> and <I>coul/debye</I>, the cutoff coefficient is optional.
If it is not used (as in some of the examples above), the default
global value specified in the pair_style command is used.
</P>
<P>For <I>coul/long</I> no cutoff can be specified for an individual I,J type
pair via the pair_coeff command. All type pairs use the same global
Coulombic cutoff specified in the pair_style command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the cutoff distance for the
<I>coul/cut</I> style can be mixed. The default mix value is <I>geometric</I>.
See the "pair_modify" command for details.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> shift option is not relevant
for these pair styles.
</P>
<P>The <I>coul/long</I> style supports the <A HREF = "pair_modify.html">pair_modify</A>
table option for tabulation of the short-range portion of the
long-range Coulombic interaction.
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>These pair styles write their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>coul/long</I> style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_hybrid.html">pair_style
hybrid/overlay</A>
</P>
<P><B>Default:</B> none
</P>
+<HR>
+
+<A NAME = "Wolf"></A>
+
+<P><B>(Wolf)</B> D. Wolf, P. Keblinski, S. R. Phillpot, J. Eggebrecht, J Chem
+Phys, 110, 8254 (1999).
+</P>
</HTML>
diff --git a/doc/pair_coul.txt b/doc/pair_coul.txt
index 44168cd1c..42b0582de 100644
--- a/doc/pair_coul.txt
+++ b/doc/pair_coul.txt
@@ -1,153 +1,183 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style coul/cut command :h3
pair_style coul/cut/omp command :h3
pair_style coul/debye command :h3
pair_style coul/debye/omp command :h3
pair_style coul/long command :h3
pair_style coul/long/omp command :h3
pair_style coul/long/gpu command :h3
+pair_style coul/wolf command :h3
[Syntax:]
pair_style coul/cut cutoff
pair_style coul/debye kappa cutoff
pair_style coul/long cutoff
-pair_style coul/long/gpu cutoff :pre
+pair_style coul/long/gpu cutoff
+pair_sytle coul/wolf alpha cutoff :pre
cutoff = global cutoff for Coulombic interactions
-kappa = Debye length (inverse distance units) :ul
+kappa = Debye length (inverse distance units)
+alpha = damping parameter (inverse distance units) :ul
[Examples:]
pair_style coul/cut 2.5
pair_coeff * *
pair_coeff 2 2 3.5 :pre
pair_style coul/debye 1.4 3.0
pair_coeff * *
pair_coeff 2 2 3.5 :pre
pair_style coul/long 10.0
pair_coeff * * :pre
+pair_style coul/wolf 0.2 9.0
+pair_coeff * *
+
[Description:]
The {coul/cut} style computes the standard Coulombic interaction
potential given by
:c,image(Eqs/pair_coulomb.jpg)
where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, and epsilon is the dielectric constant which can be set
by the "dielectric"_dielectric.html command. The cutoff Rc truncates
the interaction distance.
Style {coul/debye} adds an additional exp() damping factor to the
Coulombic term, given by
:c,image(Eqs/pair_debye.jpg)
where kappa is the Debye length. This potential is another way to
mimic the screening effect of a polar solvent.
+Style {coul/wolf} computes Coulombic interactions via the Wolf
+summation method, described in "Wolf"_#Wolf, given by:
+
+:c,image(Eqs/pair_coul_wolf.jpg)
+
+where {alpha} is the damping parameter, and erc() and erfc() are
+error-fuction and complementary error-function terms. This potential
+is essentially a short-range, spherically-truncated,
+charge-neutralized, shifted, pairwise {1/r} summation. With a
+manipulation of adding and substracting a self term (for i = j) to the
+first and second term on the right-hand-side, respectively, and a
+small enough {alpha} damping parameter, the second term shrinks and
+the potential becomes a rapidly-converging real-space summation. With
+a long enough cutoff and small enough alpha parameter, the energy and
+forces calcluated by the Wolf summation method approach those of the
+Ewald sum. So it is a means of getting effective long-range
+interactions with a short-range potential.
+
Style {coul/long} computes the same Coulombic interactions as style
{coul/cut} except that an additional damping factor is applied so it
can be used in conjunction with the "kspace_style"_kspace_style.html
command and its {ewald} or {pppm} option. The Coulombic cutoff
specified for this style means that pairwise interactions within this
distance are computed directly; interactions outside that distance are
computed in reciprocal space.
These potentials are designed to be combined with other pair
potentials via the "pair_style hybrid/overlay"_pair_hybrid.html
command. This is because they have no repulsive core. Hence if they
are used by themselves, there will be no repulsion to keep two
oppositely charged particles from overlapping each other.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
cutoff (distance units) :ul
For {coul/cut} and {coul/debye}, the cutoff coefficient is optional.
If it is not used (as in some of the examples above), the default
global value specified in the pair_style command is used.
For {coul/long} no cutoff can be specified for an individual I,J type
pair via the pair_coeff command. All type pairs use the same global
Coulombic cutoff specified in the pair_style command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the cutoff distance for the
{coul/cut} style can be mixed. The default mix value is {geometric}.
See the "pair_modify" command for details.
The "pair_modify"_pair_modify.html shift option is not relevant
for these pair styles.
The {coul/long} style supports the "pair_modify"_pair_modify.html
table option for tabulation of the short-range portion of the
long-range Coulombic interaction.
These pair styles do not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
These pair styles write their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
The {coul/long} style is part of the KSPACE package. It is only
enabled if LAMMPS was built with that package (which it is by
default). See the "Making LAMMPS"_Section_start.html#start_3 section
for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_style
hybrid/overlay"_pair_hybrid.html
[Default:] none
+
+:line
+
+:link(Wolf)
+[(Wolf)] D. Wolf, P. Keblinski, S. R. Phillpot, J. Eggebrecht, J Chem
+Phys, 110, 8254 (1999).
diff --git a/doc/pair_coul_diel.html b/doc/pair_coul_diel.html
new file mode 100644
index 000000000..c7ce1de68
--- /dev/null
+++ b/doc/pair_coul_diel.html
@@ -0,0 +1,118 @@
+<HTML>
+<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
+</CENTER>
+
+
+
+
+
+
+<HR>
+
+<H3>pair_style coul/diel command
+</H3>
+<P><B>Syntax:</B>
+</P>
+<PRE>pair_style coul/diel cutoff
+</PRE>
+<P>cutoff = global cutoff (distance units)
+</P>
+<P><B>Examples:</B>
+</P>
+<PRE>pair_style coul/diel 3.5
+pair_coeff 1 4 78. 1.375 0.112
+</PRE>
+<P><B>Description:</B>
+</P>
+<P>Style <I>coul/diel</I> computes a Coulomb correction for implict solvent
+ion interactions in which the dielectric perimittivity is distance dependent.
+The dielectric permittivity epsilon_D(r) connects to limiting regimes:
+One limit is defined by a small dielectric permittivity (close to vacuum)
+at or close to contact seperation between the ions. At larger separations
+the dielectric permittivity reaches a bulk value used in the regular Coulomb
+interaction coul/long or coul/cut.
+The transition is modeled by a hyperbolic function which is incorporated
+in the Coulomb correction term for small ion separations as follows
+</P>
+<CENTER><IMG SRC = "Eqs/pair_coul_diel.jpg">
+</CENTER>
+<P>where r_me is the inflection point of epsilon_D(r) and sigma_e is a slope
+defining length scale. C is the same Coulomb conversion factor as in the
+pair_styles coul/cut, coul/long, and coul/debye. In this way the Coulomb
+interaction between ions is corrected at small distances r. The lower
+limit of epsilon_D(r->0)=5.2 due to dielectric saturation <A HREF = "#Stiles">(Stiles)</A>
+while the Coulomb interaction reaches its bulk limit by setting
+epsilon_D(r->\infty)=epsilon, the bulk value of the solvent which is 78
+for water at 298K.
+</P>
+<P>Examples of the use of this type of Coulomb interaction include implicit
+solvent simulations of salt ions
+<A HREF = "#Lenart">(Lenart)</A> and of ionic surfactants <A HREF = "#Jusufi">(Jusufi)</A>.
+Note that this potential is only reasonable for implicit solvent simulations
+and in combiantion with coul/cut or coul/long. It is also usually combined
+with gauss/cut, see <A HREF = "#Lenart">(Lenart)</A> or <A HREF = "#Jusufi">(Jusufi)</A>.
+</P>
+<P>The following coefficients must be defined for each pair of atom
+types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the example
+above, or in the data file or restart files read by the
+<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
+commands:
+</P>
+<UL><LI>epsilon (no units)
+<LI>r_me (distance units)
+<LI>sigma_e (distance units)
+</UL>
+<P>The global cutoff (r_c) specified in the pair_style command is used.
+</P>
+<HR>
+
+<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
+</P>
+<P>This pair style does not support parameter mixing. Coefficients must be given explicitly for each type of particle pairs.
+</P>
+<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
+option for the energy of the Gauss-potential portion of the pair
+interaction.
+</P>
+<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
+for this pair style.
+</P>
+<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
+tail option for adding long-range tail corrections to energy and
+pressure.
+</P>
+<P>This pair style can only be used via the <I>pair</I> keyword of the
+<A HREF = "run_style.html">run_style respa</A> command. It does not support the
+<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
+</P>
+<P><B>Restrictions:</B>
+</P>
+<P>This style is part of the "user-misc" package. It is only enabled
+if LAMMPS was built with that package. See the <A HREF = "Section_start.html#2_3">Making
+LAMMPS</A> section for more info.
+</P>
+<P><B>Related commands:</B>
+</P>
+<P><A HREF = "pair_coeff.html">pair_coeff</A>
+<A HREF = "pair_gauss.html">pair_style gauss/cut</A>
+</P>
+<P><B>Default:</B> none
+</P>
+<HR>
+
+<A NAME = "Stiles"></A>
+
+<P><B>(Stiles)</B> Stiles , Hubbard, and Kayser, J Chem Phys, 77,
+6189 (1982).
+</P>
+<A NAME = "Lenart"></A>
+
+<P><B>(Lenart)</B> Lenart , Jusufi, and Panagiotopoulos, J Chem Phys, 126,
+044509 (2007).
+</P>
+<A NAME = "Jusufi"></A>
+
+<P><B>(Jusufi)</B> Jusufi, Hynninen, and Panagiotopoulos, J Phys Chem B, 112,
+13783 (2008).
+</P>
+</HTML>
diff --git a/doc/pair_coul_diel.txt b/doc/pair_coul_diel.txt
new file mode 100644
index 000000000..21cac35bf
--- /dev/null
+++ b/doc/pair_coul_diel.txt
@@ -0,0 +1,111 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style coul/diel command :h3
+
+[Syntax:]
+
+pair_style coul/diel cutoff :pre
+
+cutoff = global cutoff (distance units)
+
+[Examples:]
+
+pair_style coul/diel 3.5
+pair_coeff 1 4 78. 1.375 0.112 :pre
+
+
+[Description:]
+
+Style {coul/diel} computes a Coulomb correction for implict solvent
+ion interactions in which the dielectric perimittivity is distance dependent.
+The dielectric permittivity epsilon_D(r) connects to limiting regimes:
+One limit is defined by a small dielectric permittivity (close to vacuum)
+at or close to contact seperation between the ions. At larger separations
+the dielectric permittivity reaches a bulk value used in the regular Coulomb
+interaction coul/long or coul/cut.
+The transition is modeled by a hyperbolic function which is incorporated
+in the Coulomb correction term for small ion separations as follows
+
+:c,image(Eqs/pair_coul_diel.jpg)
+
+where r_me is the inflection point of epsilon_D(r) and sigma_e is a slope
+defining length scale. C is the same Coulomb conversion factor as in the
+pair_styles coul/cut, coul/long, and coul/debye. In this way the Coulomb
+interaction between ions is corrected at small distances r. The lower
+limit of epsilon_D(r->0)=5.2 due to dielectric saturation "(Stiles)"_#Stiles
+while the Coulomb interaction reaches its bulk limit by setting
+epsilon_D(r->\infty)=epsilon, the bulk value of the solvent which is 78
+for water at 298K.
+
+Examples of the use of this type of Coulomb interaction include implicit
+solvent simulations of salt ions
+"(Lenart)"_#Lenart and of ionic surfactants "(Jusufi)"_#Jusufi.
+Note that this potential is only reasonable for implicit solvent simulations
+and in combiantion with coul/cut or coul/long. It is also usually combined
+with gauss/cut, see "(Lenart)"_#Lenart or "(Jusufi)"_#Jusufi.
+
+The following coefficients must be defined for each pair of atom
+types via the "pair_coeff"_pair_coeff.html command as in the example
+above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+epsilon (no units)
+r_me (distance units)
+sigma_e (distance units) :ul
+
+The global cutoff (r_c) specified in the pair_style command is used.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+This pair style does not support parameter mixing. Coefficients must be given explicitly for each type of particle pairs.
+
+This pair style supports the "pair_modify"_pair_modify.html shift
+option for the energy of the Gauss-potential portion of the pair
+interaction.
+
+The "pair_modify"_pair_modify.html table option is not relevant
+for this pair style.
+
+This pair style does not support the "pair_modify"_pair_modify.html
+tail option for adding long-range tail corrections to energy and
+pressure.
+
+This pair style can only be used via the {pair} keyword of the
+"run_style respa"_run_style.html command. It does not support the
+{inner}, {middle}, {outer} keywords.
+
+[Restrictions:]
+
+This style is part of the "user-misc" package. It is only enabled
+if LAMMPS was built with that package. See the "Making
+LAMMPS"_Section_start.html#2_3 section for more info.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html
+"pair_style gauss/cut"_pair_gauss.html
+
+[Default:] none
+
+:line
+
+:link(Stiles)
+[(Stiles)] Stiles , Hubbard, and Kayser, J Chem Phys, 77,
+6189 (1982).
+
+:link(Lenart)
+[(Lenart)] Lenart , Jusufi, and Panagiotopoulos, J Chem Phys, 126,
+044509 (2007).
+
+:link(Jusufi)
+[(Jusufi)] Jusufi, Hynninen, and Panagiotopoulos, J Phys Chem B, 112,
+13783 (2008).
diff --git a/doc/pair_dipole.html b/doc/pair_dipole.html
index 0c259887b..3f1a5ce94 100644
--- a/doc/pair_dipole.html
+++ b/doc/pair_dipole.html
@@ -1,216 +1,216 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style dipole/cut command
</H3>
<H3>pair_style dipole/cut/omp command
</H3>
<H3>pair_style dipole/sf command
</H3>
<H3>pair_style dipole/sf/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style dipole/cut cutoff (cutoff2)
</PRE>
<PRE>pair_style dipole/sf cutoff (cutoff2)
</PRE>
<UL><LI>cutoff = global cutoff LJ (and Coulombic if only 1 arg) (distance units)
<LI>cutoff2 = global cutoff for Coulombic (optional) (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style dipole/cut 10.0
pair_coeff * * 1.0 1.0
pair_coeff 2 3 1.0 1.0 2.5 4.0
</PRE>
<PRE>pair_style dipole/sf 9.0
pair_coeff * * 1.0 1.0
pair_coeff 2 3 1.0 1.0 2.5 4.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>dipole/cut</I> computes interactions between pairs of particles
that each have a charge and/or a point dipole moment. In addition to
the usual Lennard-Jones interaction between the particles (Elj) the
charge-charge (Eqq), charge-dipole (Eqp), and dipole-dipole (Epp)
interactions are computed by these formulas for the energy (E), force
(F), and torque (T) between particles I and J.
</P>
<CENTER><IMG SRC = "Eqs/pair_dipole.jpg">
</CENTER>
<P>where qi and qj are the charges on the two particles, pi and pj are
the dipole moment vectors of the two particles, r is their separation
distance, and the vector r = Ri - Rj is the separation vector between
the two particles. Note that Eqq and Fqq are simply Coulombic energy
and force, Fij = -Fji as symmetric forces, and Tij != -Tji since the
torques do not act symmetrically. These formulas are discussed in
<A HREF = "#Allen">(Allen)</A> and in <A HREF = "#Toukmaji">(Toukmaji)</A>.
</P>
<P>Style <I>dipole/sf</I> computes "shifted-force" interactions between pairs
of particles that each have a charge and/or a point dipole moment. In
general, a shifted-force potential is a (sligthly) modified potential
containing extra terms that make both the energy and its derivative go
to zero at the cutoff distance; this removes (cutoff-related) problems
in energy conservation and any numerical instability in the equations
of motion <A HREF = "#Allen">(Allen)</A>. Shifted-force interactions for the
Lennard-Jones (E_LJ), charge-charge (Eqq), charge-dipole (Eqp),
dipole-charge (Epq) and dipole-dipole (Epp) potentials are computed by
these formulas for the energy (E), force (F), and torque (T) between
particles I and J:
</P>
<CENTER><IMG SRC = "Eqs/pair_dipole_sf.jpg">
</CENTER>
<CENTER><IMG SRC = "Eqs/pair_dipole_sf2.jpg">
</CENTER>
<P>where epsilon and sigma are the standard LJ parameters, r_c is the
cutoff, qi and qj are the charges on the two particles, pi and pj are
the dipole moment vectors of the two particles, r is their separation
distance, and the vector r = Ri - Rj is the separation vector between
the two particles. Note that Eqq and Fqq are simply Coulombic energy
and force, Fij = -Fji as symmetric forces, and Tij != -Tji since the
torques do not act symmetrically. The shifted-force formula for the
Lennard-Jones potential is reported in <A HREF = "#Stoddard">(Stoddard)</A>. The
original (unshifted) formulas for the electrostatic potentials, forces
and torques can be found in <A HREF = "#Price">(Price)</A>. The shifted-force
electrostatic potentials have been obtained by applying equation 5.13
of <A HREF = "#Allen">(Allen)</A>. The formulas for the corresponding forces and
torques have been obtained by applying the 'chain rule' as in appendix
C.3 of <A HREF = "#Allen">(Allen)</A>.
</P>
<P>If one cutoff is specified in the pair_style command, it is used for
both the LJ and Coulombic (q,p) terms. If two cutoffs are specified,
they are used as cutoffs for the LJ and Coulombic (q,p) terms
respectively.
</P>
<P>Atoms with dipole moments should be integrated using the <A HREF = "fix_nve_sphere.html">fix
nve/sphere update dipole</A> command to rotate the
dipole moments. The <A HREF = "compute_temp_sphere.html">compute temp/sphere</A>
command can be used to monitor the temperature, since it includes
rotational degrees of freedom. The <A HREF = "atom_style.html">atom_style
dipole</A> command should be used since it defines the
point dipoles and their rotational state. The magnitude of the dipole
moment for each type of particle can be defined by the
<A HREF = "dipole.html">dipole</A> command or in the "Dipoles" section of the data
file read in by the <A HREF = "read_data.html">read_data</A> command. Their initial
orientation can be defined by the <A HREF = "set.html">set dipole</A> command or in
the "Atoms" section of the data file.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff1 (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distances for this pair style can be mixed. The default
mix value is <I>geometric</I>. See the "pair_modify" command for details.
</P>
<P>For atom type pairs I,J and I != J, the A, sigma, d1, and d2
coefficients and cutoff distance for this pair style can be mixed. A
is an energy value mixed like a LJ epsilon. D1 and d2 are distance
values and are mixed like sigma. The default mix value is
<I>geometric</I>. See the "pair_modify" command for details.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option for the energy of the Lennard-Jones portion of the pair
interaction; such energy goes to zero at the cutoff by construction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P><B>Restrictions:</B>
</P>
<P>The <I>dipole/cut</I> style is part of the DIPOLE package. It is only
enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The <I>dipole/sf</I> style is part of the USER-MISC package. It is only
enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Allen"></A>
<P><B>(Allen)</B> Allen and Tildesley, Computer Simulation of Liquids,
Clarendon Press, Oxford, 1987.
</P>
<A NAME = "Toukmaji"></A>
<P><B>(Toukmaji)</B> Toukmaji, Sagui, Board, and Darden, J Chem Phys, 113,
10913 (2000).
</P>
<A NAME = "Stoddard"></A>
<P><B>(Stoddard)</B> Stoddard and Ford, Phys Rev A, 8, 1504 (1973).
</P>
<A NAME = "Price"></A>
<P><B>(Price)</B> Price, Stone and Alderton, Mol Phys, 52, 987 (1984).
</P>
</HTML>
diff --git a/doc/pair_dipole.txt b/doc/pair_dipole.txt
index d71ffef2e..f41ceb434 100755
--- a/doc/pair_dipole.txt
+++ b/doc/pair_dipole.txt
@@ -1,202 +1,202 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style dipole/cut command :h3
pair_style dipole/cut/omp command :h3
pair_style dipole/sf command :h3
pair_style dipole/sf/omp command :h3
[Syntax:]
pair_style dipole/cut cutoff (cutoff2) :pre
pair_style dipole/sf cutoff (cutoff2) :pre
cutoff = global cutoff LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units) :ul
[Examples:]
pair_style dipole/cut 10.0
pair_coeff * * 1.0 1.0
pair_coeff 2 3 1.0 1.0 2.5 4.0 :pre
pair_style dipole/sf 9.0
pair_coeff * * 1.0 1.0
pair_coeff 2 3 1.0 1.0 2.5 4.0 :pre
[Description:]
Style {dipole/cut} computes interactions between pairs of particles
that each have a charge and/or a point dipole moment. In addition to
the usual Lennard-Jones interaction between the particles (Elj) the
charge-charge (Eqq), charge-dipole (Eqp), and dipole-dipole (Epp)
interactions are computed by these formulas for the energy (E), force
(F), and torque (T) between particles I and J.
:c,image(Eqs/pair_dipole.jpg)
where qi and qj are the charges on the two particles, pi and pj are
the dipole moment vectors of the two particles, r is their separation
distance, and the vector r = Ri - Rj is the separation vector between
the two particles. Note that Eqq and Fqq are simply Coulombic energy
and force, Fij = -Fji as symmetric forces, and Tij != -Tji since the
torques do not act symmetrically. These formulas are discussed in
"(Allen)"_#Allen and in "(Toukmaji)"_#Toukmaji.
Style {dipole/sf} computes "shifted-force" interactions between pairs
of particles that each have a charge and/or a point dipole moment. In
general, a shifted-force potential is a (sligthly) modified potential
containing extra terms that make both the energy and its derivative go
to zero at the cutoff distance; this removes (cutoff-related) problems
in energy conservation and any numerical instability in the equations
of motion "(Allen)"_#Allen. Shifted-force interactions for the
Lennard-Jones (E_LJ), charge-charge (Eqq), charge-dipole (Eqp),
dipole-charge (Epq) and dipole-dipole (Epp) potentials are computed by
these formulas for the energy (E), force (F), and torque (T) between
particles I and J:
:c,image(Eqs/pair_dipole_sf.jpg)
:c,image(Eqs/pair_dipole_sf2.jpg)
where epsilon and sigma are the standard LJ parameters, r_c is the
cutoff, qi and qj are the charges on the two particles, pi and pj are
the dipole moment vectors of the two particles, r is their separation
distance, and the vector r = Ri - Rj is the separation vector between
the two particles. Note that Eqq and Fqq are simply Coulombic energy
and force, Fij = -Fji as symmetric forces, and Tij != -Tji since the
torques do not act symmetrically. The shifted-force formula for the
Lennard-Jones potential is reported in "(Stoddard)"_#Stoddard. The
original (unshifted) formulas for the electrostatic potentials, forces
and torques can be found in "(Price)"_#Price. The shifted-force
electrostatic potentials have been obtained by applying equation 5.13
of "(Allen)"_#Allen. The formulas for the corresponding forces and
torques have been obtained by applying the 'chain rule' as in appendix
C.3 of "(Allen)"_#Allen.
If one cutoff is specified in the pair_style command, it is used for
both the LJ and Coulombic (q,p) terms. If two cutoffs are specified,
they are used as cutoffs for the LJ and Coulombic (q,p) terms
respectively.
Atoms with dipole moments should be integrated using the "fix
nve/sphere update dipole"_fix_nve_sphere.html command to rotate the
dipole moments. The "compute temp/sphere"_compute_temp_sphere.html
command can be used to monitor the temperature, since it includes
rotational degrees of freedom. The "atom_style
dipole"_atom_style.html command should be used since it defines the
point dipoles and their rotational state. The magnitude of the dipole
moment for each type of particle can be defined by the
"dipole"_dipole.html command or in the "Dipoles" section of the data
file read in by the "read_data"_read_data.html command. Their initial
orientation can be defined by the "set dipole"_set.html command or in
the "Atoms" section of the data file.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff1 (distance units)
cutoff2 (distance units) :ul
The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distances for this pair style can be mixed. The default
mix value is {geometric}. See the "pair_modify" command for details.
For atom type pairs I,J and I != J, the A, sigma, d1, and d2
coefficients and cutoff distance for this pair style can be mixed. A
is an energy value mixed like a LJ epsilon. D1 and d2 are distance
values and are mixed like sigma. The default mix value is
{geometric}. See the "pair_modify" command for details.
This pair style does not support the "pair_modify"_pair_modify.html
shift option for the energy of the Lennard-Jones portion of the pair
interaction; such energy goes to zero at the cutoff by construction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
[Restrictions:]
The {dipole/cut} style is part of the DIPOLE package. It is only
enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The {dipole/sf} style is part of the USER-MISC package. It is only
enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Allen)
[(Allen)] Allen and Tildesley, Computer Simulation of Liquids,
Clarendon Press, Oxford, 1987.
:link(Toukmaji)
[(Toukmaji)] Toukmaji, Sagui, Board, and Darden, J Chem Phys, 113,
10913 (2000).
:link(Stoddard)
[(Stoddard)] Stoddard and Ford, Phys Rev A, 8, 1504 (1973).
:link(Price)
[(Price)] Price, Stone and Alderton, Mol Phys, 52, 987 (1984).
diff --git a/doc/pair_dpd.html b/doc/pair_dpd.html
index 40d1dae1f..b6c46cce0 100644
--- a/doc/pair_dpd.html
+++ b/doc/pair_dpd.html
@@ -1,188 +1,188 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style dpd command
</H3>
<H3>pair_style dpd/omp command
</H3>
<H3>pair_style dpd/tstat command
</H3>
<H3>pair_style dpd/tstat/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style dpd T cutoff seed
pair_style dpd/tstat Tstart Tstop cutoff seed
</PRE>
<UL><LI>T = temperature (temperature units)
<LI>Tstart,Tstop = desired temperature at start/end of run (temperature units)
<LI>cutoff = global cutoff for DPD interactions (distance units)
<LI>seed = random # seed (positive integer)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style dpd 1.0 2.5 34387
pair_coeff * * 3.0 1.0
pair_coeff 1 1 3.0 1.0 1.0
</PRE>
<PRE>pair_style dpd/tstat 1.0 1.0 2.5 34387
pair_coeff * * 1.0
pair_coeff 1 1 1.0 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>dpd</I> computes a force field for dissipative particle dynamics
(DPD) following the exposition in <A HREF = "#Groot">(Groot)</A>.
</P>
<P>Style <I>dpd/tstat</I> invokes a DPD thermostat on pairwise interactions,
which is equivalent to the non-conservative portion of the DPD force
field. This thermostat can be used in conjunction with any <A HREF = "pair_style.html">pair
style</A>, and in leiu of per-particle thermostats like
<A HREF = "fix_langevin.html">fix langevin</A> or ensemble thermostats like Nose
Hoover as implemented by <A HREF = "fix_nh.html">fix nvt</A>. To use <I>dpd/stat</I>
with another pair style, use the <A HREF = "pair_hybrid.html">pair_style
hybrid/overlay</A> command to compute both the desired
pair interaction and the thermostat for each pair of particles.
</P>
<P>For style <I>dpd</I>, the force on atom I due to atom J is given as a sum
of 3 terms
</P>
<CENTER><IMG SRC = "Eqs/pair_dpd.jpg">
</CENTER>
<P>where Fc is a conservative force, Fd is a dissipative force, and Fr is
a random force. Rij is a unit vector in the direction Ri - Rj, Vij is
the vector difference in velocities of the two atoms = Vi - Vj, alpha
is a Gaussian random number with zero mean and unit variance, dt is
the timestep size, and w(r) is a weighting factor that varies between
0 and 1. Rc is the cutoff. Sigma is set equal to sqrt(2 Kb T gamma),
where Kb is the Boltzmann constant and T is the temperature parameter
in the pair_style command.
</P>
<P>For style <I>dpd/tstat</I>, the force on atom I due to atom J is the same
as the above equation, except that the conservative Fc term is
dropped. Also, during the run, T is set each timestep to a ramped
value from Tstart to Tstop.
</P>
<P>For style <I>dpd</I>, the pairwise energy associated with style <I>dpd</I> is
only due to the conservative force term Fc, and is shifted to be zero
at the cutoff distance Rc. The pairwise virial is calculated using
all 3 terms. For style <I>dpd/tstat</I> there is no pairwise energy, but
the last two terms of the formula make a contribution to the virial.
</P>
<P>For style <I>dpd</I>, the following coefficients must be defined for each
pair of atoms types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in
the examples above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>A (force units)
<LI>gamma (force/velocity units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global DPD
cutoff is used. Note that sigma is set equal to sqrt(2 T gamma),
where T is the temperature set by the <A HREF = "pair_style.html">pair_style</A>
command so it does not need to be specified.
</P>
<P>For style <I>dpd/tstat</I>, the coefficiencts defined for each pair of
atoms types via the <A HREF = "pair_coeff.html">pair_coeff</A> command is the same,
except that A is not included.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option for the energy of the pair interaction. Note that as
discussed above, the energy due to the conservative Fc term is already
shifted to be 0.0 at the cutoff distance Rc.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for these pair styles.
</P>
<P>These pair style do not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>These pair styles writes their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file. Note
that the user-specified random number seed is stored in the restart
file, so when a simulation is restarted, each processor will
re-initialize its random number generator the same way it did
initially. This means the random forces will be random, but will not
be the same as they would have been if the original simulation had
continued past the restart time.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P>The <I>dpd/tstat</I> style can ramp its target temperature over multiple
runs, using the <I>start</I> and <I>stop</I> keywords of the <A HREF = "run.html">run</A>
command. See the <A HREF = "run.html">run</A> command for details of how to do
this.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The default frequency for rebuilding neighbor lists is every 10 steps
(see the <A HREF = "neigh_modify.html">neigh_modify</A> command). This may be too
infrequent for style <I>dpd</I> simulations since particles move rapidly
and can overlap by large amounts. If this setting yields a non-zero
number of "dangerous" reneighborings (printed at the end of a
simulation), you should experiment with forcing reneighboring more
often and see if system energies/trajectories change.
</P>
<P>These pair styles requires you to use the <A HREF = "communicate.html">communicate vel
yes</A> option so that velocites are stored by ghost
atoms.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "fix_nh.html">fix nvt</A>, <A HREF = "fix_langevin.html">fix
langevin</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Groot"></A>
<P><B>(Groot)</B> Groot and Warren, J Chem Phys, 107, 4423-35 (1997).
</P>
</HTML>
diff --git a/doc/pair_dpd.txt b/doc/pair_dpd.txt
index 2b60a5937..0638e753e 100644
--- a/doc/pair_dpd.txt
+++ b/doc/pair_dpd.txt
@@ -1,179 +1,179 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style dpd command :h3
pair_style dpd/omp command :h3
pair_style dpd/tstat command :h3
pair_style dpd/tstat/omp command :h3
[Syntax:]
pair_style dpd T cutoff seed
pair_style dpd/tstat Tstart Tstop cutoff seed :pre
T = temperature (temperature units)
Tstart,Tstop = desired temperature at start/end of run (temperature units)
cutoff = global cutoff for DPD interactions (distance units)
seed = random # seed (positive integer) :ul
[Examples:]
pair_style dpd 1.0 2.5 34387
pair_coeff * * 3.0 1.0
pair_coeff 1 1 3.0 1.0 1.0 :pre
pair_style dpd/tstat 1.0 1.0 2.5 34387
pair_coeff * * 1.0
pair_coeff 1 1 1.0 1.0 :pre
[Description:]
Style {dpd} computes a force field for dissipative particle dynamics
(DPD) following the exposition in "(Groot)"_#Groot.
Style {dpd/tstat} invokes a DPD thermostat on pairwise interactions,
which is equivalent to the non-conservative portion of the DPD force
field. This thermostat can be used in conjunction with any "pair
style"_pair_style.html, and in leiu of per-particle thermostats like
"fix langevin"_fix_langevin.html or ensemble thermostats like Nose
Hoover as implemented by "fix nvt"_fix_nh.html. To use {dpd/stat}
with another pair style, use the "pair_style
hybrid/overlay"_pair_hybrid.html command to compute both the desired
pair interaction and the thermostat for each pair of particles.
For style {dpd}, the force on atom I due to atom J is given as a sum
of 3 terms
:c,image(Eqs/pair_dpd.jpg)
where Fc is a conservative force, Fd is a dissipative force, and Fr is
a random force. Rij is a unit vector in the direction Ri - Rj, Vij is
the vector difference in velocities of the two atoms = Vi - Vj, alpha
is a Gaussian random number with zero mean and unit variance, dt is
the timestep size, and w(r) is a weighting factor that varies between
0 and 1. Rc is the cutoff. Sigma is set equal to sqrt(2 Kb T gamma),
where Kb is the Boltzmann constant and T is the temperature parameter
in the pair_style command.
For style {dpd/tstat}, the force on atom I due to atom J is the same
as the above equation, except that the conservative Fc term is
dropped. Also, during the run, T is set each timestep to a ramped
value from Tstart to Tstop.
For style {dpd}, the pairwise energy associated with style {dpd} is
only due to the conservative force term Fc, and is shifted to be zero
at the cutoff distance Rc. The pairwise virial is calculated using
all 3 terms. For style {dpd/tstat} there is no pairwise energy, but
the last two terms of the formula make a contribution to the virial.
For style {dpd}, the following coefficients must be defined for each
pair of atoms types via the "pair_coeff"_pair_coeff.html command as in
the examples above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
A (force units)
gamma (force/velocity units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global DPD
cutoff is used. Note that sigma is set equal to sqrt(2 T gamma),
where T is the temperature set by the "pair_style"_pair_style.html
command so it does not need to be specified.
For style {dpd/tstat}, the coefficiencts defined for each pair of
atoms types via the "pair_coeff"_pair_coeff.html command is the same,
except that A is not included.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
These pair styles do not support the "pair_modify"_pair_modify.html
shift option for the energy of the pair interaction. Note that as
discussed above, the energy due to the conservative Fc term is already
shifted to be 0.0 at the cutoff distance Rc.
The "pair_modify"_pair_modify.html table option is not relevant
for these pair styles.
These pair style do not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
These pair styles writes their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file. Note
that the user-specified random number seed is stored in the restart
file, so when a simulation is restarted, each processor will
re-initialize its random number generator the same way it did
initially. This means the random forces will be random, but will not
be the same as they would have been if the original simulation had
continued past the restart time.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
The {dpd/tstat} style can ramp its target temperature over multiple
runs, using the {start} and {stop} keywords of the "run"_run.html
command. See the "run"_run.html command for details of how to do
this.
:line
[Restrictions:]
The default frequency for rebuilding neighbor lists is every 10 steps
(see the "neigh_modify"_neigh_modify.html command). This may be too
infrequent for style {dpd} simulations since particles move rapidly
and can overlap by large amounts. If this setting yields a non-zero
number of "dangerous" reneighborings (printed at the end of a
simulation), you should experiment with forcing reneighboring more
often and see if system energies/trajectories change.
These pair styles requires you to use the "communicate vel
yes"_communicate.html option so that velocites are stored by ghost
atoms.
[Related commands:]
"pair_coeff"_pair_coeff.html, "fix nvt"_fix_nh.html, "fix
langevin"_fix_langevin.html
[Default:] none
:line
:link(Groot)
[(Groot)] Groot and Warren, J Chem Phys, 107, 4423-35 (1997).
diff --git a/doc/pair_eam.html b/doc/pair_eam.html
index 4f695c52e..8237e2a52 100644
--- a/doc/pair_eam.html
+++ b/doc/pair_eam.html
@@ -1,462 +1,462 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style eam command
</H3>
<H3>pair_style eam/cuda command
</H3>
<H3>pair_style eam/omp command
</H3>
<H3>pair_style eam/opt command
</H3>
<H3>pair_style eam/alloy command
</H3>
<H3>pair_style eam/alloy/cuda command
</H3>
<H3>pair_style eam/alloy/omp command
</H3>
<H3>pair_style eam/alloy/opt command
</H3>
<H3>pair_style eam/cd command
</H3>
<H3>pair_style eam/cd/omp command
</H3>
<H3>pair_style eam/fs command
</H3>
<H3>pair_style eam/fs/cuda command
</H3>
<H3>pair_style eam/fs/omp command
</H3>
<H3>pair_style eam/fs/opt command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style
</PRE>
<UL><LI>style = <I>eam</I> or <I>eam/alloy</I> or <I>eam/cd</I> or <I>eam/fs</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style eam
pair_coeff * * cuu3
pair_coeff 1*3 1*3 niu3.eam
</PRE>
<PRE>pair_style eam/alloy
pair_coeff * * ../potentials/NiAlH_jea.eam.alloy Ni Al Ni Ni
</PRE>
<PRE>pair_style eam/cd
pair_coeff * * ../potentials/FeCr.cdeam Fe Cr
</PRE>
<PRE>pair_style eam/fs
pair_coeff * * NiAlH_jea.eam.fs Ni Al Ni Ni
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>eam</I> computes pairwise interactions for metals and metal alloys
using embedded-atom method (EAM) potentials <A HREF = "#Daw">(Daw)</A>. The total
energy Ei of an atom I is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_eam.jpg">
</CENTER>
<P>where F is the embedding energy which is a function of the atomic
electron density rho, phi is a pair potential interaction, and alpha
and beta are the element types of atoms I and J. The multi-body
nature of the EAM potential is a result of the embedding energy term.
Both summations in the formula are over all neighbors J of atom I
within the cutoff distance.
</P>
<P>The cutoff distance and the tabulated values of the functionals F,
rho, and phi are listed in one or more files which are specified by
the <A HREF = "pair_coeff.html">pair_coeff</A> command. These are ASCII text files
in a DYNAMO-style format which is described below. DYNAMO was the
original serial EAM MD code, written by the EAM originators. Several
DYNAMO potential files for different metals are included in the
"potentials" directory of the LAMMPS distribution. All of these files
are parameterized in terms of LAMMPS <A HREF = "units.html">metal units</A>.
</P>
<P>IMPORTANT NOTE: The <I>eam</I> style reads single-element EAM potentials in
the DYNAMO <I>funcfl</I> format. Either single element or alloy systems
can be modeled using multiple <I>funcfl</I> files and style <I>eam</I>. For the
alloy case LAMMPS mixes the single-element potentials to produce alloy
potentials, the same way that DYNAMO does. Alternatively, a single
DYNAMO <I>setfl</I> file or Finnis/Sinclair EAM file can be used by LAMMPS
to model alloy systems by invoking the <I>eam/alloy</I> or <I>eam/cd</I> or
<I>eam/fs</I> styles as described below. These files require no mixing
since they specify alloy interactions explicitly.
</P>
<P>Note that unlike for other potentials, cutoffs for EAM potentials are
not set in the pair_style or pair_coeff command; they are specified in
the EAM potential files themselves. Likewise, the EAM potential files
list atomic masses; thus you do not need to use the <A HREF = "mass.html">mass</A>
command to specify them.
</P>
<P>There are several WWW sites that distribute and document EAM
potentials stored in DYNAMO or other formats:
</P>
<PRE>http://www.ctcms.nist.gov/potentials
http://cst-www.nrl.navy.mil/ccm6/ap
http://enpub.fulton.asu.edu/cms/potentials/main/main.htm
</PRE>
<P>These potentials should be usable with LAMMPS, though the alternate
formats would need to be converted to the DYNAMO format used by LAMMPS
and described on this page. The NIST site is maintained by Chandler
Becker (cbecker at nist.gov) who is good resource for info on
interatomic potentials and file formats.
</P>
<HR>
<P>For style <I>eam</I>, potential values are read from a file that is in the
DYNAMO single-element <I>funcfl</I> format. If the DYNAMO file was created
by a Fortran program, it cannot have "D" values in it for exponents.
C only recognizes "e" or "E" for scientific notation.
</P>
<P>Note that unlike for other potentials, cutoffs for EAM potentials are
not set in the pair_style or pair_coeff command; they are specified in
the EAM potential files themselves.
</P>
<P>For style <I>eam</I> a potential file must be assigned to each I,I pair of
atom types by using one or more pair_coeff commands, each with a
single argument:
</P>
<UL><LI>filename
</UL>
<P>Thus the following command
</P>
<PRE>pair_coeff *2 1*2 cuu3.eam
</PRE>
<P>will read the cuu3 potential file and use the tabulated Cu values for
F, phi, rho that it contains for type pairs 1,1 and 2,2 (type pairs
1,2 and 2,1 are ignored). In effect, this makes atom types 1 and 2 in
LAMMPS be Cu atoms. Different single-element files can be assigned to
different atom types to model an alloy system. The mixing to create
alloy potentials for type pairs with I != J is done automatically the
same way that the serial DYNAMO code originally did it; you do not
need to specify coefficients for these type pairs.
</P>
<P><I>Funcfl</I> files in the <I>potentials</I> directory of the LAMMPS
distribution have an ".eam" suffix. A DYNAMO single-element <I>funcfl</I>
file is formatted as follows:
</P>
<UL><LI>line 1: comment (ignored)
<LI>line 2: atomic number, mass, lattice constant, lattice type (e.g. FCC)
<LI>line 3: Nrho, drho, Nr, dr, cutoff
</UL>
<P>On line 2, all values but the mass are ignored by LAMMPS. The mass is
in mass <A HREF = "units.html">units</A>, e.g. mass number or grams/mole for metal
units. The cubic lattice constant is in Angstroms. On line 3, Nrho
and Nr are the number of tabulated values in the subsequent arrays,
drho and dr are the spacing in density and distance space for the
values in those arrays, and the specified cutoff becomes the pairwise
cutoff used by LAMMPS for the potential. The units of dr are
Angstroms; I'm not sure of the units for drho - some measure of
electron density.
</P>
<P>Following the three header lines are three arrays of tabulated values:
</P>
<UL><LI>embedding function F(rho) (Nrho values)
<LI>effective charge function Z(r) (Nr values)
<LI>density function rho(r) (Nr values)
</UL>
<P>The values for each array can be listed as multiple values per line,
so long as each array starts on a new line. For example, the
individual Z(r) values are for r = 0,dr,2*dr, ... (Nr-1)*dr.
</P>
<P>The units for the embedding function F are eV. The units for the
density function rho are the same as for drho (see above, electron
density). The units for the effective charge Z are "atomic charge" or
sqrt(Hartree * Bohr-radii). For two interacting atoms i,j this is used
by LAMMPS to compute the pair potential term in the EAM energy
expression as r*phi, in units of eV-Angstroms, via the formula
</P>
<PRE>r*phi = 27.2 * 0.529 * Zi * Zj
</PRE>
<P>where 1 Hartree = 27.2 eV and 1 Bohr = 0.529 Angstroms.
</P>
<HR>
<P>Style <I>eam/alloy</I> computes pairwise interactions using the same
formula as style <I>eam</I>. However the associated
<A HREF = "pair_coeff.html">pair_coeff</A> command reads a DYNAMO <I>setfl</I> file
instead of a <I>funcfl</I> file. <I>Setfl</I> files can be used to model a
single-element or alloy system. In the alloy case, as explained
above, <I>setfl</I> files contain explicit tabulated values for alloy
interactions. Thus they allow more generality than <I>funcfl</I> files for
modeling alloys.
</P>
<P>For style <I>eam/alloy</I>, potential values are read from a file that is
in the DYNAMO multi-element <I>setfl</I> format, except that element names
(Ni, Cu, etc) are added to one of the lines in the file. If the
DYNAMO file was created by a Fortran program, it cannot have "D"
values in it for exponents. C only recognizes "e" or "E" for
scientific notation.
</P>
<P>Only a single pair_coeff command is used with the <I>eam/alloy</I> style
which specifies a DYNAMO <I>setfl</I> file, which contains information for
M elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of <I>setfl</I> elements to atom types
</UL>
<P>As an example, the potentials/NiAlH_jea.eam.alloy file is a <I>setfl</I>
file which has tabulated EAM values for 3 elements and their alloy
interactions: Ni, Al, and H. If your LAMMPS simulation has 4 atoms
types and you want the 1st 3 to be Ni, and the 4th to be Al, you would
use the following pair_coeff command:
</P>
<PRE>pair_coeff * * NiAlH_jea.eam.alloy Ni Ni Ni Al
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Ni arguments map LAMMPS atom types 1,2,3 to the Ni
element in the <I>setfl</I> file. The final Al argument maps LAMMPS atom
type 4 to the Al element in the <I>setfl</I> file. Note that there is no
requirement that your simulation use all the elements specified by the
<I>setfl</I> file.
</P>
<P>If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an <I>eam/alloy</I> potential is used as part of the
<I>hybrid</I> pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
</P>
<P><I>Setfl</I> files in the <I>potentials</I> directory of the LAMMPS distribution
have an ".eam.alloy" suffix. A DYNAMO multi-element <I>setfl</I> file is
formatted as follows:
</P>
<UL><LI>lines 1,2,3 = comments (ignored)
<LI>line 4: Nelements Element1 Element2 ... ElementN
<LI>line 5: Nrho, drho, Nr, dr, cutoff
</UL>
<P>In a DYNAMO <I>setfl</I> file, line 4 only lists Nelements = the # of
elements in the <I>setfl</I> file. For LAMMPS, the element name (Ni, Cu,
etc) of each element must be added to the line, in the order the
elements appear in the file.
</P>
<P>The meaning and units of the values in line 5 is the same as for the
<I>funcfl</I> file described above. Note that the cutoff (in Angstroms) is
a global value, valid for all pairwise interactions for all element
pairings.
</P>
<P>Following the 5 header lines are Nelements sections, one for each
element, each with the following format:
</P>
<UL><LI>line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
<LI>embedding function F(rho) (Nrho values)
<LI>density function rho(r) (Nr values)
</UL>
<P>As with the <I>funcfl</I> files, only the mass (in mass <A HREF = "units.html">units</A>,
e.g. mass number or grams/mole for metal units) is used by LAMMPS from
the 1st line. The cubic lattice constant is in Angstroms. The F and
rho arrays are unique to a single element and have the same format and
units as in a <I>funcfl</I> file.
</P>
<P>Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed for all i,j element pairs in the same format
as other arrays. Since these interactions are symmetric (i,j = j,i)
only phi arrays with i >= j are listed, in the following order: i,j =
(1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), ..., (Nelements,
Nelements). Unlike the effective charge array Z(r) in <I>funcfl</I> files,
the tabulated values for each phi function are listed in <I>setfl</I> files
directly as r*phi (in units of eV-Angstroms), since they are for atom
pairs.
</P>
<HR>
<P>Style <I>eam/cd</I> is similar to the <I>eam/alloy</I> style, except that it
computes alloy pairwise interactions using the concentration-dependent
embedded-atom method (CD-EAM). This model can reproduce the enthalpy
of mixing of alloys over the full composition range, as described in
<A HREF = "#Stukowski">(Stukowski)</A>.
</P>
<P>The pair_coeff command is specified the same as for the <I>eam/alloy</I>
style. However the DYNAMO <I>setfl</I> file must has two
lines added to it, at the end of the file:
</P>
<UL><LI>line 1: Comment line (ignored)
<LI>line 2: N Coefficient0 Coefficient1 ... CoeffincientN
</UL>
<P>The last line begins with the degree <I>N</I> of the polynomial function
<I>h(x)</I> that modifies the cross interaction between A and B elements.
Then <I>N+1</I> coefficients for the terms of the polynomial are then
listed.
</P>
<P>Modified EAM <I>setfl</I> files used with the <I>eam/cd</I> style must contain
exactly two elements, i.e. in the current implementation the <I>eam/cd</I>
style only supports binary alloys. The first and second elements in
the input EAM file are always taken as the <I>A</I> and <I>B</I> species.
</P>
<P><I>CD-EAM</I> files in the <I>potentials</I> directory of the LAMMPS
distribution have a ".cdeam" suffix.
</P>
<HR>
<P>Style <I>eam/fs</I> computes pairwise interactions for metals and metal
alloys using a generalized form of EAM potentials due to Finnis and
Sinclair <A HREF = "#Finnis">(Finnis)</A>. The total energy Ei of an atom I is
given by
</P>
<CENTER><IMG SRC = "Eqs/pair_eam_fs.jpg">
</CENTER>
<P>This has the same form as the EAM formula above, except that rho is
now a functional specific to the atomic types of both atoms I and J,
so that different elements can contribute differently to the total
electron density at an atomic site depending on the identity of the
element at that atomic site.
</P>
<P>The associated <A HREF = "pair_coeff.html">pair_coeff</A> command for style <I>eam/fs</I>
reads a DYNAMO <I>setfl</I> file that has been extended to include
additional rho_alpha_beta arrays of tabulated values. A discussion of
how FS EAM differs from conventional EAM alloy potentials is given in
<A HREF = "#Ackland1">(Ackland1)</A>. An example of such a potential is the same
author's Fe-P FS potential <A HREF = "#Ackland2">(Ackland2)</A>. Note that while FS
potentials always specify the embedding energy with a square root
dependence on the total density, the implementation in LAMMPS does not
require that; the user can tabulate any functional form desired in the
FS potential files.
</P>
<P>For style <I>eam/fs</I>, the form of the pair_coeff command is exactly the
same as for style <I>eam/alloy</I>, e.g.
</P>
<PRE>pair_coeff * * NiAlH_jea.eam.fs Ni Ni Ni Al
</PRE>
<P>where there are N additional arguments after the filename, where N is
the number of LAMMPS atom types. The N values determine the mapping
of LAMMPS atom types to EAM elements in the file, as described above
for style <I>eam/alloy</I>. As with <I>eam/alloy</I>, if a mapping value is
NULL, the mapping is not performed. This can be used when an <I>eam/fs</I>
potential is used as part of the <I>hybrid</I> pair style. The NULL values
are used as placeholders for atom types that will be used with other
potentials.
</P>
<P>FS EAM files include more information than the DYNAMO <I>setfl</I> format
files read by <I>eam/alloy</I>, in that i,j density functionals for all
pairs of elements are included as needed by the Finnis/Sinclair
formulation of the EAM.
</P>
<P>FS EAM files in the <I>potentials</I> directory of the LAMMPS distribution
have an ".eam.fs" suffix. They are formatted as follows:
</P>
<UL><LI>lines 1,2,3 = comments (ignored)
<LI>line 4: Nelements Element1 Element2 ... ElementN
<LI>line 5: Nrho, drho, Nr, dr, cutoff
</UL>
<P>The 5-line header section is identical to an EAM <I>setfl</I> file.
</P>
<P>Following the header are Nelements sections, one for each element I,
each with the following format:
</P>
<UL><LI>line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
<LI>embedding function F(rho) (Nrho values)
<LI>density function rho(r) for element I at element 1 (Nr values)
<LI>density function rho(r) for element I at element 2
<LI>...
<LI>density function rho(r) for element I at element Nelement
</UL>
<P>The units of these quantities in line 1 are the same as for <I>setfl</I>
files. Note that the rho(r) arrays in Finnis/Sinclair can be
asymmetric (i,j != j,i) so there are Nelements^2 of them listed in the
file.
</P>
<P>Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed in the same manner (r*phi, units of
eV-Angstroms) as in EAM <I>setfl</I> files. Note that in Finnis/Sinclair,
the phi(r) arrays are still symmetric, so only phi arrays for i >= j
are listed.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
+<P>See <A HREF = "Section_accelerate.html">Section_accerlate</A> of the manual for more
instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above with the individual styles. You never need to specify
a pair_coeff command with I != J arguments for the eam styles.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>The eam pair styles do not write their information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in tabulated potential files.
Thus, you need to re-specify the pair_style and pair_coeff commands in
an input script that reads a restart file.
</P>
<P>The eam pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>All of these styles except the <I>eam/cd</I> style are part of the MANYBODY
package. They are only enabled if LAMMPS was built with that package
(which it is by default). See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>The <I>eam/cd</I> style is part of the USER-MISC package and also requires
the MANYBODY package. It is only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Ackland1"></A>
<P><B>(Ackland1)</B> Ackland, Condensed Matter (2005).
</P>
<A NAME = "Ackland2"></A>
<P><B>(Ackland2)</B> Ackland, Mendelev, Srolovitz, Han and Barashev, Journal
of Physics: Condensed Matter, 16, S2629 (2004).
</P>
<A NAME = "Daw"></A>
<P><B>(Daw)</B> Daw, Baskes, Phys Rev Lett, 50, 1285 (1983).
Daw, Baskes, Phys Rev B, 29, 6443 (1984).
</P>
<A NAME = "Finnis"></A>
<P><B>(Finnis)</B> Finnis, Sinclair, Philosophical Magazine A, 50, 45 (1984).
</P>
<A NAME = "Stukowski"></A>
<P><B>(Stukowski)</B> Stukowski, Sadigh, Erhart, Caro; Modeling Simulation
Materials Science & Engineering, 7, 075005 (2009).
</P>
</HTML>
diff --git a/doc/pair_eam.txt b/doc/pair_eam.txt
index d0b06bf07..90883c971 100644
--- a/doc/pair_eam.txt
+++ b/doc/pair_eam.txt
@@ -1,440 +1,440 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style eam command :h3
pair_style eam/cuda command :h3
pair_style eam/omp command :h3
pair_style eam/opt command :h3
pair_style eam/alloy command :h3
pair_style eam/alloy/cuda command :h3
pair_style eam/alloy/omp command :h3
pair_style eam/alloy/opt command :h3
pair_style eam/cd command :h3
pair_style eam/cd/omp command :h3
pair_style eam/fs command :h3
pair_style eam/fs/cuda command :h3
pair_style eam/fs/omp command :h3
pair_style eam/fs/opt command :h3
[Syntax:]
pair_style style :pre
style = {eam} or {eam/alloy} or {eam/cd} or {eam/fs} :ul
[Examples:]
pair_style eam
pair_coeff * * cuu3
pair_coeff 1*3 1*3 niu3.eam :pre
pair_style eam/alloy
pair_coeff * * ../potentials/NiAlH_jea.eam.alloy Ni Al Ni Ni :pre
pair_style eam/cd
pair_coeff * * ../potentials/FeCr.cdeam Fe Cr :pre
pair_style eam/fs
pair_coeff * * NiAlH_jea.eam.fs Ni Al Ni Ni :pre
[Description:]
Style {eam} computes pairwise interactions for metals and metal alloys
using embedded-atom method (EAM) potentials "(Daw)"_#Daw. The total
energy Ei of an atom I is given by
:c,image(Eqs/pair_eam.jpg)
where F is the embedding energy which is a function of the atomic
electron density rho, phi is a pair potential interaction, and alpha
and beta are the element types of atoms I and J. The multi-body
nature of the EAM potential is a result of the embedding energy term.
Both summations in the formula are over all neighbors J of atom I
within the cutoff distance.
The cutoff distance and the tabulated values of the functionals F,
rho, and phi are listed in one or more files which are specified by
the "pair_coeff"_pair_coeff.html command. These are ASCII text files
in a DYNAMO-style format which is described below. DYNAMO was the
original serial EAM MD code, written by the EAM originators. Several
DYNAMO potential files for different metals are included in the
"potentials" directory of the LAMMPS distribution. All of these files
are parameterized in terms of LAMMPS "metal units"_units.html.
IMPORTANT NOTE: The {eam} style reads single-element EAM potentials in
the DYNAMO {funcfl} format. Either single element or alloy systems
can be modeled using multiple {funcfl} files and style {eam}. For the
alloy case LAMMPS mixes the single-element potentials to produce alloy
potentials, the same way that DYNAMO does. Alternatively, a single
DYNAMO {setfl} file or Finnis/Sinclair EAM file can be used by LAMMPS
to model alloy systems by invoking the {eam/alloy} or {eam/cd} or
{eam/fs} styles as described below. These files require no mixing
since they specify alloy interactions explicitly.
Note that unlike for other potentials, cutoffs for EAM potentials are
not set in the pair_style or pair_coeff command; they are specified in
the EAM potential files themselves. Likewise, the EAM potential files
list atomic masses; thus you do not need to use the "mass"_mass.html
command to specify them.
There are several WWW sites that distribute and document EAM
potentials stored in DYNAMO or other formats:
http://www.ctcms.nist.gov/potentials
http://cst-www.nrl.navy.mil/ccm6/ap
http://enpub.fulton.asu.edu/cms/potentials/main/main.htm :pre
These potentials should be usable with LAMMPS, though the alternate
formats would need to be converted to the DYNAMO format used by LAMMPS
and described on this page. The NIST site is maintained by Chandler
Becker (cbecker at nist.gov) who is good resource for info on
interatomic potentials and file formats.
:line
For style {eam}, potential values are read from a file that is in the
DYNAMO single-element {funcfl} format. If the DYNAMO file was created
by a Fortran program, it cannot have "D" values in it for exponents.
C only recognizes "e" or "E" for scientific notation.
Note that unlike for other potentials, cutoffs for EAM potentials are
not set in the pair_style or pair_coeff command; they are specified in
the EAM potential files themselves.
For style {eam} a potential file must be assigned to each I,I pair of
atom types by using one or more pair_coeff commands, each with a
single argument:
filename :ul
Thus the following command
pair_coeff *2 1*2 cuu3.eam :pre
will read the cuu3 potential file and use the tabulated Cu values for
F, phi, rho that it contains for type pairs 1,1 and 2,2 (type pairs
1,2 and 2,1 are ignored). In effect, this makes atom types 1 and 2 in
LAMMPS be Cu atoms. Different single-element files can be assigned to
different atom types to model an alloy system. The mixing to create
alloy potentials for type pairs with I != J is done automatically the
same way that the serial DYNAMO code originally did it; you do not
need to specify coefficients for these type pairs.
{Funcfl} files in the {potentials} directory of the LAMMPS
distribution have an ".eam" suffix. A DYNAMO single-element {funcfl}
file is formatted as follows:
line 1: comment (ignored)
line 2: atomic number, mass, lattice constant, lattice type (e.g. FCC)
line 3: Nrho, drho, Nr, dr, cutoff :ul
On line 2, all values but the mass are ignored by LAMMPS. The mass is
in mass "units"_units.html, e.g. mass number or grams/mole for metal
units. The cubic lattice constant is in Angstroms. On line 3, Nrho
and Nr are the number of tabulated values in the subsequent arrays,
drho and dr are the spacing in density and distance space for the
values in those arrays, and the specified cutoff becomes the pairwise
cutoff used by LAMMPS for the potential. The units of dr are
Angstroms; I'm not sure of the units for drho - some measure of
electron density.
Following the three header lines are three arrays of tabulated values:
embedding function F(rho) (Nrho values)
effective charge function Z(r) (Nr values)
density function rho(r) (Nr values) :ul
The values for each array can be listed as multiple values per line,
so long as each array starts on a new line. For example, the
individual Z(r) values are for r = 0,dr,2*dr, ... (Nr-1)*dr.
The units for the embedding function F are eV. The units for the
density function rho are the same as for drho (see above, electron
density). The units for the effective charge Z are "atomic charge" or
sqrt(Hartree * Bohr-radii). For two interacting atoms i,j this is used
by LAMMPS to compute the pair potential term in the EAM energy
expression as r*phi, in units of eV-Angstroms, via the formula
r*phi = 27.2 * 0.529 * Zi * Zj :pre
where 1 Hartree = 27.2 eV and 1 Bohr = 0.529 Angstroms.
:line
Style {eam/alloy} computes pairwise interactions using the same
formula as style {eam}. However the associated
"pair_coeff"_pair_coeff.html command reads a DYNAMO {setfl} file
instead of a {funcfl} file. {Setfl} files can be used to model a
single-element or alloy system. In the alloy case, as explained
above, {setfl} files contain explicit tabulated values for alloy
interactions. Thus they allow more generality than {funcfl} files for
modeling alloys.
For style {eam/alloy}, potential values are read from a file that is
in the DYNAMO multi-element {setfl} format, except that element names
(Ni, Cu, etc) are added to one of the lines in the file. If the
DYNAMO file was created by a Fortran program, it cannot have "D"
values in it for exponents. C only recognizes "e" or "E" for
scientific notation.
Only a single pair_coeff command is used with the {eam/alloy} style
which specifies a DYNAMO {setfl} file, which contains information for
M elements. These are mapped to LAMMPS atom types by specifying N
additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of {setfl} elements to atom types :ul
As an example, the potentials/NiAlH_jea.eam.alloy file is a {setfl}
file which has tabulated EAM values for 3 elements and their alloy
interactions: Ni, Al, and H. If your LAMMPS simulation has 4 atoms
types and you want the 1st 3 to be Ni, and the 4th to be Al, you would
use the following pair_coeff command:
pair_coeff * * NiAlH_jea.eam.alloy Ni Ni Ni Al :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Ni arguments map LAMMPS atom types 1,2,3 to the Ni
element in the {setfl} file. The final Al argument maps LAMMPS atom
type 4 to the Al element in the {setfl} file. Note that there is no
requirement that your simulation use all the elements specified by the
{setfl} file.
If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an {eam/alloy} potential is used as part of the
{hybrid} pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
{Setfl} files in the {potentials} directory of the LAMMPS distribution
have an ".eam.alloy" suffix. A DYNAMO multi-element {setfl} file is
formatted as follows:
lines 1,2,3 = comments (ignored)
line 4: Nelements Element1 Element2 ... ElementN
line 5: Nrho, drho, Nr, dr, cutoff :ul
In a DYNAMO {setfl} file, line 4 only lists Nelements = the # of
elements in the {setfl} file. For LAMMPS, the element name (Ni, Cu,
etc) of each element must be added to the line, in the order the
elements appear in the file.
The meaning and units of the values in line 5 is the same as for the
{funcfl} file described above. Note that the cutoff (in Angstroms) is
a global value, valid for all pairwise interactions for all element
pairings.
Following the 5 header lines are Nelements sections, one for each
element, each with the following format:
line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
embedding function F(rho) (Nrho values)
density function rho(r) (Nr values) :ul
As with the {funcfl} files, only the mass (in mass "units"_units.html,
e.g. mass number or grams/mole for metal units) is used by LAMMPS from
the 1st line. The cubic lattice constant is in Angstroms. The F and
rho arrays are unique to a single element and have the same format and
units as in a {funcfl} file.
Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed for all i,j element pairs in the same format
as other arrays. Since these interactions are symmetric (i,j = j,i)
only phi arrays with i >= j are listed, in the following order: i,j =
(1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), ..., (Nelements,
Nelements). Unlike the effective charge array Z(r) in {funcfl} files,
the tabulated values for each phi function are listed in {setfl} files
directly as r*phi (in units of eV-Angstroms), since they are for atom
pairs.
:line
Style {eam/cd} is similar to the {eam/alloy} style, except that it
computes alloy pairwise interactions using the concentration-dependent
embedded-atom method (CD-EAM). This model can reproduce the enthalpy
of mixing of alloys over the full composition range, as described in
"(Stukowski)"_#Stukowski.
The pair_coeff command is specified the same as for the {eam/alloy}
style. However the DYNAMO {setfl} file must has two
lines added to it, at the end of the file:
line 1: Comment line (ignored)
line 2: N Coefficient0 Coefficient1 ... CoeffincientN :ul
The last line begins with the degree {N} of the polynomial function
{h(x)} that modifies the cross interaction between A and B elements.
Then {N+1} coefficients for the terms of the polynomial are then
listed.
Modified EAM {setfl} files used with the {eam/cd} style must contain
exactly two elements, i.e. in the current implementation the {eam/cd}
style only supports binary alloys. The first and second elements in
the input EAM file are always taken as the {A} and {B} species.
{CD-EAM} files in the {potentials} directory of the LAMMPS
distribution have a ".cdeam" suffix.
:line
Style {eam/fs} computes pairwise interactions for metals and metal
alloys using a generalized form of EAM potentials due to Finnis and
Sinclair "(Finnis)"_#Finnis. The total energy Ei of an atom I is
given by
:c,image(Eqs/pair_eam_fs.jpg)
This has the same form as the EAM formula above, except that rho is
now a functional specific to the atomic types of both atoms I and J,
so that different elements can contribute differently to the total
electron density at an atomic site depending on the identity of the
element at that atomic site.
The associated "pair_coeff"_pair_coeff.html command for style {eam/fs}
reads a DYNAMO {setfl} file that has been extended to include
additional rho_alpha_beta arrays of tabulated values. A discussion of
how FS EAM differs from conventional EAM alloy potentials is given in
"(Ackland1)"_#Ackland1. An example of such a potential is the same
author's Fe-P FS potential "(Ackland2)"_#Ackland2. Note that while FS
potentials always specify the embedding energy with a square root
dependence on the total density, the implementation in LAMMPS does not
require that; the user can tabulate any functional form desired in the
FS potential files.
For style {eam/fs}, the form of the pair_coeff command is exactly the
same as for style {eam/alloy}, e.g.
pair_coeff * * NiAlH_jea.eam.fs Ni Ni Ni Al :pre
where there are N additional arguments after the filename, where N is
the number of LAMMPS atom types. The N values determine the mapping
of LAMMPS atom types to EAM elements in the file, as described above
for style {eam/alloy}. As with {eam/alloy}, if a mapping value is
NULL, the mapping is not performed. This can be used when an {eam/fs}
potential is used as part of the {hybrid} pair style. The NULL values
are used as placeholders for atom types that will be used with other
potentials.
FS EAM files include more information than the DYNAMO {setfl} format
files read by {eam/alloy}, in that i,j density functionals for all
pairs of elements are included as needed by the Finnis/Sinclair
formulation of the EAM.
FS EAM files in the {potentials} directory of the LAMMPS distribution
have an ".eam.fs" suffix. They are formatted as follows:
lines 1,2,3 = comments (ignored)
line 4: Nelements Element1 Element2 ... ElementN
line 5: Nrho, drho, Nr, dr, cutoff :ul
The 5-line header section is identical to an EAM {setfl} file.
Following the header are Nelements sections, one for each element I,
each with the following format:
line 1 = atomic number, mass, lattice constant, lattice type (e.g. FCC)
embedding function F(rho) (Nrho values)
density function rho(r) for element I at element 1 (Nr values)
density function rho(r) for element I at element 2
...
density function rho(r) for element I at element Nelement :ul
The units of these quantities in line 1 are the same as for {setfl}
files. Note that the rho(r) arrays in Finnis/Sinclair can be
asymmetric (i,j != j,i) so there are Nelements^2 of them listed in the
file.
Following the Nelements sections, Nr values for each pair potential
phi(r) array are listed in the same manner (r*phi, units of
eV-Angstroms) as in EAM {setfl} files. Note that in Finnis/Sinclair,
the phi(r) arrays are still symmetric, so only phi arrays for i >= j
are listed.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
+See "Section_accerlate"_Section_accelerate.html of the manual for more
instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above with the individual styles. You never need to specify
a pair_coeff command with I != J arguments for the eam styles.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
The eam pair styles do not write their information to "binary restart
files"_restart.html, since it is stored in tabulated potential files.
Thus, you need to re-specify the pair_style and pair_coeff commands in
an input script that reads a restart file.
The eam pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
All of these styles except the {eam/cd} style are part of the MANYBODY
package. They are only enabled if LAMMPS was built with that package
(which it is by default). See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
The {eam/cd} style is part of the USER-MISC package and also requires
the MANYBODY package. It is only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Ackland1)
[(Ackland1)] Ackland, Condensed Matter (2005).
:link(Ackland2)
[(Ackland2)] Ackland, Mendelev, Srolovitz, Han and Barashev, Journal
of Physics: Condensed Matter, 16, S2629 (2004).
:link(Daw)
[(Daw)] Daw, Baskes, Phys Rev Lett, 50, 1285 (1983).
Daw, Baskes, Phys Rev B, 29, 6443 (1984).
:link(Finnis)
[(Finnis)] Finnis, Sinclair, Philosophical Magazine A, 50, 45 (1984).
:link(Stukowski)
[(Stukowski)] Stukowski, Sadigh, Erhart, Caro; Modeling Simulation
Materials Science & Engineering, 7, 075005 (2009).
diff --git a/doc/pair_edip.html b/doc/pair_edip.html
index 1c09c8ed4..fb65ffbda 100644
--- a/doc/pair_edip.html
+++ b/doc/pair_edip.html
@@ -1,170 +1,170 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style edip command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style edip
</PRE>
<PRE>pair_style edip/omp
</PRE>
<P><B>Examples:</B>
</P>
<P>pair_style edip
pair_coeff * * Si.edip Si
</P>
<P><B>Description:</B>
</P>
<P>The <I>edip</I> style computes a 3-body <A HREF = "#EDIP">EDIP</A> potential which is
popular for modeling silicon materials where it can have advantages
over other models such as the <A HREF = "pair_sw.html">Stillinger-Weber</A> or
<A HREF = "pair_tersoff.html">Tersoff</A> potentials. In EDIP, the energy E of a
system of atoms is
</P>
<CENTER><IMG SRC = "Eqs/pair_edip.jpg">
</CENTER>
<P>where phi2 is a two-body term and phi3 is a three-body term. The
summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = a.
Both terms depend on the local environment of atom I through its
effective coordination number defined by Z, which is unity for a
cutoff distance < c and gently goes to 0 at distance = a.
</P>
<P>Only a single pair_coeff command is used with the <I>edip</I> style which
specifies a EDIP potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of EDIP elements to atom types
</UL>
<P>As an example, imagine a file Si.edip has EDIP values for Si.
</P>
<P>EDIP files in the <I>potentials</I> directory of the LAMMPS
distribution have a ".edip" suffix. Lines that are not blank or
comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to the two-body
and three-body coefficients in the formula above:
</P>
<UL><LI>element 1 (the center atom in a 3-body interaction)
<LI>element 2
<LI>element 3
<LI>A (energy units)
<LI>B (distance units)
<LI>cutoffA (distance units)
<LI>cutoffC (distance units)
<LI>alpha
<LI>beta
<LI>eta
<LI>gamma (distance units)
<LI>lambda (energy units)
<LI>mu
<LI>tho
<LI>sigma (distance units)
<LI>Q0
<LI>u1
<LI>u2
<LI>u3
<LI>u4
</UL>
<P>The A, B, beta, sigma parameters are used only for two-body interactions.
The eta, gamma, lambda, mu, Q0 and all u1 to u4 parameters are used only
for three-body interactions. The alpha and cutoffC parameters are used
for the coordination environment function only.
</P>
<P>The EDIP potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
</P>
<P>For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify EDIP parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
</P>
<P>At the moment, only a single element parametrization is
implemented. However, the author is not aware of other
multi-element EDIP parametrizations. If you know any and
you are interest in that, please contact the author of
the EDIP package.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info on packages.
</P>
<P>This pair style requires the <A HREF = "newton.html">newton</A> setting to be "on"
for pair interactions.
</P>
<P>The EDIP potential files provided with LAMMPS (see the potentials directory)
are parameterized for metal <A HREF = "units.html">units</A>.
You can use the SW potential with any LAMMPS units, but you would need
to create your own EDIP potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "EDIP"></A>
<P><B>(EDIP)</B> J. F. Justo et al., Phys. Rev. B 58, 2539 (1998).
</P>
</HTML>
diff --git a/doc/pair_edip.txt b/doc/pair_edip.txt
index 3494ce68f..5fcf6e5d6 100644
--- a/doc/pair_edip.txt
+++ b/doc/pair_edip.txt
@@ -1,163 +1,163 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style edip command :h3
[Syntax:]
pair_style edip :pre
pair_style edip/omp :pre
[Examples:]
pair_style edip
pair_coeff * * Si.edip Si
[Description:]
The {edip} style computes a 3-body "EDIP"_#EDIP potential which is
popular for modeling silicon materials where it can have advantages
over other models such as the "Stillinger-Weber"_pair_sw.html or
"Tersoff"_pair_tersoff.html potentials. In EDIP, the energy E of a
system of atoms is
:c,image(Eqs/pair_edip.jpg)
where phi2 is a two-body term and phi3 is a three-body term. The
summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = a.
Both terms depend on the local environment of atom I through its
effective coordination number defined by Z, which is unity for a
cutoff distance < c and gently goes to 0 at distance = a.
Only a single pair_coeff command is used with the {edip} style which
specifies a EDIP potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of EDIP elements to atom types :ul
As an example, imagine a file Si.edip has EDIP values for Si.
EDIP files in the {potentials} directory of the LAMMPS
distribution have a ".edip" suffix. Lines that are not blank or
comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to the two-body
and three-body coefficients in the formula above:
element 1 (the center atom in a 3-body interaction)
element 2
element 3
A (energy units)
B (distance units)
cutoffA (distance units)
cutoffC (distance units)
alpha
beta
eta
gamma (distance units)
lambda (energy units)
mu
tho
sigma (distance units)
Q0
u1
u2
u3
u4 :ul
The A, B, beta, sigma parameters are used only for two-body interactions.
The eta, gamma, lambda, mu, Q0 and all u1 to u4 parameters are used only
for three-body interactions. The alpha and cutoffC parameters are used
for the coordination environment function only.
The EDIP potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify EDIP parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
At the moment, only a single element parametrization is
implemented. However, the author is not aware of other
multi-element EDIP parametrizations. If you know any and
you are interest in that, please contact the author of
the EDIP package.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This angle style can only be used if LAMMPS was built with the
USER-MISC package. See the "Making LAMMPS"_Section_start.html#start_3
section for more info on packages.
This pair style requires the "newton"_newton.html setting to be "on"
for pair interactions.
The EDIP potential files provided with LAMMPS (see the potentials directory)
are parameterized for metal "units"_units.html.
You can use the SW potential with any LAMMPS units, but you would need
to create your own EDIP potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(EDIP)
[(EDIP)] J. F. Justo et al., Phys. Rev. B 58, 2539 (1998).
diff --git a/doc/pair_eim.html b/doc/pair_eim.html
index 484cb2505..680353a8c 100644
--- a/doc/pair_eim.html
+++ b/doc/pair_eim.html
@@ -1,177 +1,177 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style eim command
</H3>
<H3>pair_style eim/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style
</PRE>
<UL><LI>style = <I>eim</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style eim
pair_coeff * * Na Cl ../potentials/ffield.eim Na Cl
pair_coeff * * Na Cl ffield.eim Na Na Na Cl
pair_coeff * * Na Cl ../potentials/ffield.eim Cl NULL Na
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>eim</I> computes pairwise interactions for ionic compounds
using embedded-ion method (EIM) potentials <A HREF = "#Zhou">(Zhou)</A>. The
energy of the system E is given by
</P>
<CENTER><IMG SRC = "Eqs/pair_eim1.jpg">
</CENTER>
<P>The first term is a double pairwise sum over the J neighbors of all I
atoms, where phi_ij is a pair potential. The second term sums over
the embedding energy E_i of atom I, which is a function of its charge
q_i and the electrical potential sigma_i at its location. E_i, q_i,
and sigma_i are calculated as
</P>
<CENTER><IMG SRC = "Eqs/pair_eim2.jpg">
</CENTER>
<P>where eta_ji is a pairwise function describing electron flow from atom
I to atom J, and psi_ij is another pairwise function. The multi-body
nature of the EIM potential is a result of the embedding energy term.
A complete list of all the pair functions used in EIM is summarized
below
</P>
<CENTER><IMG SRC = "Eqs/pair_eim3.jpg">
</CENTER>
<P>Here E_b, r_e, r_(c,phi), alpha, beta, A_(psi), zeta, r_(s,psi),
r_(c,psi), A_(eta), r_(s,eta), r_(c,eta), chi, and pair function type
p are parameters, with subscripts ij indicating the two species of
atoms in the atomic pair.
</P>
<P>IMPORTANT NOTE: Even though the EIM potential is treating atoms as
charged ions, you should not use a LAMMPS <A HREF = "atom_style.html">atom_style</A>
that stores a charge on each atom and thus requires you to assign a
charge to each atom, e.g. the <I>charge</I> or <I>full</I> atom styles. This is
because the EIM potential infers the charge on an atom from the
equation above for q_i; you do not assign charges explicitly.
</P>
<HR>
<P>All the EIM parameters are listed in a potential file which is
specified by the <A HREF = "pair_coeff.html">pair_coeff</A> command. This is an
ASCII text file in a format described below. The "ffield.eim" file
included in the "potentials" directory of the LAMMPS distribution
currently includes nine elements Li, Na, K, Rb, Cs, F, Cl, Br, and I.
A system with any combination of these elements can be modeled. This
file is parameterized in terms of LAMMPS <A HREF = "units.html">metal units</A>.
</P>
<P>Note that unlike other potentials, cutoffs for EIM potentials are not
set in the pair_style or pair_coeff command; they are specified in the
EIM potential file itself. Likewise, the EIM potential file lists
atomic masses; thus you do not need to use the <A HREF = "mass.html">mass</A>
command to specify them.
</P>
<P>Only a single pair_coeff command is used with the <I>eim</I> style which
specifies an EIM potential file and the element(s) to extract
information for. The EIM elements are mapped to LAMMPS atom types by
specifying N additional arguments after the filename in the pair_coeff
command, where N is the number of LAMMPS atom types:
</P>
<UL><LI>Elem1, Elem2, ...
<LI>EIM potential file
<LI>N element names = mapping of EIM elements to atom types
</UL>
<P>As an example like one of those above, suppose you want to model a
system with Na and Cl atoms. If your LAMMPS simulation has 4 atoms
types and you want the 1st 3 to be Na, and the 4th to be Cl, you would
use the following pair_coeff command:
</P>
<PRE>pair_coeff * * Na Cl ffield.eim Na Na Na Cl
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The filename is the EIM potential file. The Na and Cl arguments
(before the file name) are the two elements for which info will be
extracted from the potentail file. The first three trailing Na
arguments map LAMMPS atom types 1,2,3 to the EIM Na element. The
final Cl argument maps LAMMPS atom type 4 to the EIM Cl element.
</P>
<P>If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an <I>eim</I> potential is used as part of the
<I>hybrid</I> pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
</P>
<P>The ffield.eim file in the <I>potentials</I> directory of the LAMMPS
distribution is formated as follows:
</P>
<P>Lines starting with # are comments and are ignored by LAMMPS. Lines
starting with "global:" include three global values. The first value
divides the cations from anions, i.e., any elements with
electronegativity above this value are viewed as anions, and any
elements with electronegativity below this value are viewed as
cations. The second and third values are related to the cutoff
function - i.e. the 0.510204, 1.64498, and 0.010204 shown in the above
equation can be derived from these values.
</P>
<P>Lines starting with "element:" are formatted as follows: name of
element, atomic number, atomic mass, electronic negativity, atomic
radius (LAMMPS ignores it), ionic radius (LAMMPS ignores it), cohesive
energy (LAMMPS ignores it), and q0 (must be 0).
</P>
<P>Lines starting with "pair:" are entered as: element 1, element 2,
r_(c,phi), r_(c,phi) (redundant for historical reasons), E_b, r_e,
alpha, beta, r_(c,eta), A_(eta), r_(s,eta), r_(c,psi), A_(psi), zeta,
r_(s,psi), and p.
</P>
<P>The lines in the file can be in any order; LAMMPS extracts the info it
needs.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the MANYBODY package. It is only enabled if
LAMMPS was built with that package (which it is by default).
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Zhou"></A>
<P><B>(Zhou)</B> Zhou, submitted for publication (2010). Please contact
Xiaowang Zhou (Sandia) for details via email at xzhou at sandia.gov.
</P>
</HTML>
diff --git a/doc/pair_eim.txt b/doc/pair_eim.txt
index 21c054005..0c2b5439e 100644
--- a/doc/pair_eim.txt
+++ b/doc/pair_eim.txt
@@ -1,170 +1,170 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style eim command :h3
pair_style eim/omp command :h3
[Syntax:]
pair_style style :pre
style = {eim} :ul
[Examples:]
pair_style eim
pair_coeff * * Na Cl ../potentials/ffield.eim Na Cl
pair_coeff * * Na Cl ffield.eim Na Na Na Cl
pair_coeff * * Na Cl ../potentials/ffield.eim Cl NULL Na :pre
[Description:]
Style {eim} computes pairwise interactions for ionic compounds
using embedded-ion method (EIM) potentials "(Zhou)"_#Zhou. The
energy of the system E is given by
:c,image(Eqs/pair_eim1.jpg)
The first term is a double pairwise sum over the J neighbors of all I
atoms, where phi_ij is a pair potential. The second term sums over
the embedding energy E_i of atom I, which is a function of its charge
q_i and the electrical potential sigma_i at its location. E_i, q_i,
and sigma_i are calculated as
:c,image(Eqs/pair_eim2.jpg)
where eta_ji is a pairwise function describing electron flow from atom
I to atom J, and psi_ij is another pairwise function. The multi-body
nature of the EIM potential is a result of the embedding energy term.
A complete list of all the pair functions used in EIM is summarized
below
:c,image(Eqs/pair_eim3.jpg)
Here E_b, r_e, r_(c,phi), alpha, beta, A_(psi), zeta, r_(s,psi),
r_(c,psi), A_(eta), r_(s,eta), r_(c,eta), chi, and pair function type
p are parameters, with subscripts ij indicating the two species of
atoms in the atomic pair.
IMPORTANT NOTE: Even though the EIM potential is treating atoms as
charged ions, you should not use a LAMMPS "atom_style"_atom_style.html
that stores a charge on each atom and thus requires you to assign a
charge to each atom, e.g. the {charge} or {full} atom styles. This is
because the EIM potential infers the charge on an atom from the
equation above for q_i; you do not assign charges explicitly.
:line
All the EIM parameters are listed in a potential file which is
specified by the "pair_coeff"_pair_coeff.html command. This is an
ASCII text file in a format described below. The "ffield.eim" file
included in the "potentials" directory of the LAMMPS distribution
currently includes nine elements Li, Na, K, Rb, Cs, F, Cl, Br, and I.
A system with any combination of these elements can be modeled. This
file is parameterized in terms of LAMMPS "metal units"_units.html.
Note that unlike other potentials, cutoffs for EIM potentials are not
set in the pair_style or pair_coeff command; they are specified in the
EIM potential file itself. Likewise, the EIM potential file lists
atomic masses; thus you do not need to use the "mass"_mass.html
command to specify them.
Only a single pair_coeff command is used with the {eim} style which
specifies an EIM potential file and the element(s) to extract
information for. The EIM elements are mapped to LAMMPS atom types by
specifying N additional arguments after the filename in the pair_coeff
command, where N is the number of LAMMPS atom types:
Elem1, Elem2, ...
EIM potential file
N element names = mapping of EIM elements to atom types :ul
As an example like one of those above, suppose you want to model a
system with Na and Cl atoms. If your LAMMPS simulation has 4 atoms
types and you want the 1st 3 to be Na, and the 4th to be Cl, you would
use the following pair_coeff command:
pair_coeff * * Na Cl ffield.eim Na Na Na Cl :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The filename is the EIM potential file. The Na and Cl arguments
(before the file name) are the two elements for which info will be
extracted from the potentail file. The first three trailing Na
arguments map LAMMPS atom types 1,2,3 to the EIM Na element. The
final Cl argument maps LAMMPS atom type 4 to the EIM Cl element.
If a mapping value is specified as NULL, the mapping is not performed.
This can be used when an {eim} potential is used as part of the
{hybrid} pair style. The NULL values are placeholders for atom types
that will be used with other potentials.
The ffield.eim file in the {potentials} directory of the LAMMPS
distribution is formated as follows:
Lines starting with # are comments and are ignored by LAMMPS. Lines
starting with "global:" include three global values. The first value
divides the cations from anions, i.e., any elements with
electronegativity above this value are viewed as anions, and any
elements with electronegativity below this value are viewed as
cations. The second and third values are related to the cutoff
function - i.e. the 0.510204, 1.64498, and 0.010204 shown in the above
equation can be derived from these values.
Lines starting with "element:" are formatted as follows: name of
element, atomic number, atomic mass, electronic negativity, atomic
radius (LAMMPS ignores it), ionic radius (LAMMPS ignores it), cohesive
energy (LAMMPS ignores it), and q0 (must be 0).
Lines starting with "pair:" are entered as: element 1, element 2,
r_(c,phi), r_(c,phi) (redundant for historical reasons), E_b, r_e,
alpha, beta, r_(c,eta), A_(eta), r_(s,eta), r_(c,psi), A_(psi), zeta,
r_(s,psi), and p.
The lines in the file can be in any order; LAMMPS extracts the info it
needs.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Restrictions:]
This style is part of the MANYBODY package. It is only enabled if
LAMMPS was built with that package (which it is by default).
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Zhou)
[(Zhou)] Zhou, submitted for publication (2010). Please contact
Xiaowang Zhou (Sandia) for details via email at xzhou at sandia.gov.
diff --git a/doc/pair_gauss.html b/doc/pair_gauss.html
index 4a5f91c30..d29ba2e5c 100644
--- a/doc/pair_gauss.html
+++ b/doc/pair_gauss.html
@@ -1,120 +1,163 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style gauss command
</H3>
<H3>pair_style gauss/omp command
</H3>
+<H3>pair_style gauss/cut command
+</H3>
+<H3>pair_style gauss/cut/omp command
+</H3>
<P><B>Syntax:</B>
</P>
-<PRE>pair_style gauss cutoff
+<PRE>pair_style gauss cutoff
+pair_style gauss/cut cutoff
</PRE>
<UL><LI>cutoff = global cutoff for Gauss interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style gauss 12.0
pair_coeff * * 1.0 0.9
pair_coeff 1 4 1.0 0.9 10.0
</PRE>
+<PRE>pair_style gauss/cut 3.5
+pair_coeff 1 4 0.2805 1.45 0.112
+</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>gauss</I> computes a tethering potential of the form
</P>
<CENTER><IMG SRC = "Eqs/pair_gauss.jpg">
</CENTER>
<P>between an atom and its corresponding tether site which will typically
be a frozen atom in the simulation. Rc is the cutoff.
</P>
<P>The following coefficients must be defined for each pair of atom types
via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples above,
or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>A (energy units)
<LI>B (1/distance^2 units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global cutoff
is used.
</P>
+<P>Style <I>gauss/cut</I> computes a generalized Gaussian interaction potential
+between pairs of particles:
+</P>
+<CENTER><IMG SRC = "Eqs/pair_gauss_cut.jpg">
+</CENTER>
+<P>where H determines together with the standard deviation sigma_h the
+peak height of the Gaussian function, and r_mh the peak position.
+Examples of the use of the Gaussian potentials include implicit
+solvent simulations of salt ions <A HREF = "#Lenart">(Lenart)</A> and of surfactants
+<A HREF = "#Jusufi">(Jusufi)</A>. In these instances the Gaussian potential mimics
+the hydration barrier between a pair of particles. The hydration
+barrier is located at r_mh and has a width of sigma_h. The prefactor
+determines the hight of the potential barrier.
+</P>
+<P>The following coefficients must be defined for each pair of atom types
+via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the example above,
+or in the data file or restart files read by the
+<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
+commands:
+</P>
+<UL><LI>H (energy * distance units)
+<LI>r_mh (distance units)
+<LI>sigma_h (distance units)
+</UL>
+<P>The global cutoff (r_c) specified in the pair_style command is used.
+</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
-<P>This pair style does not support mixing. Thus, coefficients for all
+<P>These pair style do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
-<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
+<P>The <I>gauss</I> style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option. There is no effect due to the Gaussian well beyond the
cutoff; hence reasonable cutoffs need to be specified.
</P>
+<P>The <I>gauss/cut</I> style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
+option for the energy of the Gauss-potential portion of the pair
+interaction.
+</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table and tail options are not
relevant for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
table option, since a tabulation capability does not exist for this
potential.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
-<P>This pair style tallies an "occupancy" count of how many Gaussian-well
+<P>Thes <I>gauss</I> pair style tallies an "occupancy" count of how many Gaussian-well
sites have an atom within the distance at which the force is a maximum
= sqrt(0.5/b). This quantity can be accessed via the <A HREF = "compute_pair.html">compute
pair</A> command as a vector of values of length 1.
</P>
<P>To print this quantity to the log file (with a descriptive column
heading) the following commands could be included in an input script:
</P>
<PRE>compute gauss all pair gauss
variable occ equal c_gauss[1]
thermo_style custom step temp epair v_occ
</PRE>
<HR>
-<P><B>Restrictions:</B> none
+<P><B>Restrictions:</B>
+</P>
+<P>The <I>gauss/cut</I> style is part of the "user-misc" package. It is only enabled
+if LAMMPS is build with that package. See the <A HREF = "Section_start.html#3">Making of LAMMPS</A>
+section for more info.
</P>
<P><B>Related commands:</B>
</P>
-<P><A HREF = "pair_coeff.html">pair_coeff</A>
+<P><A HREF = "pair_coeff.html">pair_coeff</A>,
+<A HREF = "pair_coul_diel.html">pair_style coul/diel</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_gauss.txt b/doc/pair_gauss.txt
index e3e5b19d6..62092ce38 100644
--- a/doc/pair_gauss.txt
+++ b/doc/pair_gauss.txt
@@ -1,114 +1,156 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style gauss command :h3
pair_style gauss/omp command :h3
+pair_style gauss/cut command :h3
+pair_style gauss/cut/omp command :h3
[Syntax:]
-pair_style gauss cutoff :pre
+pair_style gauss cutoff
+pair_style gauss/cut cutoff :pre
cutoff = global cutoff for Gauss interactions (distance units) :ul
[Examples:]
pair_style gauss 12.0
pair_coeff * * 1.0 0.9
pair_coeff 1 4 1.0 0.9 10.0 :pre
+pair_style gauss/cut 3.5
+pair_coeff 1 4 0.2805 1.45 0.112 :pre
+
+
[Description:]
Style {gauss} computes a tethering potential of the form
:c,image(Eqs/pair_gauss.jpg)
between an atom and its corresponding tether site which will typically
be a frozen atom in the simulation. Rc is the cutoff.
The following coefficients must be defined for each pair of atom types
via the "pair_coeff"_pair_coeff.html command as in the examples above,
or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
A (energy units)
B (1/distance^2 units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global cutoff
is used.
+Style {gauss/cut} computes a generalized Gaussian interaction potential
+between pairs of particles:
+
+:c,image(Eqs/pair_gauss_cut.jpg)
+
+where H determines together with the standard deviation sigma_h the
+peak height of the Gaussian function, and r_mh the peak position.
+Examples of the use of the Gaussian potentials include implicit
+solvent simulations of salt ions "(Lenart)"_#Lenart and of surfactants
+"(Jusufi)"_#Jusufi. In these instances the Gaussian potential mimics
+the hydration barrier between a pair of particles. The hydration
+barrier is located at r_mh and has a width of sigma_h. The prefactor
+determines the hight of the potential barrier.
+
+The following coefficients must be defined for each pair of atom types
+via the "pair_coeff"_pair_coeff.html command as in the example above,
+or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands:
+
+H (energy * distance units)
+r_mh (distance units)
+sigma_h (distance units) :ul
+
+The global cutoff (r_c) specified in the pair_style command is used.
+
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
-This pair style does not support mixing. Thus, coefficients for all
+These pair style do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
-This pair style does not support the "pair_modify"_pair_modify.html
+The {gauss} style does not support the "pair_modify"_pair_modify.html
shift option. There is no effect due to the Gaussian well beyond the
cutoff; hence reasonable cutoffs need to be specified.
+The {gauss/cut} style supports the "pair_modify"_pair_modify.html shift
+option for the energy of the Gauss-potential portion of the pair
+interaction.
+
The "pair_modify"_pair_modify.html table and tail options are not
relevant for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
table option, since a tabulation capability does not exist for this
potential.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
-This pair style tallies an "occupancy" count of how many Gaussian-well
+Thes {gauss} pair style tallies an "occupancy" count of how many Gaussian-well
sites have an atom within the distance at which the force is a maximum
= sqrt(0.5/b). This quantity can be accessed via the "compute
pair"_compute_pair.html command as a vector of values of length 1.
To print this quantity to the log file (with a descriptive column
heading) the following commands could be included in an input script:
compute gauss all pair gauss
variable occ equal c_gauss\[1\]
thermo_style custom step temp epair v_occ :pre
:line
-[Restrictions:] none
+[Restrictions:]
+
+The {gauss/cut} style is part of the "user-misc" package. It is only enabled
+if LAMMPS is build with that package. See the "Making of LAMMPS"_Section_start.html#3
+section for more info.
[Related commands:]
-"pair_coeff"_pair_coeff.html
+"pair_coeff"_pair_coeff.html,
+"pair_style coul/diel"_pair_coul_diel.html
[Default:] none
diff --git a/doc/pair_gayberne.html b/doc/pair_gayberne.html
index ff4e001ce..de5b34c3b 100644
--- a/doc/pair_gayberne.html
+++ b/doc/pair_gayberne.html
@@ -1,240 +1,240 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style gayberne command
</H3>
<H3>pair_style gayberne/gpu command
</H3>
<H3>pair_style gayberne/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style gayberne gamma upsilon mu cutoff
</PRE>
<UL><LI>gamma = shift for potential minimum (typically 1)
<LI>upsilon = exponent for eta orientation-dependent energy function
<LI>mu = exponent for chi orientation-dependent energy function
<LI>cutoff = global cutoff for interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style gayberne 1.0 1.0 1.0 10.0
pair_coeff * * 1.0 1.7 1.7 3.4 3.4 1.0 1.0 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>gayberne</I> styles compute a Gay-Berne anisotropic LJ interaction
<A HREF = "#Berardi">(Berardi)</A> between pairs of ellipsoidal particles or an
ellipsoidal and spherical particle via the formulas
</P>
<CENTER><IMG SRC = "Eqs/pair_gayberne.jpg">
</CENTER>
<P>where A1 and A2 are the transformation matrices from the simulation
box frame to the body frame and r12 is the center to center vector
between the particles. Ur controls the shifted distance dependent
interaction based on the distance of closest approach of the two
particles (h12) and the user-specified shift parameter gamma. When
both particles are spherical, the formula reduces to the usual
Lennard-Jones interaction (see details below for when Gay-Berne treats
a particle as "spherical").
</P>
<P>For large uniform molecules it has been shown that the energy
parameters are approximately representable in terms of local contact
curvatures <A HREF = "#Everaers">(Everaers)</A>:
</P>
<CENTER><IMG SRC = "Eqs/pair_gayberne2.jpg">
</CENTER>
<P>The variable names utilized as potential parameters are for the most
part taken from <A HREF = "#Everaers">(Everaers)</A> in order to be consistent with
the <A HREF = "pair_resquared.html">RE-squared pair potential</A>. Details on the
upsilon and mu parameters are given
<A HREF = "PDF/pair_resquared_extra.pdf">here</A>.
</P>
<P>More details of the Gay-Berne formulation are given in the references
listed below and in <A HREF = "PDF/pair_gayberne_extra.pdf">this supplementary
document</A>.
</P>
<P>Use of this pair style requires the NVE, NVT, or NPT fixes with the
<I>asphere</I> extension (e.g. <A HREF = "fix_nve_asphere.html">fix nve/asphere</A>) in
order to integrate particle rotation. Additionally, <A HREF = "atom_style.html">atom_style
ellipsoid</A> should be used since it defines the
rotational state and the size and shape of each ellipsoidal particle.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon = well depth (energy units)
<LI>sigma = minimum effective particle radii (distance units)
<LI>epsilon_i_a = relative well depth of type I for side-to-side interactions
<LI>epsilon_i_b = relative well depth of type I for face-to-face interactions
<LI>epsilon_i_c = relative well depth of type I for end-to-end interactions
<LI>epsilon_j_a = relative well depth of type J for side-to-side interactions
<LI>epsilon_j_b = relative well depth of type J for face-to-face interactions
<LI>epsilon_j_c = relative well depth of type J for end-to-end interactions
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global
cutoff specified in the pair_style command is used.
</P>
<P>It is typical with the Gay-Berne potential to define <I>sigma</I> as the
minimum of the 3 shape diameters of the particles involved in an I,I
interaction, though this is not required. Note that this is a
different meaning for <I>sigma</I> than the <A HREF = "pair_resquared.html">pair_style
resquared</A> potential uses.
</P>
<P>The epsilon_i and epsilon_j coefficients are actually defined for atom
types, not for pairs of atom types. Thus, in a series of pair_coeff
commands, they only need to be specified once for each atom type.
</P>
<P>Specifically, if any of epsilon_i_a, epsilon_i_b, epsilon_i_c are
non-zero, the three values are assigned to atom type I. If all the
epsilon_i values are zero, they are ignored. If any of epsilon_j_a,
epsilon_j_b, epsilon_j_c are non-zero, the three values are assigned
to atom type J. If all three epsilon_i values are zero, they are
ignored. Thus the typical way to define the epsilon_i and epsilon_j
coefficients is to list their values in "pair_coeff I J" commands when
I = J, but set them to 0.0 when I != J. If you do list them when I !=
J, you should insure they are consistent with their values in other
pair_coeff commands.
</P>
<P>Note that if this potential is being used as a sub-style of
<A HREF = "pair_hybrid.html">pair_style hybrid</A>, and there is no "pair_coeff I I"
setting made for Gay-Berne for a particular type I (because I-I
interactions are computed by another hybrid pair potential), then you
still need to insure the epsilon a,b,c coefficients are assigned to
that type in a "pair_coeff I J" command.
</P>
<P>IMPORTANT NOTE: If the epsilon a = b = c for an atom type, and if the
shape of the particle itself is spherical, meaning its 3 shape
parameters are all the same, then the particle is treated as an LJ
sphere by the Gay-Berne potential. This is significant because if two
LJ spheres interact, then the simple Lennard-Jones formula is used to
compute their interaction energy/force using the specified epsilon and
sigma as the standard LJ parameters. This is much cheaper to compute
than the full Gay-Berne formula. To treat the particle as a LJ sphere
with sigma = D, you should normally set epsilon a = b = c = 1.0, set
the pair_coeff sigma = D, and also set the 3 shape parameters for the
particle to D. The one exception is that if the 3 shape parameters
are set to 0.0, which is a valid way in LAMMPS to specify a point
particle, then the Gay-Berne potential will treat that as shape
parameters of 1.0 (i.e. a LJ particle with sigma = 1), since it
requires finite-size particles. In this case you should still set the
pair_coeff sigma to 1.0 as well.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for this pair style can be mixed. The default mix
value is <I>geometric</I>. See the "pair_modify" command for details.
</P>
<P>This pair styles supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the Lennard-Jones portion of the pair
interaction, but only for sphere-sphere interactions. There is no
shifting performed for ellipsoidal interactions due to the anisotropic
dependence of the interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>gayberne</I> style is part of the ASPHERE package. It is only
enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>These pair style require that atoms store torque and a quaternion to
represent their orientation, as defined by the
<A HREF = "atom_style.html">atom_style</A>. It also require they store a per-type
<A HREF = "shape.html">shape</A>. The particles cannot store a per-particle
diameter.
</P>
<P>This pair style requires that atoms be ellipsoids as defined by the
<A HREF = "atom_style.html">atom_style ellipsoid</A> command.
</P>
<P>Particles acted on by the potential can be extended aspherical or
spherical particles, or point particles. Spherical particles have all
3 of their shape parameters equal to each other. Point particles have
all 3 of their shape parameters equal to 0.0.
</P>
<P>The Gay-Berne potential does not become isotropic as r increases
<A HREF = "#Everaers">(Everaers)</A>. The distance-of-closest-approach
approximation used by LAMMPS becomes less accurate when high-aspect
ratio ellipsoids are used.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "fix_nve_asphere.html">fix nve/asphere</A>,
<A HREF = "compute_temp_asphere.html">compute temp/asphere</A>, <A HREF = "pair_resquared.html">pair_style
resquared</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Everaers"></A>
<P><B>(Everaers)</B> Everaers and Ejtehadi, Phys Rev E, 67, 041710 (2003).
</P>
<A NAME = "Berardi"></A>
<P><B>(Berardi)</B> Berardi, Fava, Zannoni, Chem Phys Lett, 297, 8-14 (1998).
Berardi, Muccioli, Zannoni, J Chem Phys, 128, 024905 (2008).
</P>
<A NAME = "Perram"></A>
<P><B>(Perram)</B> Perram and Rasmussen, Phys Rev E, 54, 6565-6572 (1996).
</P>
<A NAME = "Allen"></A>
<P><B>(Allen)</B> Allen and Germano, Mol Phys 104, 3225-3235 (2006).
</P>
</HTML>
diff --git a/doc/pair_gayberne.txt b/doc/pair_gayberne.txt
index 9b3363c00..a83b4f43c 100755
--- a/doc/pair_gayberne.txt
+++ b/doc/pair_gayberne.txt
@@ -1,229 +1,229 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style gayberne command :h3
pair_style gayberne/gpu command :h3
pair_style gayberne/omp command :h3
[Syntax:]
pair_style gayberne gamma upsilon mu cutoff :pre
gamma = shift for potential minimum (typically 1)
upsilon = exponent for eta orientation-dependent energy function
mu = exponent for chi orientation-dependent energy function
cutoff = global cutoff for interactions (distance units) :ul
[Examples:]
pair_style gayberne 1.0 1.0 1.0 10.0
pair_coeff * * 1.0 1.7 1.7 3.4 3.4 1.0 1.0 1.0 :pre
[Description:]
The {gayberne} styles compute a Gay-Berne anisotropic LJ interaction
"(Berardi)"_#Berardi between pairs of ellipsoidal particles or an
ellipsoidal and spherical particle via the formulas
:c,image(Eqs/pair_gayberne.jpg)
where A1 and A2 are the transformation matrices from the simulation
box frame to the body frame and r12 is the center to center vector
between the particles. Ur controls the shifted distance dependent
interaction based on the distance of closest approach of the two
particles (h12) and the user-specified shift parameter gamma. When
both particles are spherical, the formula reduces to the usual
Lennard-Jones interaction (see details below for when Gay-Berne treats
a particle as "spherical").
For large uniform molecules it has been shown that the energy
parameters are approximately representable in terms of local contact
curvatures "(Everaers)"_#Everaers:
:c,image(Eqs/pair_gayberne2.jpg)
The variable names utilized as potential parameters are for the most
part taken from "(Everaers)"_#Everaers in order to be consistent with
the "RE-squared pair potential"_pair_resquared.html. Details on the
upsilon and mu parameters are given
"here"_PDF/pair_resquared_extra.pdf.
More details of the Gay-Berne formulation are given in the references
listed below and in "this supplementary
document"_PDF/pair_gayberne_extra.pdf.
Use of this pair style requires the NVE, NVT, or NPT fixes with the
{asphere} extension (e.g. "fix nve/asphere"_fix_nve_asphere.html) in
order to integrate particle rotation. Additionally, "atom_style
ellipsoid"_atom_style.html should be used since it defines the
rotational state and the size and shape of each ellipsoidal particle.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon = well depth (energy units)
sigma = minimum effective particle radii (distance units)
epsilon_i_a = relative well depth of type I for side-to-side interactions
epsilon_i_b = relative well depth of type I for face-to-face interactions
epsilon_i_c = relative well depth of type I for end-to-end interactions
epsilon_j_a = relative well depth of type J for side-to-side interactions
epsilon_j_b = relative well depth of type J for face-to-face interactions
epsilon_j_c = relative well depth of type J for end-to-end interactions
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global
cutoff specified in the pair_style command is used.
It is typical with the Gay-Berne potential to define {sigma} as the
minimum of the 3 shape diameters of the particles involved in an I,I
interaction, though this is not required. Note that this is a
different meaning for {sigma} than the "pair_style
resquared"_pair_resquared.html potential uses.
The epsilon_i and epsilon_j coefficients are actually defined for atom
types, not for pairs of atom types. Thus, in a series of pair_coeff
commands, they only need to be specified once for each atom type.
Specifically, if any of epsilon_i_a, epsilon_i_b, epsilon_i_c are
non-zero, the three values are assigned to atom type I. If all the
epsilon_i values are zero, they are ignored. If any of epsilon_j_a,
epsilon_j_b, epsilon_j_c are non-zero, the three values are assigned
to atom type J. If all three epsilon_i values are zero, they are
ignored. Thus the typical way to define the epsilon_i and epsilon_j
coefficients is to list their values in "pair_coeff I J" commands when
I = J, but set them to 0.0 when I != J. If you do list them when I !=
J, you should insure they are consistent with their values in other
pair_coeff commands.
Note that if this potential is being used as a sub-style of
"pair_style hybrid"_pair_hybrid.html, and there is no "pair_coeff I I"
setting made for Gay-Berne for a particular type I (because I-I
interactions are computed by another hybrid pair potential), then you
still need to insure the epsilon a,b,c coefficients are assigned to
that type in a "pair_coeff I J" command.
IMPORTANT NOTE: If the epsilon a = b = c for an atom type, and if the
shape of the particle itself is spherical, meaning its 3 shape
parameters are all the same, then the particle is treated as an LJ
sphere by the Gay-Berne potential. This is significant because if two
LJ spheres interact, then the simple Lennard-Jones formula is used to
compute their interaction energy/force using the specified epsilon and
sigma as the standard LJ parameters. This is much cheaper to compute
than the full Gay-Berne formula. To treat the particle as a LJ sphere
with sigma = D, you should normally set epsilon a = b = c = 1.0, set
the pair_coeff sigma = D, and also set the 3 shape parameters for the
particle to D. The one exception is that if the 3 shape parameters
are set to 0.0, which is a valid way in LAMMPS to specify a point
particle, then the Gay-Berne potential will treat that as shape
parameters of 1.0 (i.e. a LJ particle with sigma = 1), since it
requires finite-size particles. In this case you should still set the
pair_coeff sigma to 1.0 as well.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for this pair style can be mixed. The default mix
value is {geometric}. See the "pair_modify" command for details.
This pair styles supports the "pair_modify"_pair_modify.html shift
option for the energy of the Lennard-Jones portion of the pair
interaction, but only for sphere-sphere interactions. There is no
shifting performed for ellipsoidal interactions due to the anisotropic
dependence of the interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
The {gayberne} style is part of the ASPHERE package. It is only
enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
These pair style require that atoms store torque and a quaternion to
represent their orientation, as defined by the
"atom_style"_atom_style.html. It also require they store a per-type
"shape"_shape.html. The particles cannot store a per-particle
diameter.
This pair style requires that atoms be ellipsoids as defined by the
"atom_style ellipsoid"_atom_style.html command.
Particles acted on by the potential can be extended aspherical or
spherical particles, or point particles. Spherical particles have all
3 of their shape parameters equal to each other. Point particles have
all 3 of their shape parameters equal to 0.0.
The Gay-Berne potential does not become isotropic as r increases
"(Everaers)"_#Everaers. The distance-of-closest-approach
approximation used by LAMMPS becomes less accurate when high-aspect
ratio ellipsoids are used.
[Related commands:]
"pair_coeff"_pair_coeff.html, "fix nve/asphere"_fix_nve_asphere.html,
"compute temp/asphere"_compute_temp_asphere.html, "pair_style
resquared"_pair_resquared.html
[Default:] none
:line
:link(Everaers)
[(Everaers)] Everaers and Ejtehadi, Phys Rev E, 67, 041710 (2003).
:link(Berardi)
[(Berardi)] Berardi, Fava, Zannoni, Chem Phys Lett, 297, 8-14 (1998).
Berardi, Muccioli, Zannoni, J Chem Phys, 128, 024905 (2008).
:link(Perram)
[(Perram)] Perram and Rasmussen, Phys Rev E, 54, 6565-6572 (1996).
:link(Allen)
[(Allen)] Allen and Germano, Mol Phys 104, 3225-3235 (2006).
diff --git a/doc/pair_gran.html b/doc/pair_gran.html
index 2c0056f52..d9862cbe6 100644
--- a/doc/pair_gran.html
+++ b/doc/pair_gran.html
@@ -1,253 +1,264 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style gran/hooke command
</H3>
<H3>pair_style gran/cuda command
</H3>
<H3>pair_style gran/omp command
</H3>
<H3>pair_style gran/hooke/history command
</H3>
<H3>pair_style gran/hooke/history/omp command
</H3>
<H3>pair_style gran/hertz/history command
</H3>
<H3>pair_style gran/hertz/history/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style Kn Kt gamma_n gamma_t xmu dampflag
</PRE>
<UL><LI>style = <I>gran/hooke</I> or <I>gran/hooke/history</I> or <I>gran/hertz/history</I>
<LI>Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below)
<LI>Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below)
<LI>gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below)
<LI>gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below)
<LI>xmu = static yield criterion (unitless fraction between 0.0 and 1.0)
<LI>dampflag = 0 or 1 if tangential damping force is excluded or included
</UL>
<P>IMPORTANT NOTE: Versions of LAMMPS before 9Jan09 had different style
names for granular force fields. This is to emphasize the fact that
the Hertzian equation has changed to model polydispersity more
accurately. A side effect of the change is that the Kn, Kt, gamma_n,
and gamma_t coefficients in the pair_style command must be specified
with different values in order to reproduce calculations made with
earlier versions of LAMMPS, even for monodisperse systems. See the
NOTE below for details.
</P>
<P><B>Examples:</B>
</P>
<PRE>pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 1
pair_style gran/hooke 200000.0 70000.0 50.0 30.0 0.5 0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>gran</I> styles use the following formulas for the frictional force
between two granular particles, as described in
<A HREF = "#Brilliantov">(Brilliantov)</A>, <A HREF = "#Silbert">(Silbert)</A>, and
<A HREF = "#Zhang">(Zhang)</A>, when the distance r between two particles of radii
Ri and Rj is less than their contact distance d = Ri + Rj. There is
no force between the particles when r > d.
</P>
<P>The two Hookean styles use this formula:
</P>
<CENTER><IMG SRC = "Eqs/pair_gran_hooke.jpg">
</CENTER>
<P>The Hertzian style uses this formula:
</P>
<CENTER><IMG SRC = "Eqs/pair_gran_hertz.jpg">
</CENTER>
<P>In both equations the first parenthesized term is the normal force
between the two particles and the second parenthesized term is the
tangential force. The normal force has 2 terms, a contact force and a
damping force. The tangential force also has 2 terms: a shear force
and a damping force. The shear force is a "history" effect that
accounts for the tangential displacement between the particles for the
duration of the time they are in contact. This term is included in
pair styles <I>hooke/history</I> and <I>hertz/history</I>, but is not included
in pair style <I>hooke</I>. The tangential damping force term is included
in all three pair styles if <I>dampflag</I> is set to 1; it is not included
if <I>dampflag</I> is set to 0.
</P>
<P>The other quantities in the equations are as follows:
</P>
<UL><LI>delta = d - r = overlap distance of 2 particles
<LI>Kn = elastic constant for normal contact
<LI>Kt = elastic constant for tangential contact
<LI>gamma_n = viscoelastic damping constant for normal contact
<LI>gamma_t = viscoelastic damping constant for tangential contact
<LI>m_eff = Mi Mj / (Mi + Mj) = effective mass of 2 particles of mass Mi and Mj
<LI>Delta St = tangential displacement vector between 2 spherical particles which is truncated to satisfy a frictional yield criterion
<LI>n_ij = unit vector along the line connecting the centers of the 2 particles
<LI>Vn = normal component of the relative velocity of the 2 particles
<LI>Vt = tangential component of the relative velocity of the 2 particles
</UL>
<P>The Kn, Kt, gamma_n, and gamma_t coefficients are specified as
parameters to the pair_style command. If a NULL is used for Kt, then
a default value is used where Kt = 2/7 Kn. If a NULL is used for
gamma_t, then a default value is used where gamma_t = 1/2 gamma_n.
</P>
<P>The interpretation and units for these 4 coefficients are different in
the Hookean versus Hertzian equations.
</P>
<P>The Hookean model is one where the normal push-back force for two
overlapping particles is a linear function of the overlap distance.
Thus the specified Kn is in units of (force/distance). Note that this
push-back force is independent of absolute particle size (in the
monodisperse case) and of the relative sizes of the two particles (in
the polydisperse case). This model also applies to the other terms in
the force equation so that the specified gamma_n is in units of
(1/time), Kt is in units of (force/distance), and gamma_t is in units
of (1/time).
</P>
<P>The Hertzian model is one where the normal push-back force for two
overlapping particles is proportional to the area of overlap of the
two particles, and is thus a non-linear function of overlap distance.
Thus Kn has units of force per area and is thus specified in units of
(pressure). The effects of absolute particle size (monodispersity)
and relative size (polydispersity) are captured in the radii-dependent
pre-factors. When these pre-factors are carried through to the other
terms in the force equation it means that the specified gamma_n is in
units of (1/(time*distance)), Kt is in units of (pressure), and
gamma_t is in units of (1/(time*distance)).
</P>
<P>Note that in the Hookean case, Kn can be thought of as a linear spring
constant with units of force/distance. In the Hertzian case, Kn is
like a non-linear spring constant with units of force/area or
pressure, and as shown in the <A HREF = "#Zhang">(Zhang)</A> paper, Kn = 4G /
(3(1-nu)) where nu = the Poisson ratio, G = shear modulus = E /
(2(1+nu)), and E = Young's modulus. Similarly, Kt = 8G / (2-nu).
Thus in the Hertzian case Kn and Kt can be set to values that
corresponds to properties of the material being modeled. This is also
true in the Hookean case, except that a spring constant must be chosen
that is appropriate for the absolute size of particles in the model.
Since relative particle sizes are not accounted for, the Hookean
styles may not be a suitable model for polydisperse systems.
</P>
<P>IMPORTANT NOTE: In versions of LAMMPS before 9Jan09, the equation for
Hertzian interactions did not include the sqrt(RiRj/Ri+Rj) term and
thus was not as accurate for polydisperse systems. For monodisperse
systems, sqrt(RiRj/Ri+Rj) is a constant factor that effectively scales
all 4 coefficients: Kn, Kt, gamma_n, gamma_t. Thus you can set the
values of these 4 coefficients appropriately in the current code to
reproduce the results of a previous Hertzian monodisperse calculation.
For example, for the common case of a monodisperse system with
particles of diameter 1, all 4 of these coefficients should now be set
2x larger than they were previously.
</P>
<P>Xmu is also specified in the pair_style command and is the upper limit
of the tangential force through the Coulomb criterion Ft = xmu*Fn,
where Ft and Fn are the total tangential and normal force components
in the formulas above. Thus in the Hookean case, the tangential force
between 2 particles grows according to a tangential spring and
dash-pot model until Ft/Fn = xmu and is then held at Ft = Fn*xmu until
the particles lose contact. In the Hertzian case, a similar analogy
holds, though the spring is no longer linear.
</P>
<P>For granular styles there are no additional coefficients to set for
each pair of atom types via the <A HREF = "pair_coeff.html">pair_coeff</A> command.
All settings are global and are made via the pair_style command.
However you must still use the <A HREF = "pair_coeff.html">pair_coeff</A> for all
pairs of granular atom types. For example the command
</P>
<PRE>pair_coeff * *
</PRE>
<P>should be used if all atoms in the simulation interact via a granular
potential (i.e. one of the pair styles above is used). If a granular
potential is used as a sub-style of <A HREF = "pair_hybrid.html">pair_style
hybrid</A>, then specific atom types can be used in the
pair_coeff command to determine which atoms interact via a granular
potential.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> mix, shift, table, and tail options
are not relevant for granular pair styles.
</P>
<P>These pair styles write their information to <A HREF = "restart.html">binary restart
files</A>, so a pair_style command does not need to be
specified in an input script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
+<P>The single() function of these pair styles returns 0.0 for the energy
+of a pairwise interaction, since energy is not conserved in these
+dissipative potentials. It also returns only the normal component of
+the pairwise interaction force. However, the single() function also
+calculates 4 extra pairwise quantities. The first 3 are the
+components of the tangential force between particles I and J, acting
+on particle I. <I>P4</I> is the magnitude of this tangential force. These
+extra quantites can be accessed by the <A HREF = "compute_pair_local.html">compute
+pair/local</A> command, as <I>p1</I>, <I>p2</I>, <I>p3</I>,
+<I>p4</I>.
+</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P>All the granular pair styles are part of the GRANULAR package. It is
only enabled if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>These pair styles require that atoms store torque and angular velocity
(omega) as defined by the <A HREF = "atom_style.html">atom_style</A>. They also
require a per-particle radius is stored. The <I>sphere</I> atom style does
all of this.
</P>
<P>This pair style requires you to use the <A HREF = "communicate.html">communicate vel
yes</A> option so that velocites are stored by ghost
atoms.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Brilliantov"></A>
<P><B>(Brilliantov)</B> Brilliantov, Spahn, Hertzsch, Poschel, Phys Rev E, 53,
p 5382-5392 (1996).
</P>
<A NAME = "Silbert"></A>
<P><B>(Silbert)</B> Silbert, Ertas, Grest, Halsey, Levine, Plimpton, Phys Rev
E, 64, p 051302 (2001).
</P>
<A NAME = "Zhang"></A>
<P><B>(Zhang)</B> Zhang and Makse, Phys Rev E, 72, p 011301 (2005).
</P>
</HTML>
diff --git a/doc/pair_gran.txt b/doc/pair_gran.txt
index d495c010f..d84b2ae48 100644
--- a/doc/pair_gran.txt
+++ b/doc/pair_gran.txt
@@ -1,234 +1,245 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style gran/hooke command :h3
pair_style gran/cuda command :h3
pair_style gran/omp command :h3
pair_style gran/hooke/history command :h3
pair_style gran/hooke/history/omp command :h3
pair_style gran/hertz/history command :h3
pair_style gran/hertz/history/omp command :h3
[Syntax:]
pair_style style Kn Kt gamma_n gamma_t xmu dampflag :pre
style = {gran/hooke} or {gran/hooke/history} or {gran/hertz/history} :ulb,l
Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) :l
Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) :l
gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) :l
gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) :l
xmu = static yield criterion (unitless fraction between 0.0 and 1.0) :l
dampflag = 0 or 1 if tangential damping force is excluded or included :l,ule
IMPORTANT NOTE: Versions of LAMMPS before 9Jan09 had different style
names for granular force fields. This is to emphasize the fact that
the Hertzian equation has changed to model polydispersity more
accurately. A side effect of the change is that the Kn, Kt, gamma_n,
and gamma_t coefficients in the pair_style command must be specified
with different values in order to reproduce calculations made with
earlier versions of LAMMPS, even for monodisperse systems. See the
NOTE below for details.
[Examples:]
pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 1
pair_style gran/hooke 200000.0 70000.0 50.0 30.0 0.5 0 :pre
[Description:]
The {gran} styles use the following formulas for the frictional force
between two granular particles, as described in
"(Brilliantov)"_#Brilliantov, "(Silbert)"_#Silbert, and
"(Zhang)"_#Zhang, when the distance r between two particles of radii
Ri and Rj is less than their contact distance d = Ri + Rj. There is
no force between the particles when r > d.
The two Hookean styles use this formula:
:c,image(Eqs/pair_gran_hooke.jpg)
The Hertzian style uses this formula:
:c,image(Eqs/pair_gran_hertz.jpg)
In both equations the first parenthesized term is the normal force
between the two particles and the second parenthesized term is the
tangential force. The normal force has 2 terms, a contact force and a
damping force. The tangential force also has 2 terms: a shear force
and a damping force. The shear force is a "history" effect that
accounts for the tangential displacement between the particles for the
duration of the time they are in contact. This term is included in
pair styles {hooke/history} and {hertz/history}, but is not included
in pair style {hooke}. The tangential damping force term is included
in all three pair styles if {dampflag} is set to 1; it is not included
if {dampflag} is set to 0.
The other quantities in the equations are as follows:
delta = d - r = overlap distance of 2 particles
Kn = elastic constant for normal contact
Kt = elastic constant for tangential contact
gamma_n = viscoelastic damping constant for normal contact
gamma_t = viscoelastic damping constant for tangential contact
m_eff = Mi Mj / (Mi + Mj) = effective mass of 2 particles of mass Mi and Mj
Delta St = tangential displacement vector between 2 spherical particles \
which is truncated to satisfy a frictional yield criterion
n_ij = unit vector along the line connecting the centers of the 2 particles
Vn = normal component of the relative velocity of the 2 particles
Vt = tangential component of the relative velocity of the 2 particles :ul
The Kn, Kt, gamma_n, and gamma_t coefficients are specified as
parameters to the pair_style command. If a NULL is used for Kt, then
a default value is used where Kt = 2/7 Kn. If a NULL is used for
gamma_t, then a default value is used where gamma_t = 1/2 gamma_n.
The interpretation and units for these 4 coefficients are different in
the Hookean versus Hertzian equations.
The Hookean model is one where the normal push-back force for two
overlapping particles is a linear function of the overlap distance.
Thus the specified Kn is in units of (force/distance). Note that this
push-back force is independent of absolute particle size (in the
monodisperse case) and of the relative sizes of the two particles (in
the polydisperse case). This model also applies to the other terms in
the force equation so that the specified gamma_n is in units of
(1/time), Kt is in units of (force/distance), and gamma_t is in units
of (1/time).
The Hertzian model is one where the normal push-back force for two
overlapping particles is proportional to the area of overlap of the
two particles, and is thus a non-linear function of overlap distance.
Thus Kn has units of force per area and is thus specified in units of
(pressure). The effects of absolute particle size (monodispersity)
and relative size (polydispersity) are captured in the radii-dependent
pre-factors. When these pre-factors are carried through to the other
terms in the force equation it means that the specified gamma_n is in
units of (1/(time*distance)), Kt is in units of (pressure), and
gamma_t is in units of (1/(time*distance)).
Note that in the Hookean case, Kn can be thought of as a linear spring
constant with units of force/distance. In the Hertzian case, Kn is
like a non-linear spring constant with units of force/area or
pressure, and as shown in the "(Zhang)"_#Zhang paper, Kn = 4G /
(3(1-nu)) where nu = the Poisson ratio, G = shear modulus = E /
(2(1+nu)), and E = Young's modulus. Similarly, Kt = 8G / (2-nu).
Thus in the Hertzian case Kn and Kt can be set to values that
corresponds to properties of the material being modeled. This is also
true in the Hookean case, except that a spring constant must be chosen
that is appropriate for the absolute size of particles in the model.
Since relative particle sizes are not accounted for, the Hookean
styles may not be a suitable model for polydisperse systems.
IMPORTANT NOTE: In versions of LAMMPS before 9Jan09, the equation for
Hertzian interactions did not include the sqrt(RiRj/Ri+Rj) term and
thus was not as accurate for polydisperse systems. For monodisperse
systems, sqrt(RiRj/Ri+Rj) is a constant factor that effectively scales
all 4 coefficients: Kn, Kt, gamma_n, gamma_t. Thus you can set the
values of these 4 coefficients appropriately in the current code to
reproduce the results of a previous Hertzian monodisperse calculation.
For example, for the common case of a monodisperse system with
particles of diameter 1, all 4 of these coefficients should now be set
2x larger than they were previously.
Xmu is also specified in the pair_style command and is the upper limit
of the tangential force through the Coulomb criterion Ft = xmu*Fn,
where Ft and Fn are the total tangential and normal force components
in the formulas above. Thus in the Hookean case, the tangential force
between 2 particles grows according to a tangential spring and
dash-pot model until Ft/Fn = xmu and is then held at Ft = Fn*xmu until
the particles lose contact. In the Hertzian case, a similar analogy
holds, though the spring is no longer linear.
For granular styles there are no additional coefficients to set for
each pair of atom types via the "pair_coeff"_pair_coeff.html command.
All settings are global and are made via the pair_style command.
However you must still use the "pair_coeff"_pair_coeff.html for all
pairs of granular atom types. For example the command
pair_coeff * * :pre
should be used if all atoms in the simulation interact via a granular
potential (i.e. one of the pair styles above is used). If a granular
potential is used as a sub-style of "pair_style
hybrid"_pair_hybrid.html, then specific atom types can be used in the
pair_coeff command to determine which atoms interact via a granular
potential.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
The "pair_modify"_pair_modify.html mix, shift, table, and tail options
are not relevant for granular pair styles.
These pair styles write their information to "binary restart
files"_restart.html, so a pair_style command does not need to be
specified in an input script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
+The single() function of these pair styles returns 0.0 for the energy
+of a pairwise interaction, since energy is not conserved in these
+dissipative potentials. It also returns only the normal component of
+the pairwise interaction force. However, the single() function also
+calculates 4 extra pairwise quantities. The first 3 are the
+components of the tangential force between particles I and J, acting
+on particle I. {P4} is the magnitude of this tangential force. These
+extra quantites can be accessed by the "compute
+pair/local"_compute_pair_local.html command, as {p1}, {p2}, {p3},
+{p4}.
+
:line
[Restrictions:] none
All the granular pair styles are part of the GRANULAR package. It is
only enabled if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
These pair styles require that atoms store torque and angular velocity
(omega) as defined by the "atom_style"_atom_style.html. They also
require a per-particle radius is stored. The {sphere} atom style does
all of this.
This pair style requires you to use the "communicate vel
yes"_communicate.html option so that velocites are stored by ghost
atoms.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Brilliantov)
[(Brilliantov)] Brilliantov, Spahn, Hertzsch, Poschel, Phys Rev E, 53,
p 5382-5392 (1996).
:link(Silbert)
[(Silbert)] Silbert, Ertas, Grest, Halsey, Levine, Plimpton, Phys Rev
E, 64, p 051302 (2001).
:link(Zhang)
[(Zhang)] Zhang and Makse, Phys Rev E, 72, p 011301 (2005).
diff --git a/doc/pair_gromacs.html b/doc/pair_gromacs.html
index aa8051d5c..3f84634b5 100644
--- a/doc/pair_gromacs.html
+++ b/doc/pair_gromacs.html
@@ -1,165 +1,165 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/gromacs command
</H3>
<H3>pair_style lj/gromacs/cuda command
</H3>
<H3>pair_style lj/gromacs/omp command
</H3>
<H3>pair_style lj/gromacs/coul/gromacs command
</H3>
<H3>pair_style lj/gromacs/coul/gromacs/cuda command
</H3>
<H3>pair_style lj/gromacs/coul/gromacs/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = <I>lj/gromacs</I> or <I>lj/gromacs/coul/gromacs</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>lj/gromacs</I> args = inner outer
inner, outer = global switching cutoffs for Lennard Jones
<I>lj/gromacs/coul/gromacs</I> args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for Lennard Jones (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/gromacs 9.0 12.0
pair_coeff * * 100.0 2.0
pair_coeff 2 2 100.0 2.0 8.0 10.0
</PRE>
<PRE>pair_style lj/gromacs/coul/gromacs 9.0 12.0
pair_style lj/gromacs/coul/gromacs 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/gromacs</I> styles compute shifted LJ and Coulombic interactions
with an additional switching function S(r) that ramps the energy and force
smoothly to zero between an inner and outer cutoff. It is a commonly
used potential in the <A HREF = "http://www.gromacs.org">GROMACS</A> MD code and for
the coarse-grained models of <A HREF = "#Marrink">(Marrink)</A>.
</P>
<CENTER><IMG SRC = "Eqs/pair_gromacs.jpg">
</CENTER>
<P>R1 is the inner cutoff; Rc is the outer cutoff. The coefficients A, B,
and C are computed by LAMMPS to perform the shifting and smoothing.
The function
S(r) is actually applied once to each term of the LJ formula and once
to the Coulombic formula, so there are 2 or 3 sets of A,B,C coefficients
depending on which pair_style is used. The boundary conditions
applied to the smoothing function are as follows: S(r1) = S'(r1) = 0,
S(rc) = -F(rc), S'(rc) = -F'(rc), where F(r) is the corresponding term
in the LJ or Coulombic potential energy function and a
single quote represents a derivative with respect to r.
</P>
<P>The inner and outer cutoff for the LJ and Coulombic terms can be the
same or different depending on whether 2 or 4 arguments are used in
the pair_style command. The inner LJ cutoff must be > 0, but the
inner Coulombic cutoff can be >= 0.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>inner (distance units)
<LI>outer (distance units)
</UL>
<P>Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
</P>
<P>The last 2 coefficients are optional inner and outer cutoffs for style
<I>lj/gromacs</I>. If not specified, the global <I>inner</I> and <I>outer</I> values
are used.
</P>
<P>The last 2 coefficients cannot be used with style
<I>lj/gromacs/coul/gromacs</I> because this force field does not allow
varying cutoffs for individual atom pairs; all pairs use the global
cutoff(s) specified in the pair_style command.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is <I>geometric</I>. See the "pair_modify" command
for details.
</P>
<P>None of the GROMACS pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> shift option, since the Lennard-Jones
portion of the pair interaction is already smoothed to 0.0 at the
cutoff.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>None of the GROMACS pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> tail option for adding long-range tail
corrections to energy and pressure, since there are no corrections for
a potential that goes to 0.0 at the cutoff.
</P>
<P>All of the GROMACS pair styles write their information to <A HREF = "restart.html">binary
restart files</A>, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
</P>
<P>All of the GROMACS pair styles can only be used via the <I>pair</I>
keyword of the <A HREF = "run_style.html">run_style respa</A> command. They do not
support the <I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Marrink"></A>
<P><B>(Marrink)</B> Marrink, de Vries, Mark, J Phys Chem B, 108, 750-760 (2004).
</P>
</HTML>
diff --git a/doc/pair_gromacs.txt b/doc/pair_gromacs.txt
index 5fc8ef3c4..d276615d1 100644
--- a/doc/pair_gromacs.txt
+++ b/doc/pair_gromacs.txt
@@ -1,153 +1,153 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/gromacs command :h3
pair_style lj/gromacs/cuda command :h3
pair_style lj/gromacs/omp command :h3
pair_style lj/gromacs/coul/gromacs command :h3
pair_style lj/gromacs/coul/gromacs/cuda command :h3
pair_style lj/gromacs/coul/gromacs/omp command :h3
[Syntax:]
pair_style style args :pre
style = {lj/gromacs} or {lj/gromacs/coul/gromacs}
args = list of arguments for a particular style :ul
{lj/gromacs} args = inner outer
inner, outer = global switching cutoffs for Lennard Jones
{lj/gromacs/coul/gromacs} args = inner outer (inner2) (outer2)
inner, outer = global switching cutoffs for Lennard Jones (and Coulombic if only 2 args)
inner2, outer2 = global switching cutoffs for Coulombic (optional) :pre
[Examples:]
pair_style lj/gromacs 9.0 12.0
pair_coeff * * 100.0 2.0
pair_coeff 2 2 100.0 2.0 8.0 10.0 :pre
pair_style lj/gromacs/coul/gromacs 9.0 12.0
pair_style lj/gromacs/coul/gromacs 8.0 10.0 7.0 9.0
pair_coeff * * 100.0 2.0 :pre
[Description:]
The {lj/gromacs} styles compute shifted LJ and Coulombic interactions
with an additional switching function S(r) that ramps the energy and force
smoothly to zero between an inner and outer cutoff. It is a commonly
used potential in the "GROMACS"_http://www.gromacs.org MD code and for
the coarse-grained models of "(Marrink)"_#Marrink.
:c,image(Eqs/pair_gromacs.jpg)
R1 is the inner cutoff; Rc is the outer cutoff. The coefficients A, B,
and C are computed by LAMMPS to perform the shifting and smoothing.
The function
S(r) is actually applied once to each term of the LJ formula and once
to the Coulombic formula, so there are 2 or 3 sets of A,B,C coefficients
depending on which pair_style is used. The boundary conditions
applied to the smoothing function are as follows: S(r1) = S'(r1) = 0,
S(rc) = -F(rc), S'(rc) = -F'(rc), where F(r) is the corresponding term
in the LJ or Coulombic potential energy function and a
single quote represents a derivative with respect to r.
The inner and outer cutoff for the LJ and Coulombic terms can be the
same or different depending on whether 2 or 4 arguments are used in
the pair_style command. The inner LJ cutoff must be > 0, but the
inner Coulombic cutoff can be >= 0.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
inner (distance units)
outer (distance units) :ul
Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
The last 2 coefficients are optional inner and outer cutoffs for style
{lj/gromacs}. If not specified, the global {inner} and {outer} values
are used.
The last 2 coefficients cannot be used with style
{lj/gromacs/coul/gromacs} because this force field does not allow
varying cutoffs for individual atom pairs; all pairs use the global
cutoff(s) specified in the pair_style command.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is {geometric}. See the "pair_modify" command
for details.
None of the GROMACS pair styles support the
"pair_modify"_pair_modify.html shift option, since the Lennard-Jones
portion of the pair interaction is already smoothed to 0.0 at the
cutoff.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
None of the GROMACS pair styles support the
"pair_modify"_pair_modify.html tail option for adding long-range tail
corrections to energy and pressure, since there are no corrections for
a potential that goes to 0.0 at the cutoff.
All of the GROMACS pair styles write their information to "binary
restart files"_restart.html, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
All of the GROMACS pair styles can only be used via the {pair}
keyword of the "run_style respa"_run_style.html command. They do not
support the {inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Marrink)
[(Marrink)] Marrink, de Vries, Mark, J Phys Chem B, 108, 750-760 (2004).
diff --git a/doc/pair_hbond_dreiding.html b/doc/pair_hbond_dreiding.html
index d412af1ef..32c2e16e1 100644
--- a/doc/pair_hbond_dreiding.html
+++ b/doc/pair_hbond_dreiding.html
@@ -1,235 +1,235 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style hbond/dreiding/lj command
</H3>
<H3>pair_style hbond/dreiding/lj/omp command
</H3>
<H3>pair_style hbond/dreiding/morse command
</H3>
<H3>pair_style hbond/dreiding/morse/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style N inner_distance_cutoff outer_distance_cutoff angle_cutof
</PRE>
<UL><LI>style = <I>hbond/dreiding/lj</I> or <I>hbond/dreiding/morse</I>
<LI>n = cosine angle periodicity
<LI>inner_distance_cutoff = global inner spline cutoff for Donor-Acceptor interactions (distance units)
<LI>outer_distance_cutoff = global cutoff for Donor-Acceptor interactions (distance units)
<LI>angle_cutoff = global angle cutoff for Acceptor-Hydrogen-Donor
<LI>interactions (degrees)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style hbond/dreiding/lj 4 4.5 5.0 90
pair_coeff * * 3 i 100.0 3.1
pair_coeff * * 2*5 i 100.0 3.1 2 15.0 20.0 135.0
</PRE>
<PRE>pair_style hbond/dreiding/morse 2 3.0 4.6 75.0
pair_coeff * * 3 j 100.0 1.0 2.0
pair_coeff * * 2*5 j 100.0 1.0 2.0 4.0 6.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>hbond/dreiding</I> styles compute the Acceptor-Hydrogen-Donor (AHD)
3-body hydrogen bond interaction for the
<A HREF = "Section_howto.html#howto_4">DREIDING</A> force field, given by:
</P>
<CENTER><IMG SRC = "Eqs/pair_hbond_dreiding.jpg">
</CENTER>
<P>where Rin is the inner spline distance cutoff, Rout is the outer
distance cutoff, theta_c is the angle cutoff, and n is the cosine
periodicity.
</P>
<P>Here, <I>r</I> is the radial distance between the donor (D) and acceptor
(A) atoms and <I>theta</I> is the bond angle between the acceptor, the
hydrogen (H) and the donor atoms:
</P>
<CENTER><IMG SRC = "Eqs/dreiding_hbond.jpg">
</CENTER>
<P>These 3-body interactions can be defined for pairs of acceptor and
donor atoms, based on atom types. For each donor/acceptor atom pair,
the 3rd atom in the interaction is a hydrogen permanently bonded to
the donor atom, e.g. in a bond list read in from a data file via the
<A HREF = "read_data.html">read_data</A> command. The atom types of possible
hydrogen atoms for each donor/acceptor type pair are specified by the
<A HREF = "pair_coeff.html">pair_coeff</A> command (see below).
</P>
<P>Style <I>hbond/dreiding/lj</I> is the original DREIDING potential of
<A HREF = "#Mayo">(Mayo)</A>. It uses a LJ 12/10 functional for the Donor-Acceptor
interactions. To match the results in the original paper, use n = 4.
</P>
<P>Style <I>hbond/dreiding/morse</I> is an improved version using a Morse
potential for the Donor-Acceptor interactions. <A HREF = "#Liu">(Liu)</A> showed
that the Morse form gives improved results for Dendrimer simulations,
when n = 2.
</P>
<P>See this <A HREF = "Section_howto.html#howto_4">howto section</A> of the manual for
more information on the DREIDING forcefield.
</P>
<P>Because the Dreiding hydrogen bond potential is only one portion of
an overall force field which typically includes other pairwise
interactions, it is common to use it as a sub-style in a <A HREF = "pair_hybrid.html">pair_style
hybrid or hybrid/overlay</A> command.
</P>
<P>The following coefficients must be defined for pairs of eligible
donor/acceptor types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as
in the examples above.
</P>
<P>IMPORTANT NOTE: Unlike other pair styles and their associated
<A HREF = "pair_coeff.html">pair_coeff</A> commands, you do not need to specify
pair_coeff settings for all possible I,J type pairs. Only I,J type
pairs for atoms which act as joint donors/acceptors need to be
specified; all other type pairs are assumed to be inactive.
</P>
<P>IMPORTANT NOTE: A <A HREF = "pair_coeff.html">pair_coeff</A> command can be
speficied multiple times for the same donor/acceptor type pair. This
enables multiple hydrogen types to be assigned to the same
donor/acceptor type pair. For other pair_styles, if the pair_coeff
command is re-used for the same I.J type pair, the settings for that
type pair are overwritten. For the hydrogen bond potentials this is
not the case; the settings are cummulative. This means the only way
to turn off a previous setting, is to re-use the pair_style command
and start over.
</P>
<P>For the <I>hbond/dreiding/lj</I> style the list of coefficients is as
follows:
</P>
<UL><LI>K = hydrogen atom type = 1 to Ntypes
<LI>donor flag = <I>i</I> or <I>j</I>
<LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>n = exponent in formula above
<LI>distance cutoff (distance units)
<LI>angle cutoff (degrees)
</UL>
<P>For the <I>hbond/dreiding/morse</I> style the list of coefficients is as
follows:
</P>
<UL><LI>K = hydrogen atom type = 1 to Ntypes
<LI>donor flag = <I>i</I> or <I>j</I>
<LI>D0 (energy units)
<LI>alpha (1/distance units)
<LI>r0 (distance units)
<LI>n = exponent in formula above
<LI>distance cutoff (distance units)
<LI>angle cutoff (degrees)
</UL>
<P>A single hydrogen atom type K can be specified, or a wild-card
asterisk can be used in place of or in conjunction with the K
arguments to select multiple types as hydrogens. This takes the form
"*" or "*n" or "n*" or "m*n". See the <A HREF = "pair_coeff">pair_coeff</A> command
doc page for details.
</P>
<P>If the donor flag is <I>i</I>, then the atom of type I in the pair_coeff
command is treated as the donor, and J is the acceptor. If the donor
flag is <I>j</I>, then the atom of type J in the pair_coeff command is
treated as the donor and I is the donor. This option is required
because the <A HREF = "pair_coeff.html">pair_coeff</A> command requires that I <= J.
</P>
<P>Epsilon and sigma are settings for the hydrogen bond potential based
on a Lennard-Jones functional form. Note that sigma is defined as the
zero-crossing distance for the potential, not as the energy minimum at
2^(1/6) sigma.
</P>
<P>D0 and alpha and r0 are settings for the hydrogen bond potential based
on a Morse functional form.
</P>
<P>The last 3 coefficients for both styles are optional. If not
specified, the global n, distance cutoff, and angle cutoff specified
in the pair_style command are used. If you wish to only override the
2nd or 3rd optional parameter, you must also specify the preceding
optional parameters.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support mixing. You must explicitly identify
each donor/acceptor type pair.
</P>
<P>These styles do not support the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the interactions.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant for
these pair styles.
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>These pair styles do not write their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands need to be
re-specified in an input script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P>These pair styles tally a count of how many hydrogen bonding
interactions they calculate each timestep and the hbond energy. These
quantities can be accessed via the <A HREF = "compute_pair.html">compute pair</A>
command as a vector of values of length 2.
</P>
<P>To print these quantities to the log file (with a descriptive column
heading) the following commands could be included in an input script:
</P>
<PRE>compute hb all pair hbond/dreiding/lj
variable n_hbond equal c_hb[1] #number hbonds
variable E_hbond equal c_hb[2] #hbond energy
thermo_style custom step temp epair v_E_hbond
</PRE>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Mayo"></A>
<P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
</P>
<A NAME = "Liu"></A>
<P><B>(Liu)</B> Liu, Bryantsev, Diallo, Goddard III, J. Am. Chem. Soc 131 (8)
2798 (2009)
</P>
</HTML>
diff --git a/doc/pair_hbond_dreiding.txt b/doc/pair_hbond_dreiding.txt
index afc469a4a..1b0361fc1 100644
--- a/doc/pair_hbond_dreiding.txt
+++ b/doc/pair_hbond_dreiding.txt
@@ -1,225 +1,225 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style hbond/dreiding/lj command :h3
pair_style hbond/dreiding/lj/omp command :h3
pair_style hbond/dreiding/morse command :h3
pair_style hbond/dreiding/morse/omp command :h3
[Syntax:]
pair_style style N inner_distance_cutoff outer_distance_cutoff angle_cutof :pre
style = {hbond/dreiding/lj} or {hbond/dreiding/morse}
n = cosine angle periodicity
inner_distance_cutoff = global inner spline cutoff for Donor-Acceptor interactions (distance units)
outer_distance_cutoff = global cutoff for Donor-Acceptor interactions (distance units)
angle_cutoff = global angle cutoff for Acceptor-Hydrogen-Donor
interactions (degrees) :ul
[Examples:]
pair_style hbond/dreiding/lj 4 4.5 5.0 90
pair_coeff * * 3 i 100.0 3.1
pair_coeff * * 2*5 i 100.0 3.1 2 15.0 20.0 135.0 :pre
pair_style hbond/dreiding/morse 2 3.0 4.6 75.0
pair_coeff * * 3 j 100.0 1.0 2.0
pair_coeff * * 2*5 j 100.0 1.0 2.0 4.0 6.0 :pre
[Description:]
The {hbond/dreiding} styles compute the Acceptor-Hydrogen-Donor (AHD)
3-body hydrogen bond interaction for the
"DREIDING"_Section_howto.html#howto_4 force field, given by:
:c,image(Eqs/pair_hbond_dreiding.jpg)
where Rin is the inner spline distance cutoff, Rout is the outer
distance cutoff, theta_c is the angle cutoff, and n is the cosine
periodicity.
Here, {r} is the radial distance between the donor (D) and acceptor
(A) atoms and {theta} is the bond angle between the acceptor, the
hydrogen (H) and the donor atoms:
:c,image(Eqs/dreiding_hbond.jpg)
These 3-body interactions can be defined for pairs of acceptor and
donor atoms, based on atom types. For each donor/acceptor atom pair,
the 3rd atom in the interaction is a hydrogen permanently bonded to
the donor atom, e.g. in a bond list read in from a data file via the
"read_data"_read_data.html command. The atom types of possible
hydrogen atoms for each donor/acceptor type pair are specified by the
"pair_coeff"_pair_coeff.html command (see below).
Style {hbond/dreiding/lj} is the original DREIDING potential of
"(Mayo)"_#Mayo. It uses a LJ 12/10 functional for the Donor-Acceptor
interactions. To match the results in the original paper, use n = 4.
Style {hbond/dreiding/morse} is an improved version using a Morse
potential for the Donor-Acceptor interactions. "(Liu)"_#Liu showed
that the Morse form gives improved results for Dendrimer simulations,
when n = 2.
See this "howto section"_Section_howto.html#howto_4 of the manual for
more information on the DREIDING forcefield.
Because the Dreiding hydrogen bond potential is only one portion of
an overall force field which typically includes other pairwise
interactions, it is common to use it as a sub-style in a "pair_style
hybrid or hybrid/overlay"_pair_hybrid.html command.
The following coefficients must be defined for pairs of eligible
donor/acceptor types via the "pair_coeff"_pair_coeff.html command as
in the examples above.
IMPORTANT NOTE: Unlike other pair styles and their associated
"pair_coeff"_pair_coeff.html commands, you do not need to specify
pair_coeff settings for all possible I,J type pairs. Only I,J type
pairs for atoms which act as joint donors/acceptors need to be
specified; all other type pairs are assumed to be inactive.
IMPORTANT NOTE: A "pair_coeff"_pair_coeff.html command can be
speficied multiple times for the same donor/acceptor type pair. This
enables multiple hydrogen types to be assigned to the same
donor/acceptor type pair. For other pair_styles, if the pair_coeff
command is re-used for the same I.J type pair, the settings for that
type pair are overwritten. For the hydrogen bond potentials this is
not the case; the settings are cummulative. This means the only way
to turn off a previous setting, is to re-use the pair_style command
and start over.
For the {hbond/dreiding/lj} style the list of coefficients is as
follows:
K = hydrogen atom type = 1 to Ntypes
donor flag = {i} or {j}
epsilon (energy units)
sigma (distance units)
n = exponent in formula above
distance cutoff (distance units)
angle cutoff (degrees) :ul
For the {hbond/dreiding/morse} style the list of coefficients is as
follows:
K = hydrogen atom type = 1 to Ntypes
donor flag = {i} or {j}
D0 (energy units)
alpha (1/distance units)
r0 (distance units)
n = exponent in formula above
distance cutoff (distance units)
angle cutoff (degrees) :ul
A single hydrogen atom type K can be specified, or a wild-card
asterisk can be used in place of or in conjunction with the K
arguments to select multiple types as hydrogens. This takes the form
"*" or "*n" or "n*" or "m*n". See the "pair_coeff"_pair_coeff command
doc page for details.
If the donor flag is {i}, then the atom of type I in the pair_coeff
command is treated as the donor, and J is the acceptor. If the donor
flag is {j}, then the atom of type J in the pair_coeff command is
treated as the donor and I is the donor. This option is required
because the "pair_coeff"_pair_coeff.html command requires that I <= J.
Epsilon and sigma are settings for the hydrogen bond potential based
on a Lennard-Jones functional form. Note that sigma is defined as the
zero-crossing distance for the potential, not as the energy minimum at
2^(1/6) sigma.
D0 and alpha and r0 are settings for the hydrogen bond potential based
on a Morse functional form.
The last 3 coefficients for both styles are optional. If not
specified, the global n, distance cutoff, and angle cutoff specified
in the pair_style command are used. If you wish to only override the
2nd or 3rd optional parameter, you must also specify the preceding
optional parameters.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support mixing. You must explicitly identify
each donor/acceptor type pair.
These styles do not support the "pair_modify"_pair_modify.html shift
option for the energy of the interactions.
The "pair_modify"_pair_modify.html table option is not relevant for
these pair styles.
These pair styles do not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
These pair styles do not write their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands need to be
re-specified in an input script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
These pair styles tally a count of how many hydrogen bonding
interactions they calculate each timestep and the hbond energy. These
quantities can be accessed via the "compute pair"_compute_pair.html
command as a vector of values of length 2.
To print these quantities to the log file (with a descriptive column
heading) the following commands could be included in an input script:
compute hb all pair hbond/dreiding/lj
variable n_hbond equal c_hb\[1\] #number hbonds
variable E_hbond equal c_hb\[2\] #hbond energy
thermo_style custom step temp epair v_E_hbond :pre
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Mayo)
[(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
(1990).
:link(Liu)
[(Liu)] Liu, Bryantsev, Diallo, Goddard III, J. Am. Chem. Soc 131 (8)
2798 (2009)
diff --git a/doc/pair_hybrid.html b/doc/pair_hybrid.html
index 7fcba348d..7c729a727 100644
--- a/doc/pair_hybrid.html
+++ b/doc/pair_hybrid.html
@@ -1,293 +1,294 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style hybrid command
</H3>
<H3>pair_style hybrid/omp command
</H3>
<H3>pair_style hybrid/overlay command
</H3>
<H3>pair_style hybrid/overlay/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style hybrid style1 args style2 args ...
pair_style hybrid/overlay style1 args style2 args ...
</PRE>
<UL><LI>style1,style2 = list of one or more pair styles and their arguments
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style hybrid lj/cut/coul/cut 10.0 eam lj/cut 5.0
pair_coeff 1*2 1*2 eam niu3
pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0
pair_coeff 1*2 3 lj/cut 0.5 1.2
</PRE>
<PRE>pair_style hybrid/overlay lj/cut 2.5 coul/long 2.0
pair_coeff * * lj/cut 1.0 1.0
pair_coeff * * coul/long
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>hybrid</I> and <I>hybrid/overlay</I> styles enable the use of multiple
pair styles in one simulation. With the <I>hybrid</I> style, exactly one
pair style is assigned to each pair of atom types. With the
<I>hybrid/overlay</I> style, one or more pair styles can be assigned to
each pair of atom types. The assignment of pair styles to type pairs
is made via the <A HREF = "pair_coeff.html">pair_coeff</A> command.
</P>
<P>Here are two examples of hybrid simulations. The <I>hybrid</I> style could
be used for a simulation of a metal droplet on a LJ surface. The
metal atoms interact with each other via an <I>eam</I> potential, the
surface atoms interact with each other via a <I>lj/cut</I> potential, and
the metal/surface interaction is also computed via a <I>lj/cut</I>
potential. The <I>hybrid/overlay</I> style could be used as in the 2nd
example above, where multiple potentials are superposed in an additive
fashion to compute the interaction between atoms. In this example,
using <I>lj/cut</I> and <I>coul/long</I> together gives the same result as if
the <I>lj/cut/coul/long</I> potential were used by itself. In this case,
it would be more efficient to use the single combined potential, but
in general any combination of pair potentials can be used together in
to produce an interaction that is not encoded in any single pair_style
file, e.g. adding Coulombic forces between granular particles.
</P>
<P>All pair styles that will be used are listed as "sub-styles" following
the <I>hybrid</I> or <I>hybrid/overlay</I> keyword, in any order. Each
sub-style's name is followed by its usual arguments, as illustrated in
the example above. See the doc pages of individual pair styles for a
listing and explanation of the appropriate arguments.
</P>
<P>In the pair_coeff commands, the name of a pair style must be added
after the I,J type specification, with the remaining coefficients
being those appropriate to that style. For example, consider a
simulation with 3 atom types: types 1 and 2 are Ni atoms, type 3 are
LJ atoms with charges. The following commands would set up a hybrid
simulation:
</P>
<PRE>pair_style hybrid eam/alloy lj/cut/coul/cut 10.0 lj/cut 8.0
pair_coeff * * eam/alloy nialhjea Ni Ni NULL
pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0
pair_coeff 1*2 3 lj/cut 0.8 1.3
</PRE>
<P>If pair coefficients are specified in the data file read via the
<A HREF = "read_data.html">read_data</A> command, then the same rule applies.
E.g. "eam/alloy" or "lj/cut" must be added after the atom type, for
each line in the "Pair Coeffs" section, e.g.
</P>
<PRE>Pair Coeffs
</PRE>
<PRE>1 lj/cut/coul/cut 1.0 1.0
...
</PRE>
<P>Note that the pair_coeff command for some potentials such as
<A HREF = "pair_eam.html">pair_style eam/alloy</A> includes a mapping specification
of elements to all atom types, which in the hybrid case, can include
atom types not assigned to the <I>eam/alloy</I> potential. The NULL
keyword is used by many such potentials (eam/alloy, Tersoff, AIREBO,
etc), to denote an atom type that will be assigned to a different
sub-style.
</P>
<P>For the <I>hybrid</I> style, each atom type pair I,J is assigned to exactly
one sub-style. Just as with a simulation using a single pair style,
if you specify the same atom type pair in a second pair_coeff command,
the previous assignment will be overwritten.
</P>
<P>For the <I>hybrid/overlay</I> style, each atom type pair I,J can be
assigned to one or more sub-styles. If you specify the same atom type
pair in a second pair_coeff command with a new sub-style, then the
second sub-style is added to the list of potentials that will be
calculated for two interacting atoms of those types. If you specify
the same atom type pair in a second pair_coeff command with a
sub-style that has already been defined for that pair of atoms, then
the new pair coefficients simply override the previous ones, as in the
normal usage of the pair_coeff command. E.g. these two sets of
commands are the same:
</P>
<PRE>pair_style lj/cut 2.5
pair_coeff * * 1.0 1.0
pair_coeff 2 2 1.5 0.8
</PRE>
<PRE>pair_style hybrid/overlay lj/cut 2.5
pair_coeff * * lj/cut 1.0 1.0
pair_coeff 2 2 lj/cut 1.5 0.8
</PRE>
<P>Coefficients must be defined for each pair of atoms types via the
<A HREF = "pair_coeff.html">pair_coeff</A> command as described above, or in the
data file or restart files read by the <A HREF = "read_data.html">read_data</A> or
<A HREF = "read_restart.html">read_restart</A> commands, or by mixing as described
below.
</P>
<P>For both the <I>hybrid</I> and <I>hybrid/overlay</I> styles, every atom type
pair I,J (where I <= J) must be assigned to at least one sub-style via
the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples above, or
in the data file read by the <A HREF = "read_data.html">read_data</A>, or by mixing
as described below.
</P>
<P>If you want there to be no interactions between a particular pair of
atom types, you have 3 choices. You can assign the type pair to some
sub-style and use the <A HREF = "neigh_modify.html">neigh_modify exclude type</A>
command. You can assign it to some sub-style and set the coefficients
so that there is effectively no interaction (e.g. epsilon = 0.0 in a
LJ potential). Or, for <I>hybrid</I> and <I>hybrid/overlay</I> simulations, you
can use this form of the pair_coeff command in your input script:
</P>
<PRE>pair_coeff 2 3 none
</PRE>
<P>or this form in the "Pair Coeffs" section of the data file:
</P>
<PRE>3 none
</PRE>
<P>If an assignment to <I>none</I> is made in a simulation with the
<I>hybrid/overlay</I> pair style, it wipes out all previous assignments of
that atom type pair to sub-styles.
</P>
<P>Note that you may need to use an <A HREF = "atom_style.html">atom_style</A> hybrid
command in your input script, if atoms in the simulation will need
attributes from several atom styles, due to using multiple pair
potentials.
</P>
<HR>
<P>The potential energy contribution to the overall system due to an
individual sub-style can be accessed and output via the <A HREF = "compute_pair.html">compute
pair</A> command.
</P>
<HR>
<P>IMPORTANT: Several of the potentials defined via the pair_style
command in LAMMPS are really many-body potentials, such as Tersoff,
AIREBO, MEAM, ReaxFF, etc. The way to think about using these
potentials in a hybrid setting is as follows.
</P>
<P>A subset of atom types is assigned to the many-body potential with a
single <A HREF = "pair_coeff.html">pair_coeff</A> command, using "* *" to include
all types and the NULL keywords described above to exclude specific
types not assigned to that potential. If types 1,3,4 were assigned in
that way (but not type 2), this means that all many-body interactions
between all atoms of types 1,3,4 will be computed by that potential.
Pair_style hybrid allows interactions between type pairs 2-2, 1-2,
2-3, 2-4 to be specified for computation by other pair styles. You
could even add a second interaction for 1-1 to be computed by another
pair style, assuming pair_style hybrid/overlay is used.
</P>
<P>But you should not, as a general rule, attempt to exclude the
many-body interactions for some subset of the type pairs within the
set of 1,3,4 interactions, e.g. exclude 1-1 or 1-3 interactions. That
is not conceptually well-defined for many-body interactions, since the
potential will typically calculate energies and foces for small groups
of atoms, e.g. 3 or 4 atoms, using the neighbor lists of the atoms to
find the additional atoms in the group. It is typically non-physical
to think of excluding an interaction between a particular pair of
atoms when the potential computes 3-body or 4-body interactions.
</P>
<P>However, you can still use the pair_coeff none setting or the
<A HREF = "neigh_modify.html">neigh_modify exclude</A> command to exclude certain
type pairs from the neighbor list that will be passed to a manybody
sub-style. This will alter the calculations made by a many-body
potential, since it builds its list of 3-body, 4-body, etc
interactions from the pair list. You will need to think carefully as
to whether it produces a physically meaningful result for your model.
</P>
<P>For example, imagine you have two atom types in your model, type 1 for
atoms in one surface, and type 2 for atoms in the other, and you wish
to use a Tersoff potential to compute interactions within each
surface, but not between surfaces. Then either of these two command
sequences would implement that model:
</P>
<PRE>pair_style hybrid tersoff
pair_coeff * * tersoff SiC.tersoff C C
pair_coeff 1 2 none
</PRE>
<PRE>pair_style tersoff
pair_coeff * * SiC.tersoff C C
neigh_modify exclude type 1 2
</PRE>
<P>Either way, only neighbor lists with 1-1 or 2-2 interactions would be
passed to the Tersoff potential, which means it would compute no
3-body interactions containing both type 1 and 2 atoms.
</P>
<HR>
<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual.
</P>
<P>Since the <I>hybrid</I> and <I>hybrid/overlay</I> styles delegate computation
to the individual sub-styles, the suffix versions of the <I>hybrid</I>
and <I>hybrid/overlay</I> styles are used to propagate the corresponding
suffix to all sub-styles, if those versions exist. Otherwise the
non-accelerated version will be used.
</P>
<P>The individual accelerated sub-styles are part of the USER-CUDA, GPU,
USER-OMP and OPT packages, respectively. They are only enabled if
LAMMPS was built with those packages. See the
<A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>Any pair potential settings made via the
<A HREF = "pair_modify.html">pair_modify</A> command are passed along to all
sub-styles of the hybrid potential.
</P>
<P>For atom type pairs I,J and I != J, if the sub-style assigned to I,I
and J,J is the same, and if the sub-style allows for mixing, then the
coefficients for I,J can be mixed. This means you do not have to
specify a pair_coeff command for I,J since the I,J type pair will be
assigned automatically to the I,I sub-style and its coefficients
generated by the mixing rule used by that sub-style. For the
<I>hybrid/overlay</I> style, there is an additional requirement that both
the I,I and J,J pairs are assigned to a single sub-style. See the
"pair_modify" command for details of mixing rules. See the See the
doc page for the sub-style to see if allows for mixing.
</P>
<P>The hybrid pair styles supports the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options for an I,J pair interaction, if the
associated sub-style supports it.
</P>
<P>For the hybrid pair styles, the list of sub-styles and their
respective settings are written to <A HREF = "restart.html">binary restart
files</A>, so a <A HREF = "pair_style.html">pair_style</A> command does
not need to specified in an input script that reads a restart file.
However, the coefficient information is not stored in the restart
file. Thus, pair_coeff commands need to be re-specified in the
restart input script.
</P>
<P>These pair styles support the use of the <I>inner</I>, <I>middle</I>, and
<I>outer</I> keywords of the <A HREF = "run_style.html">run_style respa</A> command, if
their sub-styles do.
</P>
<P><B>Restrictions:</B>
</P>
<P>When using a long-range Coulombic solver (via the
<A HREF = "kspace_style.html">kspace_style</A> command) with a hybrid pair_style,
one or more sub-styles will be of the "long" variety,
e.g. <I>lj/cut/coul/long</I> or <I>buck/coul/long</I>. You must insure that the
short-range Coulombic cutoff used by each of these long pair styles is
the same or else LAMMPS will generate an error.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_hybrid.txt b/doc/pair_hybrid.txt
index b93fe360d..2828fc21b 100644
--- a/doc/pair_hybrid.txt
+++ b/doc/pair_hybrid.txt
@@ -1,285 +1,286 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style hybrid command :h3
pair_style hybrid/omp command :h3
pair_style hybrid/overlay command :h3
pair_style hybrid/overlay/omp command :h3
[Syntax:]
pair_style hybrid style1 args style2 args ...
pair_style hybrid/overlay style1 args style2 args ... :pre
style1,style2 = list of one or more pair styles and their arguments :ul
[Examples:]
pair_style hybrid lj/cut/coul/cut 10.0 eam lj/cut 5.0
pair_coeff 1*2 1*2 eam niu3
pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0
pair_coeff 1*2 3 lj/cut 0.5 1.2 :pre
pair_style hybrid/overlay lj/cut 2.5 coul/long 2.0
pair_coeff * * lj/cut 1.0 1.0
pair_coeff * * coul/long :pre
[Description:]
The {hybrid} and {hybrid/overlay} styles enable the use of multiple
pair styles in one simulation. With the {hybrid} style, exactly one
pair style is assigned to each pair of atom types. With the
{hybrid/overlay} style, one or more pair styles can be assigned to
each pair of atom types. The assignment of pair styles to type pairs
is made via the "pair_coeff"_pair_coeff.html command.
Here are two examples of hybrid simulations. The {hybrid} style could
be used for a simulation of a metal droplet on a LJ surface. The
metal atoms interact with each other via an {eam} potential, the
surface atoms interact with each other via a {lj/cut} potential, and
the metal/surface interaction is also computed via a {lj/cut}
potential. The {hybrid/overlay} style could be used as in the 2nd
example above, where multiple potentials are superposed in an additive
fashion to compute the interaction between atoms. In this example,
using {lj/cut} and {coul/long} together gives the same result as if
the {lj/cut/coul/long} potential were used by itself. In this case,
it would be more efficient to use the single combined potential, but
in general any combination of pair potentials can be used together in
to produce an interaction that is not encoded in any single pair_style
file, e.g. adding Coulombic forces between granular particles.
All pair styles that will be used are listed as "sub-styles" following
the {hybrid} or {hybrid/overlay} keyword, in any order. Each
sub-style's name is followed by its usual arguments, as illustrated in
the example above. See the doc pages of individual pair styles for a
listing and explanation of the appropriate arguments.
In the pair_coeff commands, the name of a pair style must be added
after the I,J type specification, with the remaining coefficients
being those appropriate to that style. For example, consider a
simulation with 3 atom types: types 1 and 2 are Ni atoms, type 3 are
LJ atoms with charges. The following commands would set up a hybrid
simulation:
pair_style hybrid eam/alloy lj/cut/coul/cut 10.0 lj/cut 8.0
pair_coeff * * eam/alloy nialhjea Ni Ni NULL
pair_coeff 3 3 lj/cut/coul/cut 1.0 1.0
pair_coeff 1*2 3 lj/cut 0.8 1.3 :pre
If pair coefficients are specified in the data file read via the
"read_data"_read_data.html command, then the same rule applies.
E.g. "eam/alloy" or "lj/cut" must be added after the atom type, for
each line in the "Pair Coeffs" section, e.g.
Pair Coeffs :pre
1 lj/cut/coul/cut 1.0 1.0
... :pre
Note that the pair_coeff command for some potentials such as
"pair_style eam/alloy"_pair_eam.html includes a mapping specification
of elements to all atom types, which in the hybrid case, can include
atom types not assigned to the {eam/alloy} potential. The NULL
keyword is used by many such potentials (eam/alloy, Tersoff, AIREBO,
etc), to denote an atom type that will be assigned to a different
sub-style.
For the {hybrid} style, each atom type pair I,J is assigned to exactly
one sub-style. Just as with a simulation using a single pair style,
if you specify the same atom type pair in a second pair_coeff command,
the previous assignment will be overwritten.
For the {hybrid/overlay} style, each atom type pair I,J can be
assigned to one or more sub-styles. If you specify the same atom type
pair in a second pair_coeff command with a new sub-style, then the
second sub-style is added to the list of potentials that will be
calculated for two interacting atoms of those types. If you specify
the same atom type pair in a second pair_coeff command with a
sub-style that has already been defined for that pair of atoms, then
the new pair coefficients simply override the previous ones, as in the
normal usage of the pair_coeff command. E.g. these two sets of
commands are the same:
pair_style lj/cut 2.5
pair_coeff * * 1.0 1.0
pair_coeff 2 2 1.5 0.8 :pre
pair_style hybrid/overlay lj/cut 2.5
pair_coeff * * lj/cut 1.0 1.0
pair_coeff 2 2 lj/cut 1.5 0.8 :pre
Coefficients must be defined for each pair of atoms types via the
"pair_coeff"_pair_coeff.html command as described above, or in the
data file or restart files read by the "read_data"_read_data.html or
"read_restart"_read_restart.html commands, or by mixing as described
below.
For both the {hybrid} and {hybrid/overlay} styles, every atom type
pair I,J (where I <= J) must be assigned to at least one sub-style via
the "pair_coeff"_pair_coeff.html command as in the examples above, or
in the data file read by the "read_data"_read_data.html, or by mixing
as described below.
If you want there to be no interactions between a particular pair of
atom types, you have 3 choices. You can assign the type pair to some
sub-style and use the "neigh_modify exclude type"_neigh_modify.html
command. You can assign it to some sub-style and set the coefficients
so that there is effectively no interaction (e.g. epsilon = 0.0 in a
LJ potential). Or, for {hybrid} and {hybrid/overlay} simulations, you
can use this form of the pair_coeff command in your input script:
pair_coeff 2 3 none :pre
or this form in the "Pair Coeffs" section of the data file:
3 none :pre
If an assignment to {none} is made in a simulation with the
{hybrid/overlay} pair style, it wipes out all previous assignments of
that atom type pair to sub-styles.
Note that you may need to use an "atom_style"_atom_style.html hybrid
command in your input script, if atoms in the simulation will need
attributes from several atom styles, due to using multiple pair
potentials.
:line
The potential energy contribution to the overall system due to an
individual sub-style can be accessed and output via the "compute
pair"_compute_pair.html command.
:line
IMPORTANT: Several of the potentials defined via the pair_style
command in LAMMPS are really many-body potentials, such as Tersoff,
AIREBO, MEAM, ReaxFF, etc. The way to think about using these
potentials in a hybrid setting is as follows.
A subset of atom types is assigned to the many-body potential with a
single "pair_coeff"_pair_coeff.html command, using "* *" to include
all types and the NULL keywords described above to exclude specific
types not assigned to that potential. If types 1,3,4 were assigned in
that way (but not type 2), this means that all many-body interactions
between all atoms of types 1,3,4 will be computed by that potential.
Pair_style hybrid allows interactions between type pairs 2-2, 1-2,
2-3, 2-4 to be specified for computation by other pair styles. You
could even add a second interaction for 1-1 to be computed by another
pair style, assuming pair_style hybrid/overlay is used.
But you should not, as a general rule, attempt to exclude the
many-body interactions for some subset of the type pairs within the
set of 1,3,4 interactions, e.g. exclude 1-1 or 1-3 interactions. That
is not conceptually well-defined for many-body interactions, since the
potential will typically calculate energies and foces for small groups
of atoms, e.g. 3 or 4 atoms, using the neighbor lists of the atoms to
find the additional atoms in the group. It is typically non-physical
to think of excluding an interaction between a particular pair of
atoms when the potential computes 3-body or 4-body interactions.
However, you can still use the pair_coeff none setting or the
"neigh_modify exclude"_neigh_modify.html command to exclude certain
type pairs from the neighbor list that will be passed to a manybody
sub-style. This will alter the calculations made by a many-body
potential, since it builds its list of 3-body, 4-body, etc
interactions from the pair list. You will need to think carefully as
to whether it produces a physically meaningful result for your model.
For example, imagine you have two atom types in your model, type 1 for
atoms in one surface, and type 2 for atoms in the other, and you wish
to use a Tersoff potential to compute interactions within each
surface, but not between surfaces. Then either of these two command
sequences would implement that model:
pair_style hybrid tersoff
pair_coeff * * tersoff SiC.tersoff C C
pair_coeff 1 2 none :pre
pair_style tersoff
pair_coeff * * SiC.tersoff C C
neigh_modify exclude type 1 2 :pre
Either way, only neighbor lists with 1-1 or 2-2 interactions would be
passed to the Tersoff potential, which means it would compute no
3-body interactions containing both type 1 and 2 atoms.
:line
Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual.
Since the {hybrid} and {hybrid/overlay} styles delegate computation
to the individual sub-styles, the suffix versions of the {hybrid}
and {hybrid/overlay} styles are used to propagate the corresponding
suffix to all sub-styles, if those versions exist. Otherwise the
non-accelerated version will be used.
The individual accelerated sub-styles are part of the USER-CUDA, GPU,
USER-OMP and OPT packages, respectively. They are only enabled if
LAMMPS was built with those packages. See the
"Making LAMMPS"_Section_start.html#start_3 section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
Any pair potential settings made via the
"pair_modify"_pair_modify.html command are passed along to all
sub-styles of the hybrid potential.
For atom type pairs I,J and I != J, if the sub-style assigned to I,I
and J,J is the same, and if the sub-style allows for mixing, then the
coefficients for I,J can be mixed. This means you do not have to
specify a pair_coeff command for I,J since the I,J type pair will be
assigned automatically to the I,I sub-style and its coefficients
generated by the mixing rule used by that sub-style. For the
{hybrid/overlay} style, there is an additional requirement that both
the I,I and J,J pairs are assigned to a single sub-style. See the
"pair_modify" command for details of mixing rules. See the See the
doc page for the sub-style to see if allows for mixing.
The hybrid pair styles supports the "pair_modify"_pair_modify.html
shift, table, and tail options for an I,J pair interaction, if the
associated sub-style supports it.
For the hybrid pair styles, the list of sub-styles and their
respective settings are written to "binary restart
files"_restart.html, so a "pair_style"_pair_style.html command does
not need to specified in an input script that reads a restart file.
However, the coefficient information is not stored in the restart
file. Thus, pair_coeff commands need to be re-specified in the
restart input script.
These pair styles support the use of the {inner}, {middle}, and
{outer} keywords of the "run_style respa"_run_style.html command, if
their sub-styles do.
[Restrictions:]
When using a long-range Coulombic solver (via the
"kspace_style"_kspace_style.html command) with a hybrid pair_style,
one or more sub-styles will be of the "long" variety,
e.g. {lj/cut/coul/long} or {buck/coul/long}. You must insure that the
short-range Coulombic cutoff used by each of these long pair styles is
the same or else LAMMPS will generate an error.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_line_lj.html b/doc/pair_line_lj.html
index 125bd41c5..41d106fec 100644
--- a/doc/pair_line_lj.html
+++ b/doc/pair_line_lj.html
@@ -1,117 +1,141 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style line/lj command
</H3>
+<H3>pair_style line/lj/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style line/lj cutoff
</PRE>
<P>cutoff = global cutoff for interactions (distance units)
</P>
<P><B>Examples:</B>
</P>
<PRE>pair_style line/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>line/lj</I> treats particles which are line segments as a set of
small spherical particles that tile the line segment length as
explained below. Interactions between two line segments, each with N1
and N2 spherical particles, are calculated as the pairwise sum of
N1*N2 Lennard-Jones interactions. Interactions between a line segment
with N spherical particles and a point particle are treated as the
pairwise sum of N Lennard-Jones interactions. See the <A HREF = "pair_lj.html">pair_style
lj/cut</A> doc page for the definition of Lennard-Jones
interactions.
</P>
<P>The cutoff distance for an interaction between 2 line segments, or
between a line segment and a point particle, is calculated from the
position of the line segment (its center), not between pairs of
individual spheres comprising the line segment. Thus an interaction
is either calculated in its entirety or not at all.
</P>
<P>The set of non-overlapping spherical particles that represent a line
segment, for purposes of this pair style, are generated in the
following manner. Their size is a function of the line segment length
and the specified sigma for that particle type. If a line segment has
a length L and is of type I, then the number of spheres N that
represent the segment is calculated as N = L/sigma_II, rounded up to
an integer value. Thus if L is not evenly divisibly by sigam_II, N is
incremented to include one extra sphere. In this case, the spheres
must be slightly smaller than sigma_II so as not to overlap, so a new
sigma-prime is chosen as the sphere diameter, such that L/N =
sigma-prime. Thus the line segment interacts with other segments or
point particles as a collection of N spheres of diameter sigma-prime,
evenly spaced along the line segment, so as to exactly cover its
length.
</P>
<P>The LJ interaction between 2 spheres on different line segments of
types I,J is computed with an arithmetic mixing of the sigma values of
the 2 spheres and using the specified epsilon value for I,J atom
types. Note that because the sigma values for line segment spheres is
computed using only sigma_II values, specific to the line segment's
type, this means that any specified sigma_IJ values (for I != J) are
effectively ignored.
</P>
<P>For style <I>line/lj</I>, the following coefficients must be defined for
each pair of atoms types via the <A HREF = "pair_coeff.html">pair_coeff</A> command
as in the examples above, or in the data file or restart files read by
the <A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global cutoff
is used.
</P>
<HR>
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of this pair style can be mixed. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#2_3">Making
LAMMPS</A> section for more info.
</P>
<P>Defining particles to be line segments so they participate in
line/line or line/particle interactions requires the use the
<A HREF = "atom_style.html">atom_style line</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_tri_lj.html">pair_style tri/lj</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_line_lj.txt b/doc/pair_line_lj.txt
index 7f0bad083..cfa4ffe79 100644
--- a/doc/pair_line_lj.txt
+++ b/doc/pair_line_lj.txt
@@ -1,112 +1,135 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style line/lj command :h3
+pair_style line/lj/omp command :h3
[Syntax:]
pair_style line/lj cutoff :pre
cutoff = global cutoff for interactions (distance units)
[Examples:]
pair_style line/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5 :pre
[Description:]
Style {line/lj} treats particles which are line segments as a set of
small spherical particles that tile the line segment length as
explained below. Interactions between two line segments, each with N1
and N2 spherical particles, are calculated as the pairwise sum of
N1*N2 Lennard-Jones interactions. Interactions between a line segment
with N spherical particles and a point particle are treated as the
pairwise sum of N Lennard-Jones interactions. See the "pair_style
lj/cut"_pair_lj.html doc page for the definition of Lennard-Jones
interactions.
The cutoff distance for an interaction between 2 line segments, or
between a line segment and a point particle, is calculated from the
position of the line segment (its center), not between pairs of
individual spheres comprising the line segment. Thus an interaction
is either calculated in its entirety or not at all.
The set of non-overlapping spherical particles that represent a line
segment, for purposes of this pair style, are generated in the
following manner. Their size is a function of the line segment length
and the specified sigma for that particle type. If a line segment has
a length L and is of type I, then the number of spheres N that
represent the segment is calculated as N = L/sigma_II, rounded up to
an integer value. Thus if L is not evenly divisibly by sigam_II, N is
incremented to include one extra sphere. In this case, the spheres
must be slightly smaller than sigma_II so as not to overlap, so a new
sigma-prime is chosen as the sphere diameter, such that L/N =
sigma-prime. Thus the line segment interacts with other segments or
point particles as a collection of N spheres of diameter sigma-prime,
evenly spaced along the line segment, so as to exactly cover its
length.
The LJ interaction between 2 spheres on different line segments of
types I,J is computed with an arithmetic mixing of the sigma values of
the 2 spheres and using the specified epsilon value for I,J atom
types. Note that because the sigma values for line segment spheres is
computed using only sigma_II values, specific to the line segment's
type, this means that any specified sigma_IJ values (for I != J) are
effectively ignored.
For style {line/lj}, the following coefficients must be defined for
each pair of atoms types via the "pair_coeff"_pair_coeff.html command
as in the examples above, or in the data file or restart files read by
the "read_data"_read_data.html or "read_restart"_read_restart.html
commands:
epsilon (energy units)
sigma (distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global cutoff
is used.
:line
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of this pair style can be mixed. The
default mix value is {geometric}. See the "pair_modify" command for
details.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#2_3 section for more info.
Defining particles to be line segments so they participate in
line/line or line/particle interactions requires the use the
"atom_style line"_atom_style.html command.
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_style tri/lj"_pair_tri_lj.html
[Default:] none
diff --git a/doc/pair_lj.html b/doc/pair_lj.html
index 760e03f9f..1c480cf25 100644
--- a/doc/pair_lj.html
+++ b/doc/pair_lj.html
@@ -1,267 +1,277 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/cut command
</H3>
<H3>pair_style lj/cut/cuda command
</H3>
<H3>pair_style lj/cut/experimental/cuda command
</H3>
<H3>pair_style lj/cut/gpu command
</H3>
<H3>pair_style lj/cut/opt command
</H3>
<H3>pair_style lj/cut/omp command
</H3>
<H3>pair_style lj/cut/coul/cut command
</H3>
<H3>pair_style lj/cut/coul/cut/cuda command
</H3>
<H3>pair_style lj/cut/coul/cut/gpu command
</H3>
<H3>pair_style lj/cut/coul/cut/omp command
</H3>
<H3>pair_style lj/cut/coul/debye command
</H3>
<H3>pair_style lj/cut/coul/debye/cuda command
</H3>
<H3>pair_style lj/cut/coul/debye/omp command
</H3>
<H3>pair_style lj/cut/coul/long command
</H3>
<H3>pair_style lj/cut/coul/long/cuda command
</H3>
<H3>pair_style lj/cut/coul/long/gpu command
</H3>
<H3>pair_style lj/cut/coul/long/opt command
</H3>
<H3>pair_style lj/cut/coul/long/omp command
</H3>
<H3>pair_style lj/cut/coul/long/tip4p command
</H3>
<H3>pair_style lj/cut/coul/long/tip4p/omp command
</H3>
<H3>pair_style lj/cut/coul/long/tip4p/opt command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = <I>lj/cut</I> or <I>lj/cut/coul/cut</I> or <I>lj/cut/coul/debye</I> or <I>lj/cut/coul/long</I> or <I>lj/cut/coul/long/tip4p</I>
<LI>args = list of arguments for a particular style
</UL>
<PRE> <I>lj/cut</I> args = cutoff
cutoff = global cutoff for Lennard Jones interactions (distance units)
<I>lj/cut/coul/cut</I> args = cutoff (cutoff2)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
<I>lj/cut/coul/debye</I> args = kappa cutoff (cutoff2)
kappa = Debye length (inverse distance units)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
<I>lj/cut/coul/long</I> args = cutoff (cutoff2)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
<I>lj/cut/coul/long/tip4p</I> args = otype htype btype atype qdist cutoff (cutoff2)
otype,htype = atom types for TIP4P O and H
btype,atype = bond and angle types for TIP4P waters
qdist = distance from O atom to massless charge (distance units)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/cut 2.5
pair_coeff * * 1 1
pair_coeff 1 1 1 1.1 2.8
</PRE>
<PRE>pair_style lj/cut/coul/cut 10.0
pair_style lj/cut/coul/cut 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
pair_coeff 1 1 100.0 3.5 9.0 9.0
</PRE>
<PRE>pair_style lj/cut/coul/debye 1.5 3.0
pair_style lj/cut/coul/debye 1.5 2.5 5.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
pair_coeff 1 1 1.0 1.5 2.5 5.0
</PRE>
<PRE>pair_style lj/cut/coul/long 10.0
pair_style lj/cut/coul/long 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
</PRE>
<PRE>pair_style lj/cut/coul/long/tip4p 1 2 7 8 0.3 12.0
pair_style lj/cut/coul/long/tip4p 1 2 7 8 0.3 12.0 10.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/cut</I> styles compute the standard 12/6 Lennard-Jones potential,
given by
</P>
<CENTER><IMG SRC = "Eqs/pair_lj.jpg">
</CENTER>
<P>Rc is the cutoff.
</P>
<P>Style <I>lj/cut/coul/cut</I> adds a Coulombic pairwise interaction given by
</P>
<CENTER><IMG SRC = "Eqs/pair_coulomb.jpg">
</CENTER>
<P>where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, and epsilon is the dielectric constant which can be set
by the <A HREF = "dielectric.html">dielectric</A> command. If one cutoff is
specified in the pair_style command, it is used for both the LJ and
Coulombic terms. If two cutoffs are specified, they are used as
cutoffs for the LJ and Coulombic terms respectively.
</P>
<P>Style <I>lj/cut/coul/debye</I> adds an additional exp() damping factor
to the Coulombic term, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_debye.jpg">
</CENTER>
<P>where kappa is the Debye length. This potential is another way to
mimic the screening effect of a polar solvent.
</P>
<P>Style <I>lj/cut/coul/long</I> computes the same Coulombic interactions as
style <I>lj/cut/coul/cut</I> except that an additional damping factor is
applied to the Coulombic term so it can be used in conjunction with
the <A HREF = "kspace_style.html">kspace_style</A> command and its <I>ewald</I> or <I>pppm</I>
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
</P>
<P>Style <I>lj/cut/coul/long/tip4p</I> implements the TIP4P water model of
<A HREF = "#Jorgensen">(Jorgensen)</A>, which introduces a massless site located a
short distance away from the oxygen atom along the bisector of the HOH
angle. The atomic types of the oxygen and hydrogen atoms, the bond
and angle types for OH and HOH interactions, and the distance to the
massless charge site are specified as pair_style arguments.
</P>
<P>IMPORTANT NOTE: For each TIP4P water molecule in your system, the atom
IDs for the O and 2 H atoms must be consecutive, with the O atom
first. This is to enable LAMMPS to "find" the 2 H atoms associated
with each O atom. For example, if the atom ID of an O atom in a TIP4P
water molecule is 500, then its 2 H atoms must have IDs 501 and 502.
</P>
<P>See the <A HREF = "Section_howto.html#howto_8">howto section</A> for more
information on how to use the TIP4P pair style.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff1 (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
</P>
<P>The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair. You cannot specify 2 cutoffs for style <I>lj/cut</I>, since it
has no Coulombic terms.
</P>
<P>For <I>lj/cut/coul/long</I> and <I>lj/cut/coul/long/tip4p</I> only the LJ cutoff
can be specified since a Coulombic cutoff cannot be specified for an
individual I,J type pair. All type pairs use the same global
Coulombic cutoff specified in the pair_style command.
</P>
+<P>Styles <I>lj/cut/coul/pppm/omp</I> and <I>lj/cut/coul/pppm/tip4p/omp</I>
+are variants of <I>lj/cut/coul/long/omp</I> and <I>lj/cut/coul/long/tip4p/omp</I>
+for use with k-space styles <A HREF = "kspace_style.html"><I>pppm/proxy</I></A> and
+<A HREF = "kspace_style.html"><I>pppm/tip4p/proxy</I></A>, respectively and OpenMP
+multi-threading and will perform the corresponding reciprocal
+space calculation concurrently with the pair calculation
+in a separate thread. For certain parallel setups, this may have
+a performance benefit over performing k-space style and pair style
+separately and one after the other.
+</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is <I>geometric</I>. See the "pair_modify" command
for details.
</P>
<P>All of the lj/cut pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> shift option for the energy of the
Lennard-Jones portion of the pair interaction.
</P>
<P>The <I>lj/cut/coul/long</I> and <I>lj/cut/coul/long/tip4p</I> pair styles
support the <A HREF = "pair_modify.html">pair_modify</A> table option since they can
tabulate the short-range portion of the long-range Coulombic
interaction.
</P>
<P>All of the lj/cut pair styles support the
<A HREF = "pair_modify.html">pair_modify</A> tail option for adding a long-range
tail correction to the energy and pressure for the Lennard-Jones
portion of the pair interaction.
</P>
<P>All of the lj/cut pair styles write their information to <A HREF = "restart.html">binary
restart files</A>, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
</P>
<P>The lj/cut and lj/cut/coul/long pair styles support the use of the
<I>inner</I>, <I>middle</I>, and <I>outer</I> keywords of the <A HREF = "run_style.html">run_style
respa</A> command, meaning the pairwise forces can be
partitioned by distance at different levels of the rRESPA hierarchy.
The other styles only support the <I>pair</I> keyword of run_style respa.
See the <A HREF = "run_style.html">run_style</A> command for details.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>lj/cut/coul/long</I> and <I>lj/cut/coul/long/tip4p</I> styles are part of
the KSPACE package. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info. Note that the KSPACE package is installed by
default.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Jorgensen"></A>
<P><B>(Jorgensen)</B> Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem
Phys, 79, 926 (1983).
</P>
</HTML>
diff --git a/doc/pair_lj.txt b/doc/pair_lj.txt
index 382af5b8a..81fc804af 100644
--- a/doc/pair_lj.txt
+++ b/doc/pair_lj.txt
@@ -1,240 +1,250 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/cut command :h3
pair_style lj/cut/cuda command :h3
pair_style lj/cut/experimental/cuda command :h3
pair_style lj/cut/gpu command :h3
pair_style lj/cut/opt command :h3
pair_style lj/cut/omp command :h3
pair_style lj/cut/coul/cut command :h3
pair_style lj/cut/coul/cut/cuda command :h3
pair_style lj/cut/coul/cut/gpu command :h3
pair_style lj/cut/coul/cut/omp command :h3
pair_style lj/cut/coul/debye command :h3
pair_style lj/cut/coul/debye/cuda command :h3
pair_style lj/cut/coul/debye/omp command :h3
pair_style lj/cut/coul/long command :h3
pair_style lj/cut/coul/long/cuda command :h3
pair_style lj/cut/coul/long/gpu command :h3
pair_style lj/cut/coul/long/opt command :h3
pair_style lj/cut/coul/long/omp command :h3
pair_style lj/cut/coul/long/tip4p command :h3
pair_style lj/cut/coul/long/tip4p/omp command :h3
pair_style lj/cut/coul/long/tip4p/opt command :h3
[Syntax:]
pair_style style args :pre
style = {lj/cut} or {lj/cut/coul/cut} or {lj/cut/coul/debye} or {lj/cut/coul/long} or {lj/cut/coul/long/tip4p}
args = list of arguments for a particular style :ul
{lj/cut} args = cutoff
cutoff = global cutoff for Lennard Jones interactions (distance units)
{lj/cut/coul/cut} args = cutoff (cutoff2)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
{lj/cut/coul/debye} args = kappa cutoff (cutoff2)
kappa = Debye length (inverse distance units)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
{lj/cut/coul/long} args = cutoff (cutoff2)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units)
{lj/cut/coul/long/tip4p} args = otype htype btype atype qdist cutoff (cutoff2)
otype,htype = atom types for TIP4P O and H
btype,atype = bond and angle types for TIP4P waters
qdist = distance from O atom to massless charge (distance units)
cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
[Examples:]
pair_style lj/cut 2.5
pair_coeff * * 1 1
pair_coeff 1 1 1 1.1 2.8 :pre
pair_style lj/cut/coul/cut 10.0
pair_style lj/cut/coul/cut 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0
pair_coeff 1 1 100.0 3.5 9.0 9.0 :pre
pair_style lj/cut/coul/debye 1.5 3.0
pair_style lj/cut/coul/debye 1.5 2.5 5.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
pair_coeff 1 1 1.0 1.5 2.5 5.0 :pre
pair_style lj/cut/coul/long 10.0
pair_style lj/cut/coul/long 10.0 8.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0 :pre
pair_style lj/cut/coul/long/tip4p 1 2 7 8 0.3 12.0
pair_style lj/cut/coul/long/tip4p 1 2 7 8 0.3 12.0 10.0
pair_coeff * * 100.0 3.0
pair_coeff 1 1 100.0 3.5 9.0 :pre
[Description:]
The {lj/cut} styles compute the standard 12/6 Lennard-Jones potential,
given by
:c,image(Eqs/pair_lj.jpg)
Rc is the cutoff.
Style {lj/cut/coul/cut} adds a Coulombic pairwise interaction given by
:c,image(Eqs/pair_coulomb.jpg)
where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, and epsilon is the dielectric constant which can be set
by the "dielectric"_dielectric.html command. If one cutoff is
specified in the pair_style command, it is used for both the LJ and
Coulombic terms. If two cutoffs are specified, they are used as
cutoffs for the LJ and Coulombic terms respectively.
Style {lj/cut/coul/debye} adds an additional exp() damping factor
to the Coulombic term, given by
:c,image(Eqs/pair_debye.jpg)
where kappa is the Debye length. This potential is another way to
mimic the screening effect of a polar solvent.
Style {lj/cut/coul/long} computes the same Coulombic interactions as
style {lj/cut/coul/cut} except that an additional damping factor is
applied to the Coulombic term so it can be used in conjunction with
the "kspace_style"_kspace_style.html command and its {ewald} or {pppm}
option. The Coulombic cutoff specified for this style means that
pairwise interactions within this distance are computed directly;
interactions outside that distance are computed in reciprocal space.
Style {lj/cut/coul/long/tip4p} implements the TIP4P water model of
"(Jorgensen)"_#Jorgensen, which introduces a massless site located a
short distance away from the oxygen atom along the bisector of the HOH
angle. The atomic types of the oxygen and hydrogen atoms, the bond
and angle types for OH and HOH interactions, and the distance to the
massless charge site are specified as pair_style arguments.
IMPORTANT NOTE: For each TIP4P water molecule in your system, the atom
IDs for the O and 2 H atoms must be consecutive, with the O atom
first. This is to enable LAMMPS to "find" the 2 H atoms associated
with each O atom. For example, if the atom ID of an O atom in a TIP4P
water molecule is 500, then its 2 H atoms must have IDs 501 and 502.
See the "howto section"_Section_howto.html#howto_8 for more
information on how to use the TIP4P pair style.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff1 (distance units)
cutoff2 (distance units) :ul
Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair. You cannot specify 2 cutoffs for style {lj/cut}, since it
has no Coulombic terms.
For {lj/cut/coul/long} and {lj/cut/coul/long/tip4p} only the LJ cutoff
can be specified since a Coulombic cutoff cannot be specified for an
individual I,J type pair. All type pairs use the same global
Coulombic cutoff specified in the pair_style command.
+Styles {lj/cut/coul/pppm/omp} and {lj/cut/coul/pppm/tip4p/omp}
+are variants of {lj/cut/coul/long/omp} and {lj/cut/coul/long/tip4p/omp}
+for use with k-space styles "{pppm/proxy}"_kspace_style.html and
+"{pppm/tip4p/proxy}"_kspace_style.html, respectively and OpenMP
+multi-threading and will perform the corresponding reciprocal
+space calculation concurrently with the pair calculation
+in a separate thread. For certain parallel setups, this may have
+a performance benefit over performing k-space style and pair style
+separately and one after the other.
+
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is {geometric}. See the "pair_modify" command
for details.
All of the lj/cut pair styles support the
"pair_modify"_pair_modify.html shift option for the energy of the
Lennard-Jones portion of the pair interaction.
The {lj/cut/coul/long} and {lj/cut/coul/long/tip4p} pair styles
support the "pair_modify"_pair_modify.html table option since they can
tabulate the short-range portion of the long-range Coulombic
interaction.
All of the lj/cut pair styles support the
"pair_modify"_pair_modify.html tail option for adding a long-range
tail correction to the energy and pressure for the Lennard-Jones
portion of the pair interaction.
All of the lj/cut pair styles write their information to "binary
restart files"_restart.html, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
The lj/cut and lj/cut/coul/long pair styles support the use of the
{inner}, {middle}, and {outer} keywords of the "run_style
respa"_run_style.html command, meaning the pairwise forces can be
partitioned by distance at different levels of the rRESPA hierarchy.
The other styles only support the {pair} keyword of run_style respa.
See the "run_style"_run_style.html command for details.
:line
[Restrictions:]
The {lj/cut/coul/long} and {lj/cut/coul/long/tip4p} styles are part of
the KSPACE package. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info. Note that the KSPACE package is installed by
default.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Jorgensen)
[(Jorgensen)] Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem
Phys, 79, 926 (1983).
diff --git a/doc/pair_lj96.html b/doc/pair_lj96.html
index 97d794d73..940459abb 100644
--- a/doc/pair_lj96.html
+++ b/doc/pair_lj96.html
@@ -1,115 +1,115 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj96/cut command
</H3>
<H3>pair_style lj96/cut/cuda command
</H3>
<H3>pair_style lj96/cut/gpu command
</H3>
<H3>pair_style lj96/cut/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj96/cut cutoff
</PRE>
<UL><LI>cutoff = global cutoff for lj96/cut interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj96/cut 2.5
pair_coeff * * 1.0 1.0 4.0
pair_coeff 1 1 1.0 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj96/cut</I> style compute a 9/6 Lennard-Jones potential, instead
of the standard 12/6 potential, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_lj96.jpg">
</CENTER>
<P>Rc is the cutoff.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global LJ
cutoff specified in the pair_style command is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is <I>geometric</I>. See the "pair_modify" command
for details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> tail
option for adding a long-range tail correction to the energy and
pressure of the pair interaction.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style supports the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I>
keywords of the <A HREF = "run_style.html">run_style respa</A> command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the <A HREF = "run_style.html">run_style</A> command for
details.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_lj96.txt b/doc/pair_lj96.txt
index dcdb3632c..2a6280a35 100644
--- a/doc/pair_lj96.txt
+++ b/doc/pair_lj96.txt
@@ -1,107 +1,107 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj96/cut command :h3
pair_style lj96/cut/cuda command :h3
pair_style lj96/cut/gpu command :h3
pair_style lj96/cut/omp command :h3
[Syntax:]
pair_style lj96/cut cutoff :pre
cutoff = global cutoff for lj96/cut interactions (distance units) :ul
[Examples:]
pair_style lj96/cut 2.5
pair_coeff * * 1.0 1.0 4.0
pair_coeff 1 1 1.0 1.0 :pre
[Description:]
The {lj96/cut} style compute a 9/6 Lennard-Jones potential, instead
of the standard 12/6 potential, given by
:c,image(Eqs/pair_lj96.jpg)
Rc is the cutoff.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global LJ
cutoff specified in the pair_style command is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is {geometric}. See the "pair_modify" command
for details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style supports the "pair_modify"_pair_modify.html tail
option for adding a long-range tail correction to the energy and
pressure of the pair interaction.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style supports the use of the {inner}, {middle}, and {outer}
keywords of the "run_style respa"_run_style.html command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the "run_style"_run_style.html command for
details.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_lj_coul.html b/doc/pair_lj_coul.html
index 9faaba871..eae07c2a2 100644
--- a/doc/pair_lj_coul.html
+++ b/doc/pair_lj_coul.html
@@ -1,181 +1,181 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/coul command
</H3>
<H3>pair_style lj/coul/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj/coul flag_lj flag_coul cutoff (cutoff2)
</PRE>
<UL><LI>flag_lj = <I>long</I> or <I>cut</I>
<PRE> <I>long</I> = use Kspace long-range summation for the dispersion term 1/r^6
<I>cut</I> = use a cutoff
</PRE>
<LI>flag_coul = <I>long</I> or <I>off</I>
<PRE> <I>long</I> = use Kspace long-range summation for the Coulombic term 1/r
<I>off</I> = omit the Coulombic term
</PRE>
<LI>cutoff = global cutoff for LJ (and Coulombic if only 1 cutoff) (distance units)
<LI>cutoff2 = global cutoff for Coulombic (optional) (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/coul cut off 2.5
pair_style lj/coul cut long 2.5 4.0
pair_style lj/coul long long 2.5 4.0
pair_coeff * * 1 1
pair_coeff 1 1 1 3 4
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/coul</I> style computes the standard 12/6 Lennard-Jones and
Coulombic potentials, given by
</P>
<CENTER><IMG SRC = "Eqs/pair_lj.jpg">
</CENTER>
<CENTER><IMG SRC = "Eqs/pair_coulomb.jpg">
</CENTER>
<P>where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, epsilon is the dielectric constant which can be set by
the <A HREF = "dielectric.html">dielectric</A> command, and Rc is the cutoff. If
one cutoff is specified in the pair_style command, it is used for both
the LJ and Coulombic terms. If two cutoffs are specified, they are
used as cutoffs for the LJ and Coulombic terms respectively.
</P>
<P>The purpose of this pair style is to capture long-range interactions
resulting from both attractive 1/r^6 Lennard-Jones and Coulombic 1/r
interactions. This is done by use of the <I>flag_lj</I> and <I>flag_coul</I>
settings. The <A HREF = "#Veld">In 't Veld</A> paper has more details on when it is
appropriate to include long-range 1/r^6 interactions, using this
potential.
</P>
<P>If <I>flag_lj</I> is set to <I>long</I>, no cutoff is used on the LJ 1/r^6
dispersion term. The long-range portion is calculated by using the
<A HREF = "kspace_style.html">kspace_style ewald/n</A> command. The specified LJ
cutoff then determines which portion of the LJ interactions are
computed directly by the pair potential versus which part is computed
in reciprocal space via the Kspace style. If <I>flag_lj</I> is set to
<I>cut</I>, the LJ interactions are simply cutoff, as with <A HREF = "pair_lj.html">pair_style
lj/cut</A>.
</P>
<P>If <I>flag_coul</I> is set to <I>long</I>, no cutoff is used on the Coulombic
interactions. The long-range portion is calculated by using any
style, including <I>ewald/n</I> of the <A HREF = "kspace_style.html">kspace_style</A>
command. Note that if <I>flag_lj</I> is also set to long, then only the
<I>ewald/n</I> Kspace style can perform the long-range calculations for
both the LJ and Coulombic interactions. If <I>flag_coul</I> is set to
<I>off</I>, Coulombic interactions are not computed.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff1 (distance units)
<LI>cutoff2 (distance units)
</UL>
<P>Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
</P>
<P>The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair. Note that if you are using <I>flag_lj</I> set to <I>long</I>, you
cannot specify a LJ cutoff for an atom type pair, since only one
global LJ cutoff is allowed. Similarly, if you are using <I>flag_coul</I>
set to <I>long</I>, you cannot specify a Coulombic cutoff for an atom type
pair, since only one global Coulombic cutoff is allowed.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is <I>geometric</I>. See the "pair_modify" command
for details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the Lennard-Jones portion of the pair
interaction, assuming <I>flag_lj</I> is <I>cut</I>.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> table
option since it can tabulate the short-range portion of the long-range
Coulombic interaction.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding a long-range tail correction to the
Lennard-Jones portion of the energy and pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style supports the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I>
keywords of the <A HREF = "run_style.html">run_style respa</A> command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the <A HREF = "run_style.html">run_style</A> command for
details.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the USER-EWALDN package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Veld"></A>
<P><B>(In 't Veld)</B> In 't Veld, Ismail, Grest, J Chem Phys (accepted) (2007).
</P>
</HTML>
diff --git a/doc/pair_lj_coul.txt b/doc/pair_lj_coul.txt
index 1593ca417..2a3ebdc97 100644
--- a/doc/pair_lj_coul.txt
+++ b/doc/pair_lj_coul.txt
@@ -1,169 +1,169 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/coul command :h3
pair_style lj/coul/omp command :h3
[Syntax:]
pair_style lj/coul flag_lj flag_coul cutoff (cutoff2) :pre
flag_lj = {long} or {cut} :ulb,l
{long} = use Kspace long-range summation for the dispersion term 1/r^6
{cut} = use a cutoff :pre
flag_coul = {long} or {off} :l
{long} = use Kspace long-range summation for the Coulombic term 1/r
{off} = omit the Coulombic term :pre
cutoff = global cutoff for LJ (and Coulombic if only 1 cutoff) (distance units) :l
cutoff2 = global cutoff for Coulombic (optional) (distance units) :l,ule
[Examples:]
pair_style lj/coul cut off 2.5
pair_style lj/coul cut long 2.5 4.0
pair_style lj/coul long long 2.5 4.0
pair_coeff * * 1 1
pair_coeff 1 1 1 3 4 :pre
[Description:]
The {lj/coul} style computes the standard 12/6 Lennard-Jones and
Coulombic potentials, given by
:c,image(Eqs/pair_lj.jpg)
:c,image(Eqs/pair_coulomb.jpg)
where C is an energy-conversion constant, Qi and Qj are the charges on
the 2 atoms, epsilon is the dielectric constant which can be set by
the "dielectric"_dielectric.html command, and Rc is the cutoff. If
one cutoff is specified in the pair_style command, it is used for both
the LJ and Coulombic terms. If two cutoffs are specified, they are
used as cutoffs for the LJ and Coulombic terms respectively.
The purpose of this pair style is to capture long-range interactions
resulting from both attractive 1/r^6 Lennard-Jones and Coulombic 1/r
interactions. This is done by use of the {flag_lj} and {flag_coul}
settings. The "In 't Veld"_#Veld paper has more details on when it is
appropriate to include long-range 1/r^6 interactions, using this
potential.
If {flag_lj} is set to {long}, no cutoff is used on the LJ 1/r^6
dispersion term. The long-range portion is calculated by using the
"kspace_style ewald/n"_kspace_style.html command. The specified LJ
cutoff then determines which portion of the LJ interactions are
computed directly by the pair potential versus which part is computed
in reciprocal space via the Kspace style. If {flag_lj} is set to
{cut}, the LJ interactions are simply cutoff, as with "pair_style
lj/cut"_pair_lj.html.
If {flag_coul} is set to {long}, no cutoff is used on the Coulombic
interactions. The long-range portion is calculated by using any
style, including {ewald/n} of the "kspace_style"_kspace_style.html
command. Note that if {flag_lj} is also set to long, then only the
{ewald/n} Kspace style can perform the long-range calculations for
both the LJ and Coulombic interactions. If {flag_coul} is set to
{off}, Coulombic interactions are not computed.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff1 (distance units)
cutoff2 (distance units) :ul
Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum at 2^(1/6)
sigma.
The latter 2 coefficients are optional. If not specified, the global
LJ and Coulombic cutoffs specified in the pair_style command are used.
If only one cutoff is specified, it is used as the cutoff for both LJ
and Coulombic interactions for this type pair. If both coefficients
are specified, they are used as the LJ and Coulombic cutoffs for this
type pair. Note that if you are using {flag_lj} set to {long}, you
cannot specify a LJ cutoff for an atom type pair, since only one
global LJ cutoff is allowed. Similarly, if you are using {flag_coul}
set to {long}, you cannot specify a Coulombic cutoff for an atom type
pair, since only one global Coulombic cutoff is allowed.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is {geometric}. See the "pair_modify" command
for details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the Lennard-Jones portion of the pair
interaction, assuming {flag_lj} is {cut}.
This pair style supports the "pair_modify"_pair_modify.html table
option since it can tabulate the short-range portion of the long-range
Coulombic interaction.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding a long-range tail correction to the
Lennard-Jones portion of the energy and pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style supports the use of the {inner}, {middle}, and {outer}
keywords of the "run_style respa"_run_style.html command, meaning the
pairwise forces can be partitioned by distance at different levels of
the rRESPA hierarchy. See the "run_style"_run_style.html command for
details.
:line
[Restrictions:]
This style is part of the USER-EWALDN package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Veld)
[(In 't Veld)] In 't Veld, Ismail, Grest, J Chem Phys (accepted) (2007).
diff --git a/doc/pair_lj_cubic.html b/doc/pair_lj_cubic.html
index b5d72b845..9bd2996a9 100644
--- a/doc/pair_lj_cubic.html
+++ b/doc/pair_lj_cubic.html
@@ -1,136 +1,136 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/cubic command
</H3>
<H3>pair_style lj/cubic/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj/cubic
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/cubic
pair_coeff * * 1.0 0.8908987
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>lj/cubic</I> style computes a truncated LJ interaction potential whose
energy and force are continuous everywhere.
Inside the inflection point the interaction is identical to the
standard 12/6 <A HREF = "pair_lj.html">Lennard-Jones</A> potential.
The LJ function outside the inflection point is replaced
with a cubic function of distance. The energy, force, and second
derivative are continuous at the inflection point.
The cubic coefficient A3 is chosen so
that both energy and force go to zero at the cutoff distance.
Outside the cutoff distance the energy and force are zero.
</P>
<CENTER><IMG SRC = "Eqs/pair_lj_cubic.jpg">
</CENTER>
<P>The location of the inflection point rs is defined
by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance
is defined by rc/rs = 67/48 or rc/sigma = 1.737....
The analytic expression for the
the cubic coefficient
A3*rmin^3/epsilon = 27.93... is given in the paper by
Holian and Ravelo <A HREF = "#Holian">(Holian)</A>.
</P>
<P>This potential is commonly used to study the shock mechanics
of FCC solids, as in Ravelo et al. <A HREF = "#Ravelo">(Ravelo)</A>.
</P>
<P>The following coefficients must be defined for each pair of atom
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the example
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
</UL>
<P>Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum, which
is located at rmin = 2^(1/6)*sigma. In the above example, sigma = 0.8908987,
so rmin = 1.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is <I>geometric</I>. See the "pair_modify" command
for details.
</P>
<P>The lj/cubic pair style does not support the
<A HREF = "pair_modify.html">pair_modify</A> shift option,
since pair interaction is already smoothed to 0.0 at the
cutoff.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>The lj/cubic pair style does not support the
<A HREF = "pair_modify.html">pair_modify</A> tail option for adding long-range tail
corrections to energy and pressure, since there are no corrections for
a potential that goes to 0.0 at the cutoff.
</P>
<P>The lj/cubic pair style writes its information to <A HREF = "restart.html">binary
restart files</A>, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
</P>
<P>The lj/cubic pair style can only be used via the <I>pair</I>
keyword of the <A HREF = "run_style.html">run_style respa</A> command. It does not
support the <I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Holian"></A>
<A NAME = "Ravelo"></A><B>(Holian)</B> Holian and Ravelo, Phys Rev B, 51, 11275 (1995).
<P><B>(Ravelo)</B> Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004).
</P>
</HTML>
diff --git a/doc/pair_lj_cubic.txt b/doc/pair_lj_cubic.txt
index 5d60cb12b..f1f17c9f9 100644
--- a/doc/pair_lj_cubic.txt
+++ b/doc/pair_lj_cubic.txt
@@ -1,128 +1,128 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/cubic command :h3
pair_style lj/cubic/omp command :h3
[Syntax:]
pair_style lj/cubic :pre
[Examples:]
pair_style lj/cubic
pair_coeff * * 1.0 0.8908987 :pre
[Description:]
The {lj/cubic} style computes a truncated LJ interaction potential whose
energy and force are continuous everywhere.
Inside the inflection point the interaction is identical to the
standard 12/6 "Lennard-Jones"_pair_lj.html potential.
The LJ function outside the inflection point is replaced
with a cubic function of distance. The energy, force, and second
derivative are continuous at the inflection point.
The cubic coefficient A3 is chosen so
that both energy and force go to zero at the cutoff distance.
Outside the cutoff distance the energy and force are zero.
:c,image(Eqs/pair_lj_cubic.jpg)
The location of the inflection point rs is defined
by the LJ diameter, rs/sigma = (26/7)^1/6. The cutoff distance
is defined by rc/rs = 67/48 or rc/sigma = 1.737....
The analytic expression for the
the cubic coefficient
A3*rmin^3/epsilon = 27.93... is given in the paper by
Holian and Ravelo "(Holian)"_#Holian.
This potential is commonly used to study the shock mechanics
of FCC solids, as in Ravelo et al. "(Ravelo)"_#Ravelo.
The following coefficients must be defined for each pair of atom
types via the "pair_coeff"_pair_coeff.html command as in the example
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units) :ul
Note that sigma is defined in the LJ formula as the zero-crossing
distance for the potential, not as the energy minimum, which
is located at rmin = 2^(1/6)*sigma. In the above example, sigma = 0.8908987,
so rmin = 1.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of the lj/cut pair styles can be mixed.
The default mix value is {geometric}. See the "pair_modify" command
for details.
The lj/cubic pair style does not support the
"pair_modify"_pair_modify.html shift option,
since pair interaction is already smoothed to 0.0 at the
cutoff.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
The lj/cubic pair style does not support the
"pair_modify"_pair_modify.html tail option for adding long-range tail
corrections to energy and pressure, since there are no corrections for
a potential that goes to 0.0 at the cutoff.
The lj/cubic pair style writes its information to "binary
restart files"_restart.html, so pair_style and pair_coeff commands do
not need to be specified in an input script that reads a restart file.
The lj/cubic pair style can only be used via the {pair}
keyword of the "run_style respa"_run_style.html command. It does not
support the {inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Holian)
[(Holian)] Holian and Ravelo, Phys Rev B, 51, 11275 (1995).
:link(Ravelo)
[(Ravelo)] Ravelo, Holian, Germann and Lomdahl, Phys Rev B, 70, 014103 (2004).
diff --git a/doc/pair_lj_expand.html b/doc/pair_lj_expand.html
index 9173bc7d5..91b3130a6 100644
--- a/doc/pair_lj_expand.html
+++ b/doc/pair_lj_expand.html
@@ -1,119 +1,119 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/expand command
</H3>
<H3>pair_style lj/expand/cuda command
</H3>
<H3>pair_style lj/expand/gpu command
</H3>
<H3>pair_style lj/expand/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj/expand cutoff
</PRE>
<UL><LI>cutoff = global cutoff for lj/expand interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/expand 2.5
pair_coeff * * 1.0 1.0 0.5
pair_coeff 1 1 1.0 1.0 -0.2 2.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>lj/expand</I> computes a LJ interaction with a distance shifted by
delta which can be useful when particles are of different sizes, since
it is different that using different sigma values in a standard LJ
formula:
</P>
<CENTER><IMG SRC = "Eqs/pair_lj_expand.jpg">
</CENTER>
<P>Rc is the cutoff which does not include the delta distance. I.e. the
actual force cutoff is the sum of cutoff + delta.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>delta (distance units)
<LI>cutoff (distance units)
</UL>
<P>The delta values can be positive or negative. The last coefficient is
optional. If not specified, the global LJ cutoff is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon, sigma, and shift
coefficients and cutoff distance for this pair style can be mixed.
Shift is always mixed via an <I>arithmetic</I> rule. The other
coefficients are mixed according to the pair_modify mix value. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> tail
option for adding a long-range tail correction to the energy and
pressure of the pair interaction.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_lj_expand.txt b/doc/pair_lj_expand.txt
index fc9fd047e..d2be5a81c 100644
--- a/doc/pair_lj_expand.txt
+++ b/doc/pair_lj_expand.txt
@@ -1,111 +1,111 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/expand command :h3
pair_style lj/expand/cuda command :h3
pair_style lj/expand/gpu command :h3
pair_style lj/expand/omp command :h3
[Syntax:]
pair_style lj/expand cutoff :pre
cutoff = global cutoff for lj/expand interactions (distance units) :ul
[Examples:]
pair_style lj/expand 2.5
pair_coeff * * 1.0 1.0 0.5
pair_coeff 1 1 1.0 1.0 -0.2 2.0 :pre
[Description:]
Style {lj/expand} computes a LJ interaction with a distance shifted by
delta which can be useful when particles are of different sizes, since
it is different that using different sigma values in a standard LJ
formula:
:c,image(Eqs/pair_lj_expand.jpg)
Rc is the cutoff which does not include the delta distance. I.e. the
actual force cutoff is the sum of cutoff + delta.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
delta (distance units)
cutoff (distance units) :ul
The delta values can be positive or negative. The last coefficient is
optional. If not specified, the global LJ cutoff is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon, sigma, and shift
coefficients and cutoff distance for this pair style can be mixed.
Shift is always mixed via an {arithmetic} rule. The other
coefficients are mixed according to the pair_modify mix value. The
default mix value is {geometric}. See the "pair_modify" command for
details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style supports the "pair_modify"_pair_modify.html tail
option for adding a long-range tail correction to the energy and
pressure of the pair interaction.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_lj_sf.html b/doc/pair_lj_sf.html
index 7ff901105..6da69b3e6 100644
--- a/doc/pair_lj_sf.html
+++ b/doc/pair_lj_sf.html
@@ -1,120 +1,120 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/sf command
</H3>
<H3>pair_style lj/sf/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj/sf cutoff
</PRE>
<UL><LI>cutoff = global cutoff for Lennard-Jones interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/sf 2.5
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.0 3.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>lj/sf</I> computes a truncated and force-shifted LJ interaction
(Shifted Force Lennard-Jones), so that both the potential and the
force go continuously to zero at the cutoff <A HREF = "#Toxvaerd">(Toxvaerd)</A>:
</P>
<CENTER><IMG SRC = "Eqs/pair_lj_sf.jpg">
</CENTER>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global
LJ cutoff specified in the pair_style command is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma
coefficients and cutoff distance for this pair style can be mixed.
Rin is a cutoff value and is mixed like the cutoff. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> shift option is not relevant for
this pair style, since the pair interaction goes to 0.0 at the cutoff.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure, since the energy of the pair interaction is smoothed to 0.0
at the cutoff.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the USER-MISC package. It is only enabled
if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Toxvaerd"></A>
<P><B>(Toxvaerd)</B> Toxvaerd, Dyre, J Chem Phys, 134, 081102 (2011).
</P>
</HTML>
diff --git a/doc/pair_lj_sf.txt b/doc/pair_lj_sf.txt
index a56cf7485..be0d94f5a 100644
--- a/doc/pair_lj_sf.txt
+++ b/doc/pair_lj_sf.txt
@@ -1,113 +1,113 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/sf command :h3
pair_style lj/sf/omp command :h3
[Syntax:]
pair_style lj/sf cutoff :pre
cutoff = global cutoff for Lennard-Jones interactions (distance units) :ul
[Examples:]
pair_style lj/sf 2.5
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.0 3.0 :pre
[Description:]
Style {lj/sf} computes a truncated and force-shifted LJ interaction
(Shifted Force Lennard-Jones), so that both the potential and the
force go continuously to zero at the cutoff "(Toxvaerd)"_#Toxvaerd:
:c,image(Eqs/pair_lj_sf.jpg)
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global
LJ cutoff specified in the pair_style command is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma
coefficients and cutoff distance for this pair style can be mixed.
Rin is a cutoff value and is mixed like the cutoff. The
default mix value is {geometric}. See the "pair_modify" command for
details.
The "pair_modify"_pair_modify.html shift option is not relevant for
this pair style, since the pair interaction goes to 0.0 at the cutoff.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure, since the energy of the pair interaction is smoothed to 0.0
at the cutoff.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the USER-MISC package. It is only enabled
if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Toxvaerd)
[(Toxvaerd)] Toxvaerd, Dyre, J Chem Phys, 134, 081102 (2011).
diff --git a/doc/pair_lj_smooth.html b/doc/pair_lj_smooth.html
index 0805dd5f0..57af043e7 100644
--- a/doc/pair_lj_smooth.html
+++ b/doc/pair_lj_smooth.html
@@ -1,128 +1,128 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style lj/smooth command
</H3>
<H3>pair_style lj/smooth/cuda command
</H3>
<H3>pair_style lj/smooth/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style lj/smooth Rin Rc
</PRE>
<UL><LI>Rin = inner cutoff beyond which force smoothing will be applied (distance units)
<LI>Rc = outer cutoff for lj/smooth interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/smooth 8.0 10.0
pair_coeff * * 10.0 1.5
pair_coeff 1 1 20.0 1.3 7.0 9.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>lj/smooth</I> computes a LJ interaction with a force smoothing
applied between the inner and outer cutoff.
</P>
<CENTER><IMG SRC = "Eqs/pair_lj_smooth.jpg">
</CENTER>
<P>The polynomial coefficients C1, C2, C3, C4 are computed by LAMMPS to
cause the force to vary smoothly from the inner cutoff Rin to the
outer cutoff Rc.
</P>
<P>At the inner cutoff the force and its 1st derivative
will match the unsmoothed LJ formula. At the outer cutoff the force
and its 1st derivative will be 0.0. The inner cutoff cannot be 0.0.
</P>
<P>IMPORTANT NOTE: this force smoothing causes the energy to be
discontinuous both in its values and 1st derivative. This can lead to
poor energy conservation and may require the use of a thermostat.
Plot the energy and force resulting from this formula via the
<A HREF = "pair_write.html">pair_write</A> command to see the effect.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>innner (distance units)
<LI>outer (distance units)
</UL>
<P>The last 2 coefficients are optional inner and outer cutoffs. If not
specified, the global values for Rin and Rc are used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon, sigma, Rin
coefficients and the cutoff distance for this pair style can be mixed.
Rin is a cutoff value and is mixed like the cutoff. The other
coefficients are mixed according to the pair_modify mix option. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure, since the energy of the pair interaction is smoothed to 0.0
at the cutoff.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_lj_smooth.txt b/doc/pair_lj_smooth.txt
index b08bb4743..a2d37902c 100644
--- a/doc/pair_lj_smooth.txt
+++ b/doc/pair_lj_smooth.txt
@@ -1,121 +1,121 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style lj/smooth command :h3
pair_style lj/smooth/cuda command :h3
pair_style lj/smooth/omp command :h3
[Syntax:]
pair_style lj/smooth Rin Rc :pre
Rin = inner cutoff beyond which force smoothing will be applied (distance units)
Rc = outer cutoff for lj/smooth interactions (distance units) :ul
[Examples:]
pair_style lj/smooth 8.0 10.0
pair_coeff * * 10.0 1.5
pair_coeff 1 1 20.0 1.3 7.0 9.0 :pre
[Description:]
Style {lj/smooth} computes a LJ interaction with a force smoothing
applied between the inner and outer cutoff.
:c,image(Eqs/pair_lj_smooth.jpg)
The polynomial coefficients C1, C2, C3, C4 are computed by LAMMPS to
cause the force to vary smoothly from the inner cutoff Rin to the
outer cutoff Rc.
At the inner cutoff the force and its 1st derivative
will match the unsmoothed LJ formula. At the outer cutoff the force
and its 1st derivative will be 0.0. The inner cutoff cannot be 0.0.
IMPORTANT NOTE: this force smoothing causes the energy to be
discontinuous both in its values and 1st derivative. This can lead to
poor energy conservation and may require the use of a thermostat.
Plot the energy and force resulting from this formula via the
"pair_write"_pair_write.html command to see the effect.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
epsilon (energy units)
sigma (distance units)
innner (distance units)
outer (distance units) :ul
The last 2 coefficients are optional inner and outer cutoffs. If not
specified, the global values for Rin and Rc are used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon, sigma, Rin
coefficients and the cutoff distance for this pair style can be mixed.
Rin is a cutoff value and is mixed like the cutoff. The other
coefficients are mixed according to the pair_modify mix option. The
default mix value is {geometric}. See the "pair_modify" command for
details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure, since the energy of the pair interaction is smoothed to 0.0
at the cutoff.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_morse.html b/doc/pair_morse.html
index eaf5f1608..42ab9eb6d 100644
--- a/doc/pair_morse.html
+++ b/doc/pair_morse.html
@@ -1,113 +1,113 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style morse command
</H3>
<H3>pair_style morse/cuda command
</H3>
<H3>pair_style morse/gpu command
</H3>
<H3>pair_style morse/omp command
</H3>
<H3>pair_style morse/opt command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style morse cutoff
</PRE>
<UL><LI>cutoff = global cutoff for Morse interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style morse 2.5
pair_coeff * * 100.0 2.0 1.5
pair_coeff 1 1 100.0 2.0 1.5 3.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>morse</I> computes pairwise interactions with the formula
</P>
<CENTER><IMG SRC = "Eqs/pair_morse.jpg">
</CENTER>
<P>Rc is the cutoff.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>D0 (energy units)
<LI>alpha (1/distance units)
<LI>r0 (distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global morse
cutoff is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>None of these pair styles support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>All of these pair styles support the <A HREF = "pair_modify.html">pair_modify</A>
shift option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table options is not relevant for
the Morse pair styles.
</P>
<P>None of these pair styles support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>All of these pair styles write their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_morse.txt b/doc/pair_morse.txt
index b31acbb5a..5c8293e6b 100644
--- a/doc/pair_morse.txt
+++ b/doc/pair_morse.txt
@@ -1,104 +1,104 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style morse command :h3
pair_style morse/cuda command :h3
pair_style morse/gpu command :h3
pair_style morse/omp command :h3
pair_style morse/opt command :h3
[Syntax:]
pair_style morse cutoff :pre
cutoff = global cutoff for Morse interactions (distance units) :ul
[Examples:]
pair_style morse 2.5
pair_coeff * * 100.0 2.0 1.5
pair_coeff 1 1 100.0 2.0 1.5 3.0 :pre
[Description:]
Style {morse} computes pairwise interactions with the formula
:c,image(Eqs/pair_morse.jpg)
Rc is the cutoff.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
D0 (energy units)
alpha (1/distance units)
r0 (distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global morse
cutoff is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
None of these pair styles support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
All of these pair styles support the "pair_modify"_pair_modify.html
shift option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table options is not relevant for
the Morse pair styles.
None of these pair styles support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
All of these pair styles write their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_peri.html b/doc/pair_peri.html
index 33bcbd17c..c5871b982 100644
--- a/doc/pair_peri.html
+++ b/doc/pair_peri.html
@@ -1,156 +1,156 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style peri/pmb command
</H3>
<H3>pair_style peri/pmb/omp command
</H3>
<H3>pair_style peri/lps command
</H3>
<H3>pair_style peri/lps/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style
</PRE>
<UL><LI>style = <I>peri/pmb</I> or <I>peri/lps</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style peri/pmb
pair_coeff * * 1.6863e22 0.0015001 0.0005 0.25
</PRE>
<PRE>pair_style peri/lps
pair_coeff * * 14.9e9 14.9e9 0.0015001 0.0005 0.25
</PRE>
<P><B>Description:</B>
</P>
<P>The peridynamic pair styles implement material models that can be used
at the mescscopic and macroscopic scales.
</P>
<P>Style <I>peri/pmb</I> implements the Peridynamic bond-based prototype
microelastic brittle (PMB) model.
</P>
<P>Style <I>peri/lps</I> implements the Peridynamic state-based linear
peridynamic solid (LPS) model.
</P>
<P>The canonical papers on Peridynamics are <A HREF = "#Silling2000">(Silling 2000)</A>
and <A HREF = "#Silling2007">(Silling 2007)</A>. The implementation of Peridynamics
in LAMMPS is described in <A HREF = "#Parks">(Parks)</A>. Also see the <A HREF = "http://www.sandia.gov/~mlparks/papers/PDLAMMPS.pdf">PDLAMMPS
user guide</A> for
more details about the implementation of peridynamics in LAMMPS.
</P>
<P>The following coefficients must be defined for each pair of atom types
via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples above,
or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below.
</P>
<P>For the <I>peri/pmb</I> style:
</P>
<UL><LI>c (energy/distance/volume^2 units)
<LI>horizon (distance units)
<LI>s00 (unitless)
<LI>alpha (unitless)
</UL>
<P>C is the effectively a spring constant for Peridynamic bonds, the
horizon is a cutoff distance for truncating interactions, and s00 and
alpha are used as a bond breaking criteria. The units of c are such
that c/distance = stiffness/volume^2, where stiffness is
energy/distance^2 and volume is distance^3. See the users guide for
more details.
</P>
<P>For the <I>peri/lps</I> style:
</P>
<UL><LI>K (force/area units)
<LI>G (force/area units)
<LI>horizon (distance units)
<LI>s00 (unitless)
<LI>alpha (unitless)
</UL>
<P>K is the bulk modulus and G is the shear modulus. The horizon is a
cutoff distance for truncating interactions, and s00 and alpha are
used as a bond breaking criteria. See the users guide for more
details.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table and tail options are not
relevant for these pair styles.
</P>
<P>These pair styles write their information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>The <I>peri/pmb</I> and <I>peri/lps</I> styles are part of the PERI
package. They are only enabled if LAMMPS was built with that package.
See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more
info.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Parks"></A>
<P><B>(Parks)</B> Parks, Lehoucq, Plimpton, Silling, Comp Phys Comm, 179(11), 777-783 (2008).
</P>
<A NAME = "Silling2000"></A>
<P><B>(Silling 2000)</B> Silling, J Mech Phys Solids, 48, 175-209 (2000).
</P>
<A NAME = "Silling2007"></A>
<P><B>(Silling 2007)</B> Silling, Epton, Weckner, Xu, Askari, J Elasticity, 88, 151-184 (2007).
</P>
</HTML>
diff --git a/doc/pair_peri.txt b/doc/pair_peri.txt
index 00f663649..acaea14e3 100644
--- a/doc/pair_peri.txt
+++ b/doc/pair_peri.txt
@@ -1,145 +1,145 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style peri/pmb command :h3
pair_style peri/pmb/omp command :h3
pair_style peri/lps command :h3
pair_style peri/lps/omp command :h3
[Syntax:]
pair_style style :pre
style = {peri/pmb} or {peri/lps} :ul
[Examples:]
pair_style peri/pmb
pair_coeff * * 1.6863e22 0.0015001 0.0005 0.25 :pre
pair_style peri/lps
pair_coeff * * 14.9e9 14.9e9 0.0015001 0.0005 0.25 :pre
[Description:]
The peridynamic pair styles implement material models that can be used
at the mescscopic and macroscopic scales.
Style {peri/pmb} implements the Peridynamic bond-based prototype
microelastic brittle (PMB) model.
Style {peri/lps} implements the Peridynamic state-based linear
peridynamic solid (LPS) model.
The canonical papers on Peridynamics are "(Silling 2000)"_#Silling2000
and "(Silling 2007)"_#Silling2007. The implementation of Peridynamics
in LAMMPS is described in "(Parks)"_#Parks. Also see the "PDLAMMPS
user guide"_http://www.sandia.gov/~mlparks/papers/PDLAMMPS.pdf for
more details about the implementation of peridynamics in LAMMPS.
The following coefficients must be defined for each pair of atom types
via the "pair_coeff"_pair_coeff.html command as in the examples above,
or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below.
For the {peri/pmb} style:
c (energy/distance/volume^2 units)
horizon (distance units)
s00 (unitless)
alpha (unitless) :ul
C is the effectively a spring constant for Peridynamic bonds, the
horizon is a cutoff distance for truncating interactions, and s00 and
alpha are used as a bond breaking criteria. The units of c are such
that c/distance = stiffness/volume^2, where stiffness is
energy/distance^2 and volume is distance^3. See the users guide for
more details.
For the {peri/lps} style:
K (force/area units)
G (force/area units)
horizon (distance units)
s00 (unitless)
alpha (unitless) :ul
K is the bulk modulus and G is the shear modulus. The horizon is a
cutoff distance for truncating interactions, and s00 and alpha are
used as a bond breaking criteria. See the users guide for more
details.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
These pair styles do not support the "pair_modify"_pair_modify.html
shift option.
The "pair_modify"_pair_modify.html table and tail options are not
relevant for these pair styles.
These pair styles write their information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
The {peri/pmb} and {peri/lps} styles are part of the PERI
package. They are only enabled if LAMMPS was built with that package.
See the "Making LAMMPS"_Section_start.html#start_3 section for more
info.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Parks)
[(Parks)] Parks, Lehoucq, Plimpton, Silling, Comp Phys Comm, 179(11), 777-783 (2008).
:link(Silling2000)
[(Silling 2000)] Silling, J Mech Phys Solids, 48, 175-209 (2000).
:link(Silling2007)
[(Silling 2007)] Silling, Epton, Weckner, Xu, Askari, J Elasticity, 88, 151-184 (2007).
diff --git a/doc/pair_resquared.html b/doc/pair_resquared.html
index 63e274fb5..ebca4fe03 100644
--- a/doc/pair_resquared.html
+++ b/doc/pair_resquared.html
@@ -1,243 +1,243 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style resquared command
</H3>
<H3>pair_style resquared/gpu command
</H3>
<H3>pair_style resquared/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style resquared cutoff
</PRE>
<UL><LI>cutoff = global cutoff for interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style resquared 10.0
pair_coeff * * 1.0 1.0 1.7 3.4 3.4 1.0 1.0 1.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>resquared</I> computes the RE-squared anisotropic interaction
<A HREF = "#Everaers">(Everaers)</A>, <A HREF = "#Babadi">(Babadi)</A> between pairs of
ellipsoidal and/or spherical Lennard-Jones particles. For ellipsoidal
interactions, the potential considers the ellipsoid as being comprised
of small spheres of size sigma. LJ particles are a single sphere of
size sigma. The distinction is made to allow the pair style to make
efficient calculations of ellipsoid/solvent interactions.
</P>
<P>Details for the equations used are given in the references below and
in <A HREF = "PDF/pair_resquared_extra.pdf">this supplementary document</A>.
</P>
<P>Use of this pair style requires the NVE, NVT, or NPT fixes with the
<I>asphere</I> extension (e.g. <A HREF = "fix_nve_asphere.html">fix nve/asphere</A>) in
order to integrate particle rotation. Additionally, <A HREF = "atom_style.html">atom_style
ellipsoid</A> should be used since it defines the
rotational state and the size and shape of each ellipsoidal particle.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>A12 = Energy Prefactor/Hamaker constant (energy units)
<LI>sigma = atomic interaction diameter (distance units)
<LI>epsilon_i_a = relative well depth of type I for side-to-side interactions
<LI>epsilon_i_b = relative well depth of type I for face-to-face interactions
<LI>epsilon_i_c = relative well depth of type I for end-to-end interactions
<LI>epsilon_j_a = relative well depth of type J for side-to-side interactions
<LI>epsilon_j_b = relative well depth of type J for face-to-face interactions
<LI>epsilon_j_c = relative well depth of type J for end-to-end interactions
<LI>cutoff (distance units)
</UL>
<P>The parameters used depend on the type of the interacting particles,
i.e. ellipsoids or LJ spheres. The type of a particle is determined
by the diameters specified for its 3 shape paramters. If all 3 shape
parameters = 0.0, then the particle is treated as an LJ sphere. The
epsilon_i_* or epsilon_j_* parameters are ignored for LJ spheres. If
the 3 shape paraemters are > 0.0, then the particle is treated as an
ellipsoid (even if the 3 parameters are equal to each other).
</P>
<P>A12 specifies the energy prefactor which depends on the types of the
two interacting particles.
</P>
<P>For ellipsoid/ellipsoid interactions, the interaction is computed by
the formulas in the supplementary docuement referenced above. A12 is
the Hamaker constant as described in <A HREF = "#Everaers">(Everaers)</A>. In LJ
units:
</P>
<CENTER><IMG SRC = "Eqs/pair_resquared.jpg">
</CENTER>
<P>where rho gives the number density of the spherical particles
composing the ellipsoids and epsilon_LJ determines the interaction
strength of the spherical particles.
</P>
<P>For ellipsoid/LJ sphere interactions, the interaction is also computed
by the formulas in the supplementary docuement referenced above. A12
has a modifed form (see <A HREF = "PDF/pair_resquared_extra.pdf">here</A> for
details):
</P>
<CENTER><IMG SRC = "Eqs/pair_resquared2.jpg">
</CENTER>
<P>For ellipsoid/LJ sphere interactions, a correction to the distance-
of-closest approach equation has been implemented to reduce the error
from two particles of disparate sizes; see <A HREF = "PDF/pair_resquared_extra.pdf">this supplementary
document</A>.
</P>
<P>For LJ sphere/LJ sphere interactions, the interaction is computed
using the standard Lennard-Jones formula, which is much cheaper to
compute than the ellipsoidal formulas. A12 is used as epsilon in the
standard LJ formula:
</P>
<CENTER><IMG SRC = "Eqs/pair_resquared3.jpg">
</CENTER>
<P>and the specified <I>sigma</I> is used as the sigma in the standard LJ
formula.
</P>
<P>When one of both of the interacting particles are ellipsoids, then
<I>sigma</I> specifies the diameter of the continuous distribution of
constituent particles within each ellipsoid used to model the
RE-squared potential. Note that this is a different meaning for
<I>sigma</I> than the <A HREF = "pair_gayberne.html">pair_style gayberne</A> potential
uses.
</P>
<P>The epsilon_i and epsilon_j coefficients are defined for atom types,
not for pairs of atom types. Thus, in a series of pair_coeff
commands, they only need to be specified once for each atom type.
</P>
<P>Specifically, if any of epsilon_i_a, epsilon_i_b, epsilon_i_c are
non-zero, the three values are assigned to atom type I. If all the
epsilon_i values are zero, they are ignored. If any of epsilon_j_a,
epsilon_j_b, epsilon_j_c are non-zero, the three values are assigned
to atom type J. If all three epsilon_i values are zero, they are
ignored. Thus the typical way to define the epsilon_i and epsilon_j
coefficients is to list their values in "pair_coeff I J" commands when
I = J, but set them to 0.0 when I != J. If you do list them when I !=
J, you should insure they are consistent with their values in other
pair_coeff commands.
</P>
<P>Note that if this potential is being used as a sub-style of
<A HREF = "pair_hybrid.html">pair_style hybrid</A>, and there is no "pair_coeff I I"
setting made for RE-squared for a particular type I (because I-I
interactions are computed by another hybrid pair potential), then you
still need to insure the epsilon a,b,c coefficients are assigned to
that type in a "pair_coeff I J" command.
</P>
<P>For large uniform molecules it has been shown that the epsilon_*_*
energy parameters are approximately representable in terms of local
contact curvatures <A HREF = "#Everaers">(Everaers)</A>:
</P>
<CENTER><IMG SRC = "Eqs/pair_resquared4.jpg">
</CENTER>
<P>where a, b, and c give the particle diameters.
</P>
<P>The last coefficient is optional. If not specified, the global cutoff
specified in the pair_style command is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance can be mixed, but only for sphere pairs. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details. Other type pairs cannot be mixed, due to the different
meanings of the energy prefactors used to calculate the interactions
and the implicit dependence of the ellipsoid-sphere interaction on the
equation for the Hamaker constant presented here. Mixing of sigma and
epsilon followed by calculation of the energy prefactors using the
equations above is recommended.
</P>
<P>This pair styles supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the Lennard-Jones portion of the pair
interaction, but only for sphere-sphere interactions. There is no
shifting performed for ellipsoidal interactions due to the anisotropic
dependence of the interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords of the <A HREF = "run_style.html">run_style
command</A>.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>This pair style requires that atoms be ellipsoids as defined by the
<A HREF = "atom_style.html">atom_style ellipsoid</A> command.
</P>
<P>Particles acted on by the potential can be extended aspherical or
spherical particles, or point particles. Spherical particles have all
3 of their shape parameters equal to each other. Point particles have
all 3 of their shape parameters equal to 0.0.
</P>
<P>The distance-of-closest-approach approximation used by LAMMPS becomes
less accurate when high-aspect ratio ellipsoids are used.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "fix_nve_asphere.html">fix nve/asphere</A>,
<A HREF = "compute_temp_asphere.html">compute temp/asphere</A>, <A HREF = "pair_gayberne.html">pair_style
gayberne</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Everaers"></A>
<P><B>(Everaers)</B> Everaers and Ejtehadi, Phys Rev E, 67, 041710 (2003).
</P>
<A NAME = "Babadi"></A>
<P><B>(Berardi)</B> Babadi, Ejtehadi, Everaers, J Comp Phys, 219, 770-779 (2006).
</P>
</HTML>
diff --git a/doc/pair_resquared.txt b/doc/pair_resquared.txt
index 0762b0522..d364346f7 100755
--- a/doc/pair_resquared.txt
+++ b/doc/pair_resquared.txt
@@ -1,234 +1,234 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style resquared command :h3
pair_style resquared/gpu command :h3
pair_style resquared/omp command :h3
[Syntax:]
pair_style resquared cutoff :pre
cutoff = global cutoff for interactions (distance units) :ul
[Examples:]
pair_style resquared 10.0
pair_coeff * * 1.0 1.0 1.7 3.4 3.4 1.0 1.0 1.0 :pre
[Description:]
Style {resquared} computes the RE-squared anisotropic interaction
"(Everaers)"_#Everaers, "(Babadi)"_#Babadi between pairs of
ellipsoidal and/or spherical Lennard-Jones particles. For ellipsoidal
interactions, the potential considers the ellipsoid as being comprised
of small spheres of size sigma. LJ particles are a single sphere of
size sigma. The distinction is made to allow the pair style to make
efficient calculations of ellipsoid/solvent interactions.
Details for the equations used are given in the references below and
in "this supplementary document"_PDF/pair_resquared_extra.pdf.
Use of this pair style requires the NVE, NVT, or NPT fixes with the
{asphere} extension (e.g. "fix nve/asphere"_fix_nve_asphere.html) in
order to integrate particle rotation. Additionally, "atom_style
ellipsoid"_atom_style.html should be used since it defines the
rotational state and the size and shape of each ellipsoidal particle.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands:
A12 = Energy Prefactor/Hamaker constant (energy units)
sigma = atomic interaction diameter (distance units)
epsilon_i_a = relative well depth of type I for side-to-side interactions
epsilon_i_b = relative well depth of type I for face-to-face interactions
epsilon_i_c = relative well depth of type I for end-to-end interactions
epsilon_j_a = relative well depth of type J for side-to-side interactions
epsilon_j_b = relative well depth of type J for face-to-face interactions
epsilon_j_c = relative well depth of type J for end-to-end interactions
cutoff (distance units) :ul
The parameters used depend on the type of the interacting particles,
i.e. ellipsoids or LJ spheres. The type of a particle is determined
by the diameters specified for its 3 shape paramters. If all 3 shape
parameters = 0.0, then the particle is treated as an LJ sphere. The
epsilon_i_* or epsilon_j_* parameters are ignored for LJ spheres. If
the 3 shape paraemters are > 0.0, then the particle is treated as an
ellipsoid (even if the 3 parameters are equal to each other).
A12 specifies the energy prefactor which depends on the types of the
two interacting particles.
For ellipsoid/ellipsoid interactions, the interaction is computed by
the formulas in the supplementary docuement referenced above. A12 is
the Hamaker constant as described in "(Everaers)"_#Everaers. In LJ
units:
:c,image(Eqs/pair_resquared.jpg)
where rho gives the number density of the spherical particles
composing the ellipsoids and epsilon_LJ determines the interaction
strength of the spherical particles.
For ellipsoid/LJ sphere interactions, the interaction is also computed
by the formulas in the supplementary docuement referenced above. A12
has a modifed form (see "here"_PDF/pair_resquared_extra.pdf for
details):
:c,image(Eqs/pair_resquared2.jpg)
For ellipsoid/LJ sphere interactions, a correction to the distance-
of-closest approach equation has been implemented to reduce the error
from two particles of disparate sizes; see "this supplementary
document"_PDF/pair_resquared_extra.pdf.
For LJ sphere/LJ sphere interactions, the interaction is computed
using the standard Lennard-Jones formula, which is much cheaper to
compute than the ellipsoidal formulas. A12 is used as epsilon in the
standard LJ formula:
:c,image(Eqs/pair_resquared3.jpg)
and the specified {sigma} is used as the sigma in the standard LJ
formula.
When one of both of the interacting particles are ellipsoids, then
{sigma} specifies the diameter of the continuous distribution of
constituent particles within each ellipsoid used to model the
RE-squared potential. Note that this is a different meaning for
{sigma} than the "pair_style gayberne"_pair_gayberne.html potential
uses.
The epsilon_i and epsilon_j coefficients are defined for atom types,
not for pairs of atom types. Thus, in a series of pair_coeff
commands, they only need to be specified once for each atom type.
Specifically, if any of epsilon_i_a, epsilon_i_b, epsilon_i_c are
non-zero, the three values are assigned to atom type I. If all the
epsilon_i values are zero, they are ignored. If any of epsilon_j_a,
epsilon_j_b, epsilon_j_c are non-zero, the three values are assigned
to atom type J. If all three epsilon_i values are zero, they are
ignored. Thus the typical way to define the epsilon_i and epsilon_j
coefficients is to list their values in "pair_coeff I J" commands when
I = J, but set them to 0.0 when I != J. If you do list them when I !=
J, you should insure they are consistent with their values in other
pair_coeff commands.
Note that if this potential is being used as a sub-style of
"pair_style hybrid"_pair_hybrid.html, and there is no "pair_coeff I I"
setting made for RE-squared for a particular type I (because I-I
interactions are computed by another hybrid pair potential), then you
still need to insure the epsilon a,b,c coefficients are assigned to
that type in a "pair_coeff I J" command.
For large uniform molecules it has been shown that the epsilon_*_*
energy parameters are approximately representable in terms of local
contact curvatures "(Everaers)"_#Everaers:
:c,image(Eqs/pair_resquared4.jpg)
where a, b, and c give the particle diameters.
The last coefficient is optional. If not specified, the global cutoff
specified in the pair_style command is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance can be mixed, but only for sphere pairs. The
default mix value is {geometric}. See the "pair_modify" command for
details. Other type pairs cannot be mixed, due to the different
meanings of the energy prefactors used to calculate the interactions
and the implicit dependence of the ellipsoid-sphere interaction on the
equation for the Hamaker constant presented here. Mixing of sigma and
epsilon followed by calculation of the energy prefactors using the
equations above is recommended.
This pair styles supports the "pair_modify"_pair_modify.html shift
option for the energy of the Lennard-Jones portion of the pair
interaction, but only for sphere-sphere interactions. There is no
shifting performed for ellipsoidal interactions due to the anisotropic
dependence of the interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords of the "run_style
command"_run_style.html.
:line
[Restrictions:]
This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires that atoms be ellipsoids as defined by the
"atom_style ellipsoid"_atom_style.html command.
Particles acted on by the potential can be extended aspherical or
spherical particles, or point particles. Spherical particles have all
3 of their shape parameters equal to each other. Point particles have
all 3 of their shape parameters equal to 0.0.
The distance-of-closest-approach approximation used by LAMMPS becomes
less accurate when high-aspect ratio ellipsoids are used.
[Related commands:]
"pair_coeff"_pair_coeff.html, "fix nve/asphere"_fix_nve_asphere.html,
"compute temp/asphere"_compute_temp_asphere.html, "pair_style
gayberne"_pair_gayberne.html
[Default:] none
:line
:link(Everaers)
[(Everaers)] Everaers and Ejtehadi, Phys Rev E, 67, 041710 (2003).
:link(Babadi)
[(Berardi)] Babadi, Ejtehadi, Everaers, J Comp Phys, 219, 770-779 (2006).
diff --git a/doc/pair_sdk.html b/doc/pair_sdk.html
new file mode 100644
index 000000000..c2f9a76c3
--- /dev/null
+++ b/doc/pair_sdk.html
@@ -0,0 +1,166 @@
+<HTML>
+<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
+</CENTER>
+
+
+
+
+
+
+<HR>
+
+<H3>pair_style lj/sdk command
+</H3>
+<H3>pair_style lj/sdk/gpu command
+</H3>
+<H3>pair_style lj/sdk/omp command
+</H3>
+<H3>pair_style lj/sdk/coul/long command
+</H3>
+<H3>pair_style lj/sdk/coul/long/gpu command
+</H3>
+<H3>pair_style lj/sdk/coul/long/omp command
+</H3>
+<P><B>Syntax:</B>
+</P>
+<PRE>pair_style style args
+</PRE>
+<UL><LI>style = <I>lj/sdk</I> or <I>lj/sdk/coul/long</I>
+<LI>args = list of arguments for a particular style
+</UL>
+<PRE> <I>lj/sdk</I> args = cutoff
+ cutoff = global cutoff for Lennard Jones interactions (distance units)
+ <I>lj/sdk/coul/long</I> args = cutoff (cutoff2)
+ cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
+ cutoff2 = global cutoff for Coulombic (optional) (distance units)
+</PRE>
+<P><B>Examples:</B>
+</P>
+<PRE>pair_style lj/sdk 2.5
+pair_coeff 1 1 lj12_6 1 1.1 2.8
+</PRE>
+<PRE>pair_style lj/sdk/coul/long 10.0
+pair_style lj/sdk/coul/long 10.0 12.0
+pair_coeff 1 1 lj9_6 100.0 3.5 12.0
+</PRE>
+<P><B>Description:</B>
+</P>
+<P>The <I>lj/sdk</I> styles compute a 9/6, 12/4, or 12/6 Lennard-Jones potential,
+given by
+</P>
+<CENTER><IMG SRC = "Eqs/pair_cmm.jpg">
+</CENTER>
+<P>as required for the SDK Coarse-grained MD parametrization discussed in
+<A HREF = "#Shinoda">(Shinoda)</A> and <A HREF = "#DeVane">(DeVane)</A>. Rc is the cutoff.
+</P>
+<P>Style <I>lj/sdk/coul/long</I> computes the adds Coulombic interactions
+with an additional damping factor applied so it can be used in
+conjunction with the <A HREF = "kspace_style.html">kspace_style</A> command and
+its <I>ewald</I> or <I>pppm</I> or <I>pppm/cg</I> option. The Coulombic cutoff
+specified for this style means that pairwise interactions within
+this distance are computed directly; interactions outside that
+distance are computed in reciprocal space.
+</P>
+<P>The following coefficients must be defined for each pair of atoms
+types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
+above, or in the data file or restart files read by the
+<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
+commands, or by mixing as described below:
+</P>
+<UL><LI>cg_type (lj9_6, lj12_4, or lj12_6)
+<LI>epsilon (energy units)
+<LI>sigma (distance units)
+<LI>cutoff1 (distance units)
+</UL>
+<P>Note that sigma is defined in the LJ formula as the zero-crossing
+distance for the potential, not as the energy minimum. The prefactors
+are chosen so that the potential minimum is at -epsilon.
+</P>
+<P>The latter 2 coefficients are optional. If not specified, the global
+LJ and Coulombic cutoffs specified in the pair_style command are used.
+If only one cutoff is specified, it is used as the cutoff for both LJ
+and Coulombic interactions for this type pair. If both coefficients
+are specified, they are used as the LJ and Coulombic cutoffs for this
+type pair.
+</P>
+<P>For <I>lj/sdk/coul/long</I> only the LJ cutoff can be specified since a
+Coulombic cutoff cannot be specified for an individual I,J type pair.
+All type pairs use the same global Coulombic cutoff specified in the
+pair_style command.
+</P>
+<HR>
+
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I> or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP, and
+OPT packages respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
+<P><B>Mixing, shift, table, tail correction, restart, and rRESPA info</B>:
+</P>
+<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of the lj/sdk pair styles <I>cannot</I> be mixed,
+since different pairs may have different exponents. So all parameters
+for all pairs have to be specified explicitly through the "pair_coeff"
+command. Defining then in a data file is also not supported, due to
+limitations of that file format.
+</P>
+<P>All of the lj/sdk pair styles support the
+<A HREF = "pair_modify.html">pair_modify</A> shift option for the energy of the
+Lennard-Jones portion of the pair interaction.
+</P>
+<P>The <I>lj/sdk/coul/long</I> pair styles support the
+<A HREF = "pair_modify.html">pair_modify</A> table option since they can tabulate
+the short-range portion of the long-range Coulombic interaction.
+</P>
+<P>All of the lj/sdk pair styles write their information to <A HREF = "restart.html">binary
+restart files</A>, so pair_style and pair_coeff commands do
+not need to be specified in an input script that reads a restart file.
+</P>
+<P>The lj/sdk and lj/cut/coul/long pair styles do not support
+the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I> keywords of the <A HREF = "run_style.html">run_style
+respa</A> command.
+</P>
+<HR>
+
+<P><B>Restrictions:</B>
+</P>
+<P>All of the lj/sdk pair styles are part of the USER-CG-CMM package.
+The <I>lj/sdk/coul/long</I> style also requires the KSPACE package to be
+built (which is enabled by default). They are only enabled if LAMMPS
+was built with that package. See the <A HREF = "Section_start.html#start_3">Making
+LAMMPS</A> section for more info.
+</P>
+<P><B>Related commands:</B>
+</P>
+<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "angle_sdk.html">angle_style sdk</A>
+</P>
+<P><B>Default:</B> none
+</P>
+<HR>
+
+<A NAME = "Shinoda"></A>
+
+<P><B>(Shinoda)</B> Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007).
+</P>
+<A NAME = "DeVane"></A>
+
+<P><B>(DeVane)</B> Shinoda, DeVane, Klein, Soft Matter, 4, 2453-2462 (2008).
+</P>
+</HTML>
diff --git a/doc/pair_sdk.txt b/doc/pair_sdk.txt
new file mode 100644
index 000000000..536be2a6e
--- /dev/null
+++ b/doc/pair_sdk.txt
@@ -0,0 +1,154 @@
+"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
+
+:link(lws,http://lammps.sandia.gov)
+:link(ld,Manual.html)
+:link(lc,Section_commands.html#comm)
+
+:line
+
+pair_style lj/sdk command :h3
+pair_style lj/sdk/gpu command :h3
+pair_style lj/sdk/omp command :h3
+pair_style lj/sdk/coul/long command :h3
+pair_style lj/sdk/coul/long/gpu command :h3
+pair_style lj/sdk/coul/long/omp command :h3
+
+[Syntax:]
+
+pair_style style args :pre
+
+style = {lj/sdk} or {lj/sdk/coul/long}
+args = list of arguments for a particular style :ul
+ {lj/sdk} args = cutoff
+ cutoff = global cutoff for Lennard Jones interactions (distance units)
+ {lj/sdk/coul/long} args = cutoff (cutoff2)
+ cutoff = global cutoff for LJ (and Coulombic if only 1 arg) (distance units)
+ cutoff2 = global cutoff for Coulombic (optional) (distance units) :pre
+
+[Examples:]
+
+pair_style lj/sdk 2.5
+pair_coeff 1 1 lj12_6 1 1.1 2.8 :pre
+
+pair_style lj/sdk/coul/long 10.0
+pair_style lj/sdk/coul/long 10.0 12.0
+pair_coeff 1 1 lj9_6 100.0 3.5 12.0 :pre
+
+[Description:]
+
+The {lj/sdk} styles compute a 9/6, 12/4, or 12/6 Lennard-Jones potential,
+given by
+
+:c,image(Eqs/pair_cmm.jpg)
+
+as required for the SDK Coarse-grained MD parametrization discussed in
+"(Shinoda)"_#Shinoda and "(DeVane)"_#DeVane. Rc is the cutoff.
+
+Style {lj/sdk/coul/long} computes the adds Coulombic interactions
+with an additional damping factor applied so it can be used in
+conjunction with the "kspace_style"_kspace_style.html command and
+its {ewald} or {pppm} or {pppm/cg} option. The Coulombic cutoff
+specified for this style means that pairwise interactions within
+this distance are computed directly; interactions outside that
+distance are computed in reciprocal space.
+
+The following coefficients must be defined for each pair of atoms
+types via the "pair_coeff"_pair_coeff.html command as in the examples
+above, or in the data file or restart files read by the
+"read_data"_read_data.html or "read_restart"_read_restart.html
+commands, or by mixing as described below:
+
+cg_type (lj9_6, lj12_4, or lj12_6)
+epsilon (energy units)
+sigma (distance units)
+cutoff1 (distance units) :ul
+
+Note that sigma is defined in the LJ formula as the zero-crossing
+distance for the potential, not as the energy minimum. The prefactors
+are chosen so that the potential minimum is at -epsilon.
+
+The latter 2 coefficients are optional. If not specified, the global
+LJ and Coulombic cutoffs specified in the pair_style command are used.
+If only one cutoff is specified, it is used as the cutoff for both LJ
+and Coulombic interactions for this type pair. If both coefficients
+are specified, they are used as the LJ and Coulombic cutoffs for this
+type pair.
+
+For {lj/sdk/coul/long} only the LJ cutoff can be specified since a
+Coulombic cutoff cannot be specified for an individual I,J type pair.
+All type pairs use the same global Coulombic cutoff specified in the
+pair_style command.
+
+:line
+
+Styles with a {cuda}, {gpu}, {omp} or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP, and
+OPT packages respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
+[Mixing, shift, table, tail correction, restart, and rRESPA info]:
+
+For atom type pairs I,J and I != J, the epsilon and sigma coefficients
+and cutoff distance for all of the lj/sdk pair styles {cannot} be mixed,
+since different pairs may have different exponents. So all parameters
+for all pairs have to be specified explicitly through the "pair_coeff"
+command. Defining then in a data file is also not supported, due to
+limitations of that file format.
+
+All of the lj/sdk pair styles support the
+"pair_modify"_pair_modify.html shift option for the energy of the
+Lennard-Jones portion of the pair interaction.
+
+The {lj/sdk/coul/long} pair styles support the
+"pair_modify"_pair_modify.html table option since they can tabulate
+the short-range portion of the long-range Coulombic interaction.
+
+All of the lj/sdk pair styles write their information to "binary
+restart files"_restart.html, so pair_style and pair_coeff commands do
+not need to be specified in an input script that reads a restart file.
+
+The lj/sdk and lj/cut/coul/long pair styles do not support
+the use of the {inner}, {middle}, and {outer} keywords of the "run_style
+respa"_run_style.html command.
+
+:line
+
+[Restrictions:]
+
+All of the lj/sdk pair styles are part of the USER-CG-CMM package.
+The {lj/sdk/coul/long} style also requires the KSPACE package to be
+built (which is enabled by default). They are only enabled if LAMMPS
+was built with that package. See the "Making
+LAMMPS"_Section_start.html#start_3 section for more info.
+
+[Related commands:]
+
+"pair_coeff"_pair_coeff.html, "angle_style sdk"_angle_sdk.html
+
+[Default:] none
+
+:line
+
+:link(Shinoda)
+[(Shinoda)] Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007).
+
+:link(DeVane)
+[(DeVane)] Shinoda, DeVane, Klein, Soft Matter, 4, 2453-2462 (2008).
+
diff --git a/doc/pair_soft.html b/doc/pair_soft.html
index 145056ece..0376c6fe5 100644
--- a/doc/pair_soft.html
+++ b/doc/pair_soft.html
@@ -1,140 +1,140 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style soft command
</H3>
<H3>pair_style soft/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style soft cutoff
</PRE>
<UL><LI>cutoff = global cutoff for soft interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style soft 2.5
pair_coeff * * 10.0
pair_coeff 1 1 10.0 3.0
</PRE>
<PRE>pair_style soft 2.5
pair_coeff * * 0.0
variable prefactor equal ramp(0,30)
fix 1 all adapt 1 pair soft a * * v_prefactor
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>soft</I> computes pairwise interactions with the formula
</P>
<CENTER><IMG SRC = "Eqs/pair_soft.jpg">
</CENTER>
<P>It is useful for pushing apart overlapping atoms, since it does not
blow up as r goes to 0. A is a pre-factor that can be made to vary in
time from the start to the end of the run (see discussion below),
e.g. to start with a very soft potential and slowly harden the
interactions over time. Rc is the cutoff. See the <A HREF = "fix_nve_limit.html">fix
nve/limit</A> command for another way to push apart
overlapping atoms.
</P>
<P>The following coefficients must be defined for each pair of atom types
via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples above,
or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>A (energy units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global soft
cutoff is used.
</P>
<P>IMPORTANT NOTE: The syntax for <A HREF = "pair_coeff.html">pair_coeff</A> with a
single A coeff is different in the current version of LAMMPS than in
older versions which took two values, Astart and Astop, to ramp
between them. This functionality is now available in a more general
form through the <A HREF = "fix_adapt.html">fix adapt</A> command, as explained
below. Note that if you use an old input script and specify Astart
and Astop without a cutoff, then LAMMPS will interpret that as A and a
cutoff, which is probabably not what you want.
</P>
<P>The <A HREF = "fix_adapt.html">fix adapt</A> command can be used to vary A for one
or more pair types over the course of a simulation, in which case
pair_coeff settings for A must still be specified, but will be
overridden. For example these commands will vary the prefactor A for
all pairwise interactions from 0.0 at the beginning to 30.0 at the end
of a run:
</P>
<PRE>variable prefactor equal ramp(0,30)
fix 1 all adapt 1 pair soft a * * v_prefactor
</PRE>
<P>Note that a formula defined by an <A HREF = "variable.html">equal-style variable</A>
can use the current timestep, elapsed time in the current run, elapsed
time since the beginning of a series of runs, as well as access other
variables.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is always mixed via a
<I>geometric</I> rule. The cutoff is mixed according to the pair_modify
mix value. The default mix value is <I>geometric</I>. See the
"pair_modify" command for details.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift option, since the pair interaction goes to 0.0 at the cutoff.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table and tail options are not
relevant for this pair style.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "fix_nve_limit.html">fix nve/limit</A>, <A HREF = "fix_adapt.html">fix
adapt</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_soft.txt b/doc/pair_soft.txt
index 14f68d7c4..d95c0d23c 100644
--- a/doc/pair_soft.txt
+++ b/doc/pair_soft.txt
@@ -1,134 +1,134 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style soft command :h3
pair_style soft/omp command :h3
[Syntax:]
pair_style soft cutoff :pre
cutoff = global cutoff for soft interactions (distance units) :ul
[Examples:]
pair_style soft 2.5
pair_coeff * * 10.0
pair_coeff 1 1 10.0 3.0 :pre
pair_style soft 2.5
pair_coeff * * 0.0
variable prefactor equal ramp(0,30)
fix 1 all adapt 1 pair soft a * * v_prefactor :pre
[Description:]
Style {soft} computes pairwise interactions with the formula
:c,image(Eqs/pair_soft.jpg)
It is useful for pushing apart overlapping atoms, since it does not
blow up as r goes to 0. A is a pre-factor that can be made to vary in
time from the start to the end of the run (see discussion below),
e.g. to start with a very soft potential and slowly harden the
interactions over time. Rc is the cutoff. See the "fix
nve/limit"_fix_nve_limit.html command for another way to push apart
overlapping atoms.
The following coefficients must be defined for each pair of atom types
via the "pair_coeff"_pair_coeff.html command as in the examples above,
or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
A (energy units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global soft
cutoff is used.
IMPORTANT NOTE: The syntax for "pair_coeff"_pair_coeff.html with a
single A coeff is different in the current version of LAMMPS than in
older versions which took two values, Astart and Astop, to ramp
between them. This functionality is now available in a more general
form through the "fix adapt"_fix_adapt.html command, as explained
below. Note that if you use an old input script and specify Astart
and Astop without a cutoff, then LAMMPS will interpret that as A and a
cutoff, which is probabably not what you want.
The "fix adapt"_fix_adapt.html command can be used to vary A for one
or more pair types over the course of a simulation, in which case
pair_coeff settings for A must still be specified, but will be
overridden. For example these commands will vary the prefactor A for
all pairwise interactions from 0.0 at the beginning to 30.0 at the end
of a run:
variable prefactor equal ramp(0,30)
fix 1 all adapt 1 pair soft a * * v_prefactor :pre
Note that a formula defined by an "equal-style variable"_variable.html
can use the current timestep, elapsed time in the current run, elapsed
time since the beginning of a series of runs, as well as access other
variables.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is always mixed via a
{geometric} rule. The cutoff is mixed according to the pair_modify
mix value. The default mix value is {geometric}. See the
"pair_modify" command for details.
This pair style does not support the "pair_modify"_pair_modify.html
shift option, since the pair interaction goes to 0.0 at the cutoff.
The "pair_modify"_pair_modify.html table and tail options are not
relevant for this pair style.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html, "fix nve/limit"_fix_nve_limit.html, "fix
adapt"_fix_adapt.html
[Default:] none
diff --git a/doc/pair_style.html b/doc/pair_style.html
index c192fce8a..c146e10b2 100644
--- a/doc/pair_style.html
+++ b/doc/pair_style.html
@@ -1,192 +1,194 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = one of the styles from the list below
<LI>args = arguments used by a particular style
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/cut 2.5
pair_style eam/alloy
pair_style hybrid lj/charmm/coul/long 10.0 eam
pair_style table linear 1000
pair_style none
</PRE>
<P><B>Description:</B>
</P>
<P>Set the formula(s) LAMMPS uses to compute pairwise interactions. In
LAMMPS, pair potentials are defined between pairs of atoms that are
within a cutoff distance and the set of active interactions typically
changes over time. See the <A HREF = "bond_style.html">bond_style</A> command to
define potentials between pairs of bonded atoms, which typically
remain in place for the duration of a simulation.
</P>
<P>In LAMMPS, pairwise force fields encompass a variety of interactions,
some of which include many-body effects, e.g. EAM, Stillinger-Weber,
Tersoff, REBO potentials. They are still classified as "pairwise"
potentials because the set of interacting atoms changes with time
(unlike molecular bonds) and thus a neighbor list is used to find
nearby interacting atoms.
</P>
<P>Hybrid models where specified pairs of atom types interact via
different pair potentials can be setup using the <I>hybrid</I> pair style.
</P>
<P>The coefficients associated with a pair style are typically set for
each pair of atom types, and are specified by the
<A HREF = "pair_coeff.html">pair_coeff</A> command or read from a file by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> command sets options for mixing of
type I-J interaction coefficients and adding energy offsets or tail
corrections to Lennard-Jones potentials. Details on these options as
they pertain to individual potentials are described on the doc page
for the potential. Likewise, info on whether the potential
information is stored in a <A HREF = "write_restart.html">restart file</A> is listed
on the potential doc page.
</P>
<P>In the formulas listed for each pair style, <I>E</I> is the energy of a
pairwise interaction between two atoms separated by a distance <I>r</I>.
The force between the atoms is the negative derivative of this
expression.
</P>
<P>If the pair_style command has a cutoff argument, it sets global
cutoffs for all pairs of atom types. The distance(s) can be smaller
or larger than the dimensions of the simulation box.
</P>
<P>Typically, the global cutoff value can be overridden for a specific
pair of atom types by the <A HREF = "pair_coeff.html">pair_coeff</A> command. The
pair style settings (including global cutoffs) can be changed by a
subsequent pair_style command using the same style. This will reset
the cutoffs for all atom type pairs, including those previously set
explicitly by a <A HREF = "pair_coeff.html">pair_coeff</A> command. The exceptions
to this are that pair_style <I>table</I> and <I>hybrid</I> settings cannot be
reset. A new pair_style command for these styles will wipe out all
previously specified pair_coeff values.
</P>
<HR>
<P>Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
<A HREF = "pair_coeff.html">pair_coeff</A> command:
</P>
<UL><LI><A HREF = "pair_none.html">pair_style none</A> - turn off pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid</A> - multiple styles of pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid/overlay</A> - multiple styles of superposed pairwise interactions
</UL>
<UL><LI><A HREF = "pair_adp.html">pair_style adp</A> - angular dependent potential (ADP) of Mishin
<LI><A HREF = "pair_airebo.html">pair_style airebo</A> - AIREBO potential of Stuart
<LI><A HREF = "pair_born.html">pair_style born</A> - Born-Mayer-Huggins potential
-<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulomb
+<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulombics
+<LI><A HREF = "pair_born.html">pair_style born/coul/wolf</A> - Born-Mayer-Huggins with Coulombics via Wolf potential
<LI><A HREF = "pair_brownian.html">pair_style brownian</A> - Brownian potential for Fast Lubrication Dynamics
<LI><A HREF = "pair_brownian.html">pair_style brownian/poly</A> - Brownian potential for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_buck.html">pair_style buck</A> - Buckingham potential
<LI><A HREF = "pair_buck.html">pair_style buck/coul/cut</A> - Buckingham with cutoff Coulomb
<LI><A HREF = "pair_buck.html">pair_style buck/coul/long</A> - Buckingham with long-range Coulomb
<LI><A HREF = "pair_colloid.html">pair_style colloid</A> - integrated colloidal potential
<LI><A HREF = "pair_comb.html">pair_style comb</A> - charge-optimized many-body (COMB) potential
<LI><A HREF = "pair_coul.html">pair_style coul/cut</A> - cutoff Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/debye</A> - cutoff Coulombic potential with Debye screening
<LI><A HREF = "pair_coul.html">pair_style coul/long</A> - long-range Coulombic potential
+<LI><A HREF = "pair_coul.html">pair_style coul/wolf</A> - Coulombics via Wolf potential
<LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A> - point dipoles with cutoff
<LI><A HREF = "pair_dpd.html">pair_style dpd</A> - dissipative particle dynamics (DPD)
<LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A> - DPD thermostatting
<LI><A HREF = "pair_dsmc.html">pair_style dsmc</A> - Direct Simulation Monte Carlo (DSMC)
<LI><A HREF = "pair_eam.html">pair_style eam</A> - embedded atom method (EAM)
<LI><A HREF = "pair_eam.html">pair_style eam/alloy</A> - alloy EAM
<LI><A HREF = "pair_eam.html">pair_style eam/fs</A> - Finnis-Sinclair EAM
<LI><A HREF = "pair_eim.html">pair_style eim</A> - embedded ion method (EIM)
<LI><A HREF = "pair_gauss.html">pair_style gauss</A> - Gaussian potential
<LI><A HREF = "pair_gayberne.html">pair_style gayberne</A> - Gay-Berne ellipsoidal potential
<LI><A HREF = "pair_gran.html">pair_style gran/hertz/history</A> - granular potential with Hertzian interactions
<LI><A HREF = "pair_gran.html">pair_style gran/hooke</A> - granular potential with history effects
<LI><A HREF = "pair_gran.html">pair_style gran/hooke/history</A> - granular potential without history effects
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/lj</A> - DREIDING hydrogen bonding LJ potential
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/morse</A> - DREIDING hydrogen bonding Morse potential
<LI><A HREF = "pair_line_lj.html">pair_style line/lj</A> - LJ potential between line segments
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm</A> - CHARMM potential with cutoff Coulomb
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm/implicit</A> - CHARMM for implicit solvent
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/long</A> - CHARMM with long-range Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2</A> - COMPASS (class 2) force field with no Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/cut</A> - COMPASS with cutoff Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/long</A> - COMPASS with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut</A> - cutoff Lennard-Jones potential with no Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/cut</A> - LJ with cutoff Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/debye</A> - LJ with Debye screening added to Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long</A> - LJ with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long/tip4p</A> - LJ with long-range Coulomb for TIP4P water
<LI><A HREF = "pair_lj_expand.html">pair_style lj/expand</A> - Lennard-Jones for variable size particles
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs</A> - GROMACS-style Lennard-Jones potential
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs/coul/gromacs</A> - GROMACS-style LJ and Coulombic potential
<LI><A HREF = "pair_lj_smooth.html">pair_style lj/smooth</A> - smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj96.html">pair_style lj96/cut</A> - Lennard-Jones 9/6 potential
<LI><A HREF = "pair_lubricate.html">pair_style lubricate</A> - hydrodynamic lubrication forces
<LI><A HREF = "pair_lubricate.html">pair_style lubricate/poly</A> - hydrodynamic lubrication forces with polydispersity
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU/poly</A> - hydrodynamic lubrication forces for Fast Lubrication with polydispersity
<LI><A HREF = "pair_meam.html">pair_style meam</A> - modified embedded atom method (MEAM)
<LI><A HREF = "pair_morse.html">pair_style morse</A> - Morse potential
<LI><A HREF = "pair_peri.html">pair_style peri/lps</A> - peridynamic LPS potential
<LI><A HREF = "pair_peri.html">pair_style peri/pmb</A> - peridynamic PMB potential
<LI><A HREF = "pair_reax.html">pair_style reax</A> - ReaxFF potential
<LI><A HREF = "pair_airebo.html">pair_style rebo</A> - 2nd generation REBO potential of Brenner
<LI><A HREF = "pair_resquared.html">pair_style resquared</A> - Everaers RE-Squared ellipsoidal potential
<LI><A HREF = "pair_soft.html">pair_style soft</A> - Soft (cosine) potential
<LI><A HREF = "pair_sw.html">pair_style sw</A> - Stillinger-Weber 3-body potential
<LI><A HREF = "pair_table.html">pair_style table</A> - tabulated pair potential
<LI><A HREF = "pair_tersoff.html">pair_style tersoff</A> - Tersoff 3-body potential
<LI><A HREF = "pair_tersoff_zbl.html">pair_style tersoff/zbl</A> - Tersoff/ZBL 3-body potential
<LI><A HREF = "pair_tri_lj.html">pair_style tri/lj</A> - LJ potential between triangles
<LI><A HREF = "pair_yukawa.html">pair_style yukawa</A> - Yukawa potential
<LI><A HREF = "pair_yukawa_colloid.html">pair_style yukawa/colloid</A> - screened Yukawa potential for finite-size particles
</UL>
<P>There are also additional pair styles submitted by users which are
included in the LAMMPS distribution. The list of these with links to
the individual styles are given in the pair section of <A HREF = "Section_commands.html#cmd_5">this
page</A>.
</P>
<P>There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command must be used before any coefficients are set by the
<A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "read_data.html">read_data</A>, or
<A HREF = "read_restart.html">read_restart</A> commands.
</P>
<P>Some pair styles are part of specific packages. They are only enabled
if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
The doc pages for individual pair potentials tell if it is part of a
package.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "read_data.html">read_data</A>,
<A HREF = "pair_modify.html">pair_modify</A>, <A HREF = "kspace_style.html">kspace_style</A>,
<A HREF = "dielectric.html">dielectric</A>, <A HREF = "pair_write.html">pair_write</A>
</P>
<P><B>Default:</B>
</P>
<PRE>pair_style none
</PRE>
</HTML>
diff --git a/doc/pair_style.txt b/doc/pair_style.txt
index c7489246b..6535e69e2 100644
--- a/doc/pair_style.txt
+++ b/doc/pair_style.txt
@@ -1,187 +1,189 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style command :h3
[Syntax:]
pair_style style args :pre
style = one of the styles from the list below
args = arguments used by a particular style :ul
[Examples:]
pair_style lj/cut 2.5
pair_style eam/alloy
pair_style hybrid lj/charmm/coul/long 10.0 eam
pair_style table linear 1000
pair_style none :pre
[Description:]
Set the formula(s) LAMMPS uses to compute pairwise interactions. In
LAMMPS, pair potentials are defined between pairs of atoms that are
within a cutoff distance and the set of active interactions typically
changes over time. See the "bond_style"_bond_style.html command to
define potentials between pairs of bonded atoms, which typically
remain in place for the duration of a simulation.
In LAMMPS, pairwise force fields encompass a variety of interactions,
some of which include many-body effects, e.g. EAM, Stillinger-Weber,
Tersoff, REBO potentials. They are still classified as "pairwise"
potentials because the set of interacting atoms changes with time
(unlike molecular bonds) and thus a neighbor list is used to find
nearby interacting atoms.
Hybrid models where specified pairs of atom types interact via
different pair potentials can be setup using the {hybrid} pair style.
The coefficients associated with a pair style are typically set for
each pair of atom types, and are specified by the
"pair_coeff"_pair_coeff.html command or read from a file by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands.
The "pair_modify"_pair_modify.html command sets options for mixing of
type I-J interaction coefficients and adding energy offsets or tail
corrections to Lennard-Jones potentials. Details on these options as
they pertain to individual potentials are described on the doc page
for the potential. Likewise, info on whether the potential
information is stored in a "restart file"_write_restart.html is listed
on the potential doc page.
In the formulas listed for each pair style, {E} is the energy of a
pairwise interaction between two atoms separated by a distance {r}.
The force between the atoms is the negative derivative of this
expression.
If the pair_style command has a cutoff argument, it sets global
cutoffs for all pairs of atom types. The distance(s) can be smaller
or larger than the dimensions of the simulation box.
Typically, the global cutoff value can be overridden for a specific
pair of atom types by the "pair_coeff"_pair_coeff.html command. The
pair style settings (including global cutoffs) can be changed by a
subsequent pair_style command using the same style. This will reset
the cutoffs for all atom type pairs, including those previously set
explicitly by a "pair_coeff"_pair_coeff.html command. The exceptions
to this are that pair_style {table} and {hybrid} settings cannot be
reset. A new pair_style command for these styles will wipe out all
previously specified pair_coeff values.
:line
Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
"pair_coeff"_pair_coeff.html command:
"pair_style none"_pair_none.html - turn off pairwise interactions
"pair_style hybrid"_pair_hybrid.html - multiple styles of pairwise interactions
"pair_style hybrid/overlay"_pair_hybrid.html - multiple styles of superposed pairwise interactions :ul
"pair_style adp"_pair_adp.html - angular dependent potential (ADP) of Mishin
"pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart
"pair_style born"_pair_born.html - Born-Mayer-Huggins potential
-"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulomb
+"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulombics
+"pair_style born/coul/wolf"_pair_born.html - Born-Mayer-Huggins with Coulombics via Wolf potential
"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics
"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity
"pair_style buck"_pair_buck.html - Buckingham potential
"pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb
"pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb
"pair_style colloid"_pair_colloid.html - integrated colloidal potential
"pair_style comb"_pair_comb.html - charge-optimized many-body (COMB) potential
"pair_style coul/cut"_pair_coul.html - cutoff Coulombic potential
"pair_style coul/debye"_pair_coul.html - cutoff Coulombic potential with Debye screening
"pair_style coul/long"_pair_coul.html - long-range Coulombic potential
+"pair_style coul/wolf"_pair_coul.html - Coulombics via Wolf potential
"pair_style dipole/cut"_pair_dipole.html - point dipoles with cutoff
"pair_style dpd"_pair_dpd.html - dissipative particle dynamics (DPD)
"pair_style dpd/tstat"_pair_dpd.html - DPD thermostatting
"pair_style dsmc"_pair_dsmc.html - Direct Simulation Monte Carlo (DSMC)
"pair_style eam"_pair_eam.html - embedded atom method (EAM)
"pair_style eam/alloy"_pair_eam.html - alloy EAM
"pair_style eam/fs"_pair_eam.html - Finnis-Sinclair EAM
"pair_style eim"_pair_eim.html - embedded ion method (EIM)
"pair_style gauss"_pair_gauss.html - Gaussian potential
"pair_style gayberne"_pair_gayberne.html - Gay-Berne ellipsoidal potential
"pair_style gran/hertz/history"_pair_gran.html - granular potential with Hertzian interactions
"pair_style gran/hooke"_pair_gran.html - granular potential with history effects
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
"pair_style lj/class2"_pair_class2.html - COMPASS (class 2) force field with no Coulomb
"pair_style lj/class2/coul/cut"_pair_class2.html - COMPASS with cutoff Coulomb
"pair_style lj/class2/coul/long"_pair_class2.html - COMPASS with long-range Coulomb
"pair_style lj/cut"_pair_lj.html - cutoff Lennard-Jones potential with no Coulomb
"pair_style lj/cut/coul/cut"_pair_lj.html - LJ with cutoff Coulomb
"pair_style lj/cut/coul/debye"_pair_lj.html - LJ with Debye screening added to Coulomb
"pair_style lj/cut/coul/long"_pair_lj.html - LJ with long-range Coulomb
"pair_style lj/cut/coul/long/tip4p"_pair_lj.html - LJ with long-range Coulomb for TIP4P water
"pair_style lj/expand"_pair_lj_expand.html - Lennard-Jones for variable size particles
"pair_style lj/gromacs"_pair_gromacs.html - GROMACS-style Lennard-Jones potential
"pair_style lj/gromacs/coul/gromacs"_pair_gromacs.html - GROMACS-style LJ and Coulombic potential
"pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential
"pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential
"pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces
"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity
"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics
"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication with polydispersity
"pair_style meam"_pair_meam.html - modified embedded atom method (MEAM)
"pair_style morse"_pair_morse.html - Morse potential
"pair_style peri/lps"_pair_peri.html - peridynamic LPS potential
"pair_style peri/pmb"_pair_peri.html - peridynamic PMB potential
"pair_style reax"_pair_reax.html - ReaxFF potential
"pair_style rebo"_pair_airebo.html - 2nd generation REBO potential of Brenner
"pair_style resquared"_pair_resquared.html - Everaers RE-Squared ellipsoidal potential
"pair_style soft"_pair_soft.html - Soft (cosine) potential
"pair_style sw"_pair_sw.html - Stillinger-Weber 3-body potential
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
There are also additional pair styles submitted by users which are
included in the LAMMPS distribution. The list of these with links to
the individual styles are given in the pair section of "this
page"_Section_commands.html#cmd_5.
There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of "this page"_Section_commands.html#cmd_5.
:line
[Restrictions:]
This command must be used before any coefficients are set by the
"pair_coeff"_pair_coeff.html, "read_data"_read_data.html, or
"read_restart"_read_restart.html commands.
Some pair styles are part of specific packages. They are only enabled
if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
The doc pages for individual pair potentials tell if it is part of a
package.
[Related commands:]
"pair_coeff"_pair_coeff.html, "read_data"_read_data.html,
"pair_modify"_pair_modify.html, "kspace_style"_kspace_style.html,
"dielectric"_dielectric.html, "pair_write"_pair_write.html
[Default:]
pair_style none :pre
diff --git a/doc/pair_sw.html b/doc/pair_sw.html
index 6ea6f9127..67165ac0b 100644
--- a/doc/pair_sw.html
+++ b/doc/pair_sw.html
@@ -1,213 +1,213 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style sw command
</H3>
<H3>pair_style sw/cuda command
</H3>
<H3>pair_style sw/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style sw
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style sw
pair_coeff * * si.sw Si
pair_coeff * * GaN.sw Ga N Ga
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>sw</I> style computes a 3-body <A HREF = "#Stillinger">Stillinger-Weber</A>
potential for the energy E of a system of atoms as
</P>
<CENTER><IMG SRC = "Eqs/pair_sw.jpg">
</CENTER>
<P>where phi2 is a two-body term and phi3 is a three-body term. The
summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = a*sigma.
</P>
<P>Only a single pair_coeff command is used with the <I>sw</I> style which
specifies a Stillinger-Weber potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of SW elements to atom types
</UL>
<P>As an example, imagine a file SiC.sw has Stillinger-Weber values for
Si and C. If your LAMMPS simulation has 4 atoms types and you want
the 1st 3 to be Si, and the 4th to be C, you would use the following
pair_coeff command:
</P>
<PRE>pair_coeff * * SiC.sw Si Si Si C
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the SW file. The final C argument maps LAMMPS atom type 4
to the C element in the SW file. If a mapping value is specified as
NULL, the mapping is not performed. This can be used when a <I>sw</I>
potential is used as part of the <I>hybrid</I> pair style. The NULL values
are placeholders for atom types that will be used with other
potentials.
</P>
<P>Stillinger-Weber files in the <I>potentials</I> directory of the LAMMPS
distribution have a ".sw" suffix. Lines that are not blank or
comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to the two-body
and three-body coefficients in the formula above:
</P>
<UL><LI>element 1 (the center atom in a 3-body interaction)
<LI>element 2
<LI>element 3
<LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>a
<LI>lambda
<LI>gamma
<LI>costheta0
<LI>A
<LI>B
<LI>p
<LI>q
<LI>tol
</UL>
<P>The A, B, p, and q parameters are used only for two-body
interactions. The lambda and costheta0 parameters are used only for
three-body interactions. The epsilon, sigma and a parameters are used
for both two-body and three-body interactions. gamma is used only in the
three-body interactions, but is defined for pairs of atoms.
The non-annotated parameters are unitless.
</P>
<P>LAMMPS introduces an additional performance-optimization parameter tol
that is used for both two-body and three-body interactions. In the
Stillinger-Weber potential, the interaction energies become negligibly
small at atomic separations substantially less than the theoretical
cutoff distances. LAMMPS therefore defines a virtual cutoff distance
based on a user defined tolerance tol. The use of the virtual cutoff
distance in constructing atom neighbor lists can significantly reduce
the neighbor list sizes and therefore the computational cost. LAMMPS
provides a <I>tol</I> value for each of the three-body entries so that they
can be separately controlled. If tol = 0.0, then the standard
Stillinger-Weber cutoff is used.
</P>
<P>The Stillinger-Weber potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
</P>
<P>For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify SW parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
</P>
<P>As annotated above, the first element in the entry is the center atom
in a three-body interaction. Thus an entry for SiCC means a Si atom
with 2 C atoms as neighbors. The parameter values used for the
two-body interaction come from the entry where the 2nd and 3rd
elements are the same. Thus the two-body parameters for Si
interacting with C, comes from the SiCC entry. The three-body
parameters can in principle be specific to the three elements of the
configuration. In the literature, however, the three-body parameters
are usually defined by simple formulas involving two sets of pair-wise
parameters, corresponding to the ij and ik pairs, where i is the
center atom. The user must ensure that the correct combining rule is
used to calculate the values of the threebody parameters for
alloys. Note also that the function phi3 contains two exponential
screening factors with parameter values from the ij pair and ik
pairs. So phi3 for a C atom bonded to a Si atom and a second C atom
will depend on the three-body parameters for the CSiC entry, and also
on the two-body parameters for the CCC and CSiSi entries. Since the
order of the two neighbors is arbitrary, the threebody parameters for
entries CSiC and CCSi should be the same. Similarly, the two-body
parameters for entries SiCC and CSiSi should also be the same. The
parameters used only for two-body interactions (A, B, p, and q) in
entries whose 2nd and 3rd element are different (e.g. SiCSi) are not
used for anything and can be set to 0.0 if desired.
This is also true for the parameters in phi3 that are
taken from the ij and ik pairs (sigma, a, gamma)
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more info.
</P>
<P>This pair style requires the <A HREF = "newton.html">newton</A> setting to be "on"
for pair interactions.
</P>
<P>The Stillinger-Weber potential files provided with LAMMPS (see the
potentials directory) are parameterized for metal <A HREF = "units.html">units</A>.
You can use the SW potential with any LAMMPS units, but you would need
to create your own SW potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Stillinger"></A>
<P><B>(Stillinger)</B> Stillinger and Weber, Phys Rev B, 31, 5262 (1985).
</P>
</HTML>
diff --git a/doc/pair_sw.txt b/doc/pair_sw.txt
index 6395470c8..b6a8113b7 100644
--- a/doc/pair_sw.txt
+++ b/doc/pair_sw.txt
@@ -1,205 +1,205 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style sw command :h3
pair_style sw/cuda command :h3
pair_style sw/omp command :h3
[Syntax:]
pair_style sw :pre
[Examples:]
pair_style sw
pair_coeff * * si.sw Si
pair_coeff * * GaN.sw Ga N Ga :pre
[Description:]
The {sw} style computes a 3-body "Stillinger-Weber"_#Stillinger
potential for the energy E of a system of atoms as
:c,image(Eqs/pair_sw.jpg)
where phi2 is a two-body term and phi3 is a three-body term. The
summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = a*sigma.
Only a single pair_coeff command is used with the {sw} style which
specifies a Stillinger-Weber potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of SW elements to atom types :ul
As an example, imagine a file SiC.sw has Stillinger-Weber values for
Si and C. If your LAMMPS simulation has 4 atoms types and you want
the 1st 3 to be Si, and the 4th to be C, you would use the following
pair_coeff command:
pair_coeff * * SiC.sw Si Si Si C :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the SW file. The final C argument maps LAMMPS atom type 4
to the C element in the SW file. If a mapping value is specified as
NULL, the mapping is not performed. This can be used when a {sw}
potential is used as part of the {hybrid} pair style. The NULL values
are placeholders for atom types that will be used with other
potentials.
Stillinger-Weber files in the {potentials} directory of the LAMMPS
distribution have a ".sw" suffix. Lines that are not blank or
comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to the two-body
and three-body coefficients in the formula above:
element 1 (the center atom in a 3-body interaction)
element 2
element 3
epsilon (energy units)
sigma (distance units)
a
lambda
gamma
costheta0
A
B
p
q
tol :ul
The A, B, p, and q parameters are used only for two-body
interactions. The lambda and costheta0 parameters are used only for
three-body interactions. The epsilon, sigma and a parameters are used
for both two-body and three-body interactions. gamma is used only in the
three-body interactions, but is defined for pairs of atoms.
The non-annotated parameters are unitless.
LAMMPS introduces an additional performance-optimization parameter tol
that is used for both two-body and three-body interactions. In the
Stillinger-Weber potential, the interaction energies become negligibly
small at atomic separations substantially less than the theoretical
cutoff distances. LAMMPS therefore defines a virtual cutoff distance
based on a user defined tolerance tol. The use of the virtual cutoff
distance in constructing atom neighbor lists can significantly reduce
the neighbor list sizes and therefore the computational cost. LAMMPS
provides a {tol} value for each of the three-body entries so that they
can be separately controlled. If tol = 0.0, then the standard
Stillinger-Weber cutoff is used.
The Stillinger-Weber potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify SW parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
As annotated above, the first element in the entry is the center atom
in a three-body interaction. Thus an entry for SiCC means a Si atom
with 2 C atoms as neighbors. The parameter values used for the
two-body interaction come from the entry where the 2nd and 3rd
elements are the same. Thus the two-body parameters for Si
interacting with C, comes from the SiCC entry. The three-body
parameters can in principle be specific to the three elements of the
configuration. In the literature, however, the three-body parameters
are usually defined by simple formulas involving two sets of pair-wise
parameters, corresponding to the ij and ik pairs, where i is the
center atom. The user must ensure that the correct combining rule is
used to calculate the values of the threebody parameters for
alloys. Note also that the function phi3 contains two exponential
screening factors with parameter values from the ij pair and ik
pairs. So phi3 for a C atom bonded to a Si atom and a second C atom
will depend on the three-body parameters for the CSiC entry, and also
on the two-body parameters for the CCC and CSiSi entries. Since the
order of the two neighbors is arbitrary, the threebody parameters for
entries CSiC and CCSi should be the same. Similarly, the two-body
parameters for entries SiCC and CSiSi should also be the same. The
parameters used only for two-body interactions (A, B, p, and q) in
entries whose 2nd and 3rd element are different (e.g. SiCSi) are not
used for anything and can be set to 0.0 if desired.
This is also true for the parameters in phi3 that are
taken from the ij and ik pairs (sigma, a, gamma)
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the "Making LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires the "newton"_newton.html setting to be "on"
for pair interactions.
The Stillinger-Weber potential files provided with LAMMPS (see the
potentials directory) are parameterized for metal "units"_units.html.
You can use the SW potential with any LAMMPS units, but you would need
to create your own SW potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Stillinger)
[(Stillinger)] Stillinger and Weber, Phys Rev B, 31, 5262 (1985).
diff --git a/doc/pair_table.html b/doc/pair_table.html
index 6b59e441b..23f0f5bd8 100644
--- a/doc/pair_table.html
+++ b/doc/pair_table.html
@@ -1,238 +1,238 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style table command
</H3>
<H3>pair_style table/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style table style N
</PRE>
<UL><LI>style = <I>lookup</I> or <I>linear</I> or <I>spline</I> or <I>bitmap</I> = method of interpolation
<LI>N = use N values in <I>lookup</I>, <I>linear</I>, <I>spline</I> tables
<LI>N = use 2^N values in <I>bitmap</I> tables
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style table linear 1000
pair_style table bitmap 12
pair_coeff * 3 morse.table ENTRY1
pair_coeff * 3 morse.table ENTRY1 7.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>table</I> creates interpolation tables of length <I>N</I> from pair
potential and force values listed in a file(s) as a function of
distance. The files are read by the <A HREF = "pair_coeff.html">pair_coeff</A>
command.
</P>
<P>The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and force values at each of <I>N</I>
distances. During a simulation, these tables are used to interpolate
energy and force values as needed. The interpolation is done in one
of 4 styles: <I>lookup</I>, <I>linear</I>, <I>spline</I>, or <I>bitmap</I>.
</P>
<P>For the <I>lookup</I> style, the distance between 2 atoms is used to find
the nearest table entry, which is the energy or force.
</P>
<P>For the <I>linear</I> style, the pair distance is used to find 2
surrounding table values from which an energy or force is computed by
linear interpolation.
</P>
<P>For the <I>spline</I> style, a cubic spline coefficients are computed and
stored at each of the <I>N</I> values in the table. The pair distance is
used to find the appropriate set of coefficients which are used to
evaluate a cubic polynomial which computes the energy or force.
</P>
<P>For the <I>bitmap</I> style, the N means to create interpolation tables
that are 2^N in length. <The pair distance is used to index into the
table via a fast bit-mapping technique <A HREF = "#Wolff">(Wolff)</A> and a linear
interpolation is performed between adjacent table values.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above.
</P>
<UL><LI>filename
<LI>keyword
<LI>cutoff (distance units)
</UL>
<P>The filename specifies a file containing tabulated energy and force
values. The keyword specifies a section of the file. The cutoff is
an optional coefficient. If not specified, the outer cutoff in the
table itself (see below) will be used to build an interpolation table
that extend to the largest tabulated distance. If specified, only
file values up to the cutoff are used to create the interpolation
table. The format of this file is described below.
</P>
<HR>
<P>Here are some guidelines for using the pair_style table command to
best effect:
</P>
<UL><LI>Vary the number of table points; you may need to use more than you think
to get good resolution.
<LI>Always use the <A HREF = "pair_write.html">pair_write</A> command to produce a plot
of what the final interpolated potential looks like. This can show up
interpolation "features" you may not like.
<LI>Start with the linear style; it's the style least likely to have problems.
<LI>Use <I>N</I> in the pair_style command equal to the "N" in the tabulation
file, and use the "RSQ" or "BITMAP" parameter, so additional interpolation
is not needed. See discussion below.
<LI>Use as large an inner cutoff as possible. This avoids fitting splines
to very steep parts of the potential.
</UL>
<HR>
<P>The format of a tabulated file is as follows (without the
parenthesized comments):
</P>
<PRE># Morse potential for Fe (one or more comment or blank lines)
</PRE>
<PRE>MORSE_FE (keyword is first text on line)
N 500 R 1.0 10.0 (N, R, RSQ, BITMAP, FPRIME parameters)
(blank)
1 1.0 25.5 102.34 (index, r, energy, force)
2 1.02 23.4 98.5
...
500 10.0 0.001 0.003
</PRE>
<P>A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the pair_coeff
command. The next line lists (in any order) one or more parameters
for the table. Each parameter is a keyword followed by one or more
numeric values.
</P>
<P>The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the <I>N</I>
specified in the <A HREF = "pair_style.html">pair_style table</A> command. Let
Ntable = <I>N</I> in the pair_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and force
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual pair distances. This means that if you want the
interpolation tables of length Ntable to match exactly what is in the
tabulated file (with effectively no preliminary interpolation), you
should set Ntable = Nfile, and use the "RSQ" or "BITMAP" parameter.
</P>
<P>All other parameters are optional. If "R" or "RSQ" or "BITMAP" does
not appear, then the distances in each line of the table are used
as-is to perform spline interpolation. In this case, the table values
can be spaced in <I>r</I> uniformly or however you wish to position table
values in regions of large gradients.
</P>
<P>If used, the parameters "R" or "RSQ" are followed by 2 values <I>rlo</I>
and <I>rhi</I>. If specified, the distance associated with each energy and
force value is computed from these 2 values (at high accuracy), rather
than using the (low-accuracy) value listed in each line of the table.
For "R", distances uniformly spaced between <I>rlo</I> and <I>rhi</I> are
computed; for "RSQ", squared distances uniformly spaced between
<I>rlo*rlo</I> and <I>rhi*rhi</I> are computed.
</P>
<P>If used, the parameter "BITMAP" is also followed by 2 values <I>rlo</I> and
<I>rhi</I>. These values, along with the "N" value determine the ordering
of the N lines that follow and what distance is associated with each.
This ordering is complex, so it is not documented here, since this
file is typically produced by the <A HREF = "pair_write.html">pair_write</A> command
with its <I>bitmap</I> option. When the table is in BITMAP format, the "N"
parameter in the file must be equal to 2^M where M is the value
specified in the pair_style command. Also, a cutoff parameter cannot
be used as an optional 3rd argument in the pair_coeff command; the
entire table extent as specified in the file must be used.
</P>
<P>If used, the parameter "FPRIME" is followed by 2 values <I>fplo</I> and
<I>fphi</I> which are the derivative of the force at the innermost and
outermost distances listed in the table. These values are needed by
the spline construction routines. If not specified by the "FPRIME"
parameter, they are estimated (less accurately) by the first 2 and
last 2 force values in the table. This parameter is not used by
BITMAP tables.
</P>
<P>Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
r (in distance units), the 3rd value is the energy (in energy units),
and the 4th is the force (in force units). The r values must increase
from one line to the next (unless the BITMAP parameter is specified).
</P>
<P>Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>This pair style does not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> shift, table, and tail options are
not relevant for this pair style.
</P>
<P>This pair style writes the settings for the "pair_style table" command
to <A HREF = "restart.html">binary restart files</A>, so a pair_style command does
not need to specified in an input script that reads a restart file.
However, the coefficient information is not stored in the restart
file, since it is tabulated in the potential files. Thus, pair_coeff
commands do need to be specified in the restart input script.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Wolff"></A>
<P><B>(Wolff)</B> Wolff and Rudd, Comp Phys Comm, 120, 200-32 (1999).
</P>
</HTML>
diff --git a/doc/pair_table.txt b/doc/pair_table.txt
index 64bdb31f4..c6916de68 100644
--- a/doc/pair_table.txt
+++ b/doc/pair_table.txt
@@ -1,231 +1,231 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style table command :h3
pair_style table/omp command :h3
[Syntax:]
pair_style table style N :pre
style = {lookup} or {linear} or {spline} or {bitmap} = method of interpolation
N = use N values in {lookup}, {linear}, {spline} tables
N = use 2^N values in {bitmap} tables :ul
[Examples:]
pair_style table linear 1000
pair_style table bitmap 12
pair_coeff * 3 morse.table ENTRY1
pair_coeff * 3 morse.table ENTRY1 7.0 :pre
[Description:]
Style {table} creates interpolation tables of length {N} from pair
potential and force values listed in a file(s) as a function of
distance. The files are read by the "pair_coeff"_pair_coeff.html
command.
The interpolation tables are created by fitting cubic splines to the
file values and interpolating energy and force values at each of {N}
distances. During a simulation, these tables are used to interpolate
energy and force values as needed. The interpolation is done in one
of 4 styles: {lookup}, {linear}, {spline}, or {bitmap}.
For the {lookup} style, the distance between 2 atoms is used to find
the nearest table entry, which is the energy or force.
For the {linear} style, the pair distance is used to find 2
surrounding table values from which an energy or force is computed by
linear interpolation.
For the {spline} style, a cubic spline coefficients are computed and
stored at each of the {N} values in the table. The pair distance is
used to find the appropriate set of coefficients which are used to
evaluate a cubic polynomial which computes the energy or force.
For the {bitmap} style, the N means to create interpolation tables
that are 2^N in length. <The pair distance is used to index into the
table via a fast bit-mapping technique "(Wolff)"_#Wolff and a linear
interpolation is performed between adjacent table values.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above.
filename
keyword
cutoff (distance units) :ul
The filename specifies a file containing tabulated energy and force
values. The keyword specifies a section of the file. The cutoff is
an optional coefficient. If not specified, the outer cutoff in the
table itself (see below) will be used to build an interpolation table
that extend to the largest tabulated distance. If specified, only
file values up to the cutoff are used to create the interpolation
table. The format of this file is described below.
:line
Here are some guidelines for using the pair_style table command to
best effect:
Vary the number of table points; you may need to use more than you think
to get good resolution. :ulb,l
Always use the "pair_write"_pair_write.html command to produce a plot
of what the final interpolated potential looks like. This can show up
interpolation "features" you may not like. :l
Start with the linear style; it's the style least likely to have problems. :l
Use {N} in the pair_style command equal to the "N" in the tabulation
file, and use the "RSQ" or "BITMAP" parameter, so additional interpolation
is not needed. See discussion below. :l
Use as large an inner cutoff as possible. This avoids fitting splines
to very steep parts of the potential. :l,ule
:line
The format of a tabulated file is as follows (without the
parenthesized comments):
# Morse potential for Fe (one or more comment or blank lines) :pre
MORSE_FE (keyword is first text on line)
N 500 R 1.0 10.0 (N, R, RSQ, BITMAP, FPRIME parameters)
(blank)
1 1.0 25.5 102.34 (index, r, energy, force)
2 1.02 23.4 98.5
...
500 10.0 0.001 0.003 :pre
A section begins with a non-blank line whose 1st character is not a
"#"; blank lines or lines starting with "#" can be used as comments
between sections. The first line begins with a keyword which
identifies the section. The line can contain additional text, but the
initial text must match the argument specified in the pair_coeff
command. The next line lists (in any order) one or more parameters
for the table. Each parameter is a keyword followed by one or more
numeric values.
The parameter "N" is required and its value is the number of table
entries that follow. Note that this may be different than the {N}
specified in the "pair_style table"_pair_style.html command. Let
Ntable = {N} in the pair_style command, and Nfile = "N" in the
tabulated file. What LAMMPS does is a preliminary interpolation by
creating splines using the Nfile tabulated values as nodal points. It
uses these to interpolate as needed to generate energy and force
values at Ntable different points. The resulting tables of length
Ntable are then used as described above, when computing energy and
force for individual pair distances. This means that if you want the
interpolation tables of length Ntable to match exactly what is in the
tabulated file (with effectively no preliminary interpolation), you
should set Ntable = Nfile, and use the "RSQ" or "BITMAP" parameter.
All other parameters are optional. If "R" or "RSQ" or "BITMAP" does
not appear, then the distances in each line of the table are used
as-is to perform spline interpolation. In this case, the table values
can be spaced in {r} uniformly or however you wish to position table
values in regions of large gradients.
If used, the parameters "R" or "RSQ" are followed by 2 values {rlo}
and {rhi}. If specified, the distance associated with each energy and
force value is computed from these 2 values (at high accuracy), rather
than using the (low-accuracy) value listed in each line of the table.
For "R", distances uniformly spaced between {rlo} and {rhi} are
computed; for "RSQ", squared distances uniformly spaced between
{rlo*rlo} and {rhi*rhi} are computed.
If used, the parameter "BITMAP" is also followed by 2 values {rlo} and
{rhi}. These values, along with the "N" value determine the ordering
of the N lines that follow and what distance is associated with each.
This ordering is complex, so it is not documented here, since this
file is typically produced by the "pair_write"_pair_write.html command
with its {bitmap} option. When the table is in BITMAP format, the "N"
parameter in the file must be equal to 2^M where M is the value
specified in the pair_style command. Also, a cutoff parameter cannot
be used as an optional 3rd argument in the pair_coeff command; the
entire table extent as specified in the file must be used.
If used, the parameter "FPRIME" is followed by 2 values {fplo} and
{fphi} which are the derivative of the force at the innermost and
outermost distances listed in the table. These values are needed by
the spline construction routines. If not specified by the "FPRIME"
parameter, they are estimated (less accurately) by the first 2 and
last 2 force values in the table. This parameter is not used by
BITMAP tables.
Following a blank line, the next N lines list the tabulated values.
On each line, the 1st value is the index from 1 to N, the 2nd value is
r (in distance units), the 3rd value is the energy (in energy units),
and the 4th is the force (in force units). The r values must increase
from one line to the next (unless the BITMAP parameter is specified).
Note that one file can contain many sections, each with a tabulated
potential. LAMMPS reads the file section by section until it finds
one that matches the specified keyword.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
This pair style does not support mixing. Thus, coefficients for all
I,J pairs must be specified explicitly.
The "pair_modify"_pair_modify.html shift, table, and tail options are
not relevant for this pair style.
This pair style writes the settings for the "pair_style table" command
to "binary restart files"_restart.html, so a pair_style command does
not need to specified in an input script that reads a restart file.
However, the coefficient information is not stored in the restart
file, since it is tabulated in the potential files. Thus, pair_coeff
commands do need to be specified in the restart input script.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Wolff)
[(Wolff)] Wolff and Rudd, Comp Phys Comm, 120, 200-32 (1999).
diff --git a/doc/pair_tersoff.html b/doc/pair_tersoff.html
index 968635273..ef109da04 100644
--- a/doc/pair_tersoff.html
+++ b/doc/pair_tersoff.html
@@ -1,243 +1,259 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style tersoff command
</H3>
+<H3>pair_style tersoff/table command
+</H3>
+<H3>pair_style tersoff/cuda
+</H3>
+<H3>pair_style tersoff/omp
+</H3>
+<H3>pair_style tersoff/table/omp command
+</H3>
<P><B>Syntax:</B>
</P>
-<PRE>pair_style tersoff
-</PRE>
-<PRE>pair_style tersoff/cuda
-</PRE>
-<PRE>pair_style tersoff/omp
+<PRE>pair_style style
</PRE>
+<P>style = <I>tersoff</I> or <I>tersoff/table</I> or <I>tersoff/cuda</I> or <I>tersoff/omp</I> or <I>tersoff/table/omp</I>
+</P>
<P><B>Examples:</B>
</P>
<PRE>pair_style tersoff
pair_coeff * * Si.tersoff Si
pair_coeff * * SiC.tersoff Si C Si
</PRE>
+<PRE>pair_style tersoff/table
+pair_coeff * * SiCGe.tersoff Si(D)
+</PRE>
<P><B>Description:</B>
</P>
<P>The <I>tersoff</I> style computes a 3-body Tersoff potential
<A HREF = "#Tersoff_1">(Tersoff_1)</A> for the energy E of a system of atoms as
</P>
<CENTER><IMG SRC = "Eqs/pair_tersoff_1.jpg">
</CENTER>
<P>where f_R is a two-body term and f_A includes three-body interactions.
The summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = R + D.
</P>
+<P>The <I>tersoff/table</I> style uses tabulated forms for the two-body,
+environment and angular functions. Linear interpolation is performed
+between adjacent table entries. The table length is chosen to be
+accurate within 10^-6 with respect to the <I>tersoff</I> style energy.
+The <I>tersoff/table</I> should give better performance in terms of speed.
+</P>
<P>Only a single pair_coeff command is used with the <I>tersoff</I> style
which specifies a Tersoff potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of Tersoff elements to atom types
</UL>
<P>As an example, imagine the SiC.tersoff file has Tersoff values for Si
and C. If your LAMMPS simulation has 4 atoms types and you want the
1st 3 to be Si, and the 4th to be C, you would use the following
pair_coeff command:
</P>
<PRE>pair_coeff * * SiC.tersoff Si Si Si C
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the Tersoff file. The final C argument maps LAMMPS atom
type 4 to the C element in the Tersoff file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a <I>tersoff</I> potential is used as part of the <I>hybrid</I> pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
</P>
<P>Tersoff files in the <I>potentials</I> directory of the LAMMPS distribution
have a ".tersoff" suffix. Lines that are not blank or comments
(starting with #) define parameters for a triplet of elements. The
parameters in a single entry correspond to coefficients in the formula
above:
</P>
<UL><LI>element 1 (the center atom in a 3-body interaction)
<LI>element 2 (the atom bonded to the center atom)
<LI>element 3 (the atom influencing the 1-2 bond in a bond-order sense)
<LI>m
<LI>gamma
<LI>lambda3 (1/distance units)
<LI>c
<LI>d
<LI>costheta0 (can be a value < -1 or > 1)
<LI>n
<LI>beta
<LI>lambda2 (1/distance units)
<LI>B (energy units)
<LI>R (distance units)
<LI>D (distance units)
<LI>lambda1 (1/distance units)
<LI>A (energy units)
</UL>
<P>The n, beta, lambda2, B, lambda1, and A parameters are only used for
two-body interactions. The m, gamma, lambda3, c, d, and costheta0
parameters are only used for three-body interactions. The R and D
parameters are used for both two-body and three-body interactions. The
non-annotated parameters are unitless. The value of m must be 3 or 1.
</P>
<P>The Tersoff potential file must contain entries for all the elements
listed in the pair_coeff command. It can also contain entries for
additional elements not being used in a particular simulation; LAMMPS
ignores those entries.
</P>
<P>For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify Tersoff parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
</P>
<P>As annotated above, the first element in the entry is the center atom
in a three-body interaction and it is bonded to the 2nd atom and the
bond is influenced by the 3rd atom. Thus an entry for SiCC means Si
bonded to a C with another C atom influencing the bond. Thus
three-body parameters for SiCSi and SiSiC entries will not, in
general, be the same. The parameters used for the two-body
interaction come from the entry where the 2nd element is repeated.
Thus the two-body parameters for Si interacting with C, comes from the
SiCC entry.
</P>
<P>The parameters used for a particular
three-body interaction come from the entry with the corresponding
three elements. The parameters used only for two-body interactions
(n, beta, lambda2, B, lambda1, and A) in entries whose 2nd and 3rd
element are different (e.g. SiCSi) are not used for anything and can
be set to 0.0 if desired.
</P>
<P>Note that the twobody parameters in entries such as SiCC and CSiSi
are often the same, due to the common use of symmetric mixing rules,
but this is not always the case. For example, the beta and n parameters in
Tersoff_2 <A HREF = "#Tersoff_2">(Tersoff_2)</A> are not symmetric.
</P>
<P>We chose the above form so as to enable users to define all commonly
used variants of the Tersoff potential. In particular, our form
reduces to the original Tersoff form when m = 3 and gamma = 1, while
it reduces to the form of <A HREF = "#Albe">Albe et al.</A> when beta = 1 and m = 1.
Note that in the current Tersoff implementation in LAMMPS, m must be
specified as either 3 or 1. Tersoff used a slightly different but
equivalent form for alloys, which we will refer to as Tersoff_2
-potential <A HREF = "#Tersoff_2">(Tersoff_2)</A>.
+potential <A HREF = "#Tersoff_2">(Tersoff_2)</A>. The <I>tersoff/table</I> style implements
+Tersoff_2 parameterization only.
</P>
<P>LAMMPS parameter values for Tersoff_2 can be obtained as follows:
gamma_ijk = omega_ik, lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
</P>
<CENTER><IMG SRC = "Eqs/pair_tersoff_2.jpg">
</CENTER>
<P>Tersoff_2 parameters R and S must be converted to the LAMMPS
parameters R and D (R is different in both forms), using the following
relations: R=(R'+S')/2 and D=(S'-R')/2, where the primes indicate the
Tersoff_2 parameters.
</P>
<P>In the potentials directory, the file SiCGe.tersoff provides the
LAMMPS parameters for Tersoff's various versions of Si, as well as his
alloy parameters for Si, C, and Ge. This file can be used for pure Si,
(three different versions), pure C, pure Ge, binary SiC, and binary
SiGe. LAMMPS will generate an error if this file is used with any
combination involving C and Ge, since there are no entries for the GeC
interactions (Tersoff did not publish parameters for this
cross-interaction.) Tersoff files are also provided for the SiC alloy
(SiC.tersoff) and the GaN (GaN.tersoff) alloys.
</P>
<P>Many thanks to Rutuparna Narulkar, David Farrell, and Xiaowang Zhou
for helping clarify how Tersoff parameters for alloys have been
defined in various papers.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more info.
</P>
<P>This pair style requires the <A HREF = "newton.html">newton</A> setting to be "on"
for pair interactions.
</P>
<P>The Tersoff potential files provided with LAMMPS (see the potentials
directory) are parameterized for metal <A HREF = "units.html">units</A>. You can
use the Tersoff potential with any LAMMPS units, but you would need to
create your own Tersoff potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Tersoff_1"></A>
<P><B>(Tersoff_1)</B> J. Tersoff, Phys Rev B, 37, 6991 (1988).
</P>
<A NAME = "Albe"></A>
<P><B>(Albe)</B> J. Nord, K. Albe, P. Erhart, and K. Nordlund, J. Phys.:
Condens. Matter, 15, 5649(2003).
</P>
<A NAME = "Tersoff_2"></A>
<P><B>(Tersoff_2)</B> J. Tersoff, Phys Rev B, 39, 5566 (1989); errata (PRB 41, 3248)
</P>
</HTML>
diff --git a/doc/pair_tersoff.txt b/doc/pair_tersoff.txt
index 5d23f009f..58a88abaa 100644
--- a/doc/pair_tersoff.txt
+++ b/doc/pair_tersoff.txt
@@ -1,233 +1,247 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style tersoff command :h3
+pair_style tersoff/table command :h3
+pair_style tersoff/cuda :h3
+pair_style tersoff/omp :h3
+pair_style tersoff/table/omp command :h3
[Syntax:]
-pair_style tersoff :pre
-pair_style tersoff/cuda :pre
-pair_style tersoff/omp :pre
+pair_style style :pre
+
+style = {tersoff} or {tersoff/table} or {tersoff/cuda} or {tersoff/omp} or {tersoff/table/omp}
[Examples:]
pair_style tersoff
pair_coeff * * Si.tersoff Si
pair_coeff * * SiC.tersoff Si C Si :pre
+pair_style tersoff/table
+pair_coeff * * SiCGe.tersoff Si(D) :pre
+
[Description:]
The {tersoff} style computes a 3-body Tersoff potential
"(Tersoff_1)"_#Tersoff_1 for the energy E of a system of atoms as
:c,image(Eqs/pair_tersoff_1.jpg)
where f_R is a two-body term and f_A includes three-body interactions.
The summations in the formula are over all neighbors J and K of atom I
within a cutoff distance = R + D.
+The {tersoff/table} style uses tabulated forms for the two-body,
+environment and angular functions. Linear interpolation is performed
+between adjacent table entries. The table length is chosen to be
+accurate within 10^-6 with respect to the {tersoff} style energy.
+The {tersoff/table} should give better performance in terms of speed.
+
Only a single pair_coeff command is used with the {tersoff} style
which specifies a Tersoff potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of Tersoff elements to atom types :ul
As an example, imagine the SiC.tersoff file has Tersoff values for Si
and C. If your LAMMPS simulation has 4 atoms types and you want the
1st 3 to be Si, and the 4th to be C, you would use the following
pair_coeff command:
pair_coeff * * SiC.tersoff Si Si Si C :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the Tersoff file. The final C argument maps LAMMPS atom
type 4 to the C element in the Tersoff file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a {tersoff} potential is used as part of the {hybrid} pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
Tersoff files in the {potentials} directory of the LAMMPS distribution
have a ".tersoff" suffix. Lines that are not blank or comments
(starting with #) define parameters for a triplet of elements. The
parameters in a single entry correspond to coefficients in the formula
above:
element 1 (the center atom in a 3-body interaction)
element 2 (the atom bonded to the center atom)
element 3 (the atom influencing the 1-2 bond in a bond-order sense)
m
gamma
lambda3 (1/distance units)
c
d
costheta0 (can be a value < -1 or > 1)
n
beta
lambda2 (1/distance units)
B (energy units)
R (distance units)
D (distance units)
lambda1 (1/distance units)
A (energy units) :ul
The n, beta, lambda2, B, lambda1, and A parameters are only used for
two-body interactions. The m, gamma, lambda3, c, d, and costheta0
parameters are only used for three-body interactions. The R and D
parameters are used for both two-body and three-body interactions. The
non-annotated parameters are unitless. The value of m must be 3 or 1.
The Tersoff potential file must contain entries for all the elements
listed in the pair_coeff command. It can also contain entries for
additional elements not being used in a particular simulation; LAMMPS
ignores those entries.
For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify Tersoff parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
As annotated above, the first element in the entry is the center atom
in a three-body interaction and it is bonded to the 2nd atom and the
bond is influenced by the 3rd atom. Thus an entry for SiCC means Si
bonded to a C with another C atom influencing the bond. Thus
three-body parameters for SiCSi and SiSiC entries will not, in
general, be the same. The parameters used for the two-body
interaction come from the entry where the 2nd element is repeated.
Thus the two-body parameters for Si interacting with C, comes from the
SiCC entry.
The parameters used for a particular
three-body interaction come from the entry with the corresponding
three elements. The parameters used only for two-body interactions
(n, beta, lambda2, B, lambda1, and A) in entries whose 2nd and 3rd
element are different (e.g. SiCSi) are not used for anything and can
be set to 0.0 if desired.
Note that the twobody parameters in entries such as SiCC and CSiSi
are often the same, due to the common use of symmetric mixing rules,
but this is not always the case. For example, the beta and n parameters in
Tersoff_2 "(Tersoff_2)"_#Tersoff_2 are not symmetric.
We chose the above form so as to enable users to define all commonly
used variants of the Tersoff potential. In particular, our form
reduces to the original Tersoff form when m = 3 and gamma = 1, while
it reduces to the form of "Albe et al."_#Albe when beta = 1 and m = 1.
Note that in the current Tersoff implementation in LAMMPS, m must be
specified as either 3 or 1. Tersoff used a slightly different but
equivalent form for alloys, which we will refer to as Tersoff_2
-potential "(Tersoff_2)"_#Tersoff_2.
+potential "(Tersoff_2)"_#Tersoff_2. The {tersoff/table} style implements
+Tersoff_2 parameterization only.
LAMMPS parameter values for Tersoff_2 can be obtained as follows:
gamma_ijk = omega_ik, lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
:c,image(Eqs/pair_tersoff_2.jpg)
Tersoff_2 parameters R and S must be converted to the LAMMPS
parameters R and D (R is different in both forms), using the following
relations: R=(R'+S')/2 and D=(S'-R')/2, where the primes indicate the
Tersoff_2 parameters.
In the potentials directory, the file SiCGe.tersoff provides the
LAMMPS parameters for Tersoff's various versions of Si, as well as his
alloy parameters for Si, C, and Ge. This file can be used for pure Si,
(three different versions), pure C, pure Ge, binary SiC, and binary
SiGe. LAMMPS will generate an error if this file is used with any
combination involving C and Ge, since there are no entries for the GeC
interactions (Tersoff did not publish parameters for this
cross-interaction.) Tersoff files are also provided for the SiC alloy
(SiC.tersoff) and the GaN (GaN.tersoff) alloys.
Many thanks to Rutuparna Narulkar, David Farrell, and Xiaowang Zhou
for helping clarify how Tersoff parameters for alloys have been
defined in various papers.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the "Making LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires the "newton"_newton.html setting to be "on"
for pair interactions.
The Tersoff potential files provided with LAMMPS (see the potentials
directory) are parameterized for metal "units"_units.html. You can
use the Tersoff potential with any LAMMPS units, but you would need to
create your own Tersoff potential file with coefficients listed in the
appropriate units if your simulation doesn't use "metal" units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Tersoff_1)
[(Tersoff_1)] J. Tersoff, Phys Rev B, 37, 6991 (1988).
:link(Albe)
[(Albe)] J. Nord, K. Albe, P. Erhart, and K. Nordlund, J. Phys.:
Condens. Matter, 15, 5649(2003).
:link(Tersoff_2)
[(Tersoff_2)] J. Tersoff, Phys Rev B, 39, 5566 (1989); errata (PRB 41, 3248)
diff --git a/doc/pair_tersoff_zbl.html b/doc/pair_tersoff_zbl.html
index be760ba0d..202601f7a 100644
--- a/doc/pair_tersoff_zbl.html
+++ b/doc/pair_tersoff_zbl.html
@@ -1,267 +1,267 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style tersoff/zbl command
</H3>
<H3>pair_style tersoff/zbl/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style tersoff/zbl
</PRE>
<P><B>Examples:</B>
</P>
<PRE>pair_style tersoff/zbl
pair_coeff * * SiC.tersoff.zbl Si C Si
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>tersoff/zbl</I> style computes a 3-body Tersoff potential
<A HREF = "#Tersoff_1">(Tersoff_1)</A> with a close-separation pairwise modification
based on a Coulomb potential and the Ziegler-Biersack-Littmark
universal screening function <A HREF = "#ZBL">(ZBL)</A>, giving the energy E of a
system of atoms as
</P>
<CENTER><IMG SRC = "Eqs/pair_tersoff_zbl.jpg">
</CENTER>
<P>The f_F term is a fermi-like function used to smoothly connect the ZBL
repulsive potential with the Tersoff potential. There are 2
parameters used to adjust it: A_F and r_C. A_F controls how "sharp"
the transition is between the two, and r_C is essentially the cutoff
for the ZBL potential.
</P>
<P>For the ZBL portion, there are two terms. The first is the Coulomb
repulsive term, with Z1, Z2 as the number of protons in each nucleus,
e as the electron charge (1 for metal and real units) and epsilon0 as
the permittivity of vacuum. The second part is the ZBL universal
screening function, with a0 being the Bohr radius (typically 0.529
Angstroms), and the remainder of the coefficients provided by the
original paper. This screening function should be applicable to most
systems. However, it is only accurate for small separations
(i.e. less than 1 Angstrom).
</P>
<P>For the Tersoff portion, f_R is a two-body term and f_A includes
three-body interactions. The summations in the formula are over all
neighbors J and K of atom I within a cutoff distance = R + D.
</P>
<P>Only a single pair_coeff command is used with the <I>tersoff/zbl</I> style
which specifies a Tersoff/ZBL potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of Tersoff/ZBL elements to atom types
</UL>
<P>As an example, imagine the SiC.tersoff.zbl file has Tersoff/ZBL values
for Si and C. If your LAMMPS simulation has 4 atoms types and you
want the 1st 3 to be Si, and the 4th to be C, you would use the
following pair_coeff command:
</P>
<PRE>pair_coeff * * SiC.tersoff Si Si Si C
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the Tersoff/ZBL file. The final C argument maps LAMMPS
atom type 4 to the C element in the Tersoff/ZBL file. If a mapping
value is specified as NULL, the mapping is not performed. This can be
used when a <I>tersoff/zbl</I> potential is used as part of the <I>hybrid</I>
pair style. The NULL values are placeholders for atom types that will
be used with other potentials.
</P>
<P>Tersoff/ZBL files in the <I>potentials</I> directory of the LAMMPS
distribution have a ".tersoff.zbl" suffix. Lines that are not blank
or comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to coefficients
in the formula above:
</P>
<UL><LI>element 1 (the center atom in a 3-body interaction)
<LI>element 2 (the atom bonded to the center atom)
<LI>element 3 (the atom influencing the 1-2 bond in a bond-order sense)
<LI>m
<LI>gamma
<LI>lambda3 (1/distance units)
<LI>c
<LI>d
<LI>costheta0 (can be a value < -1 or > 1)
<LI>n
<LI>beta
<LI>lambda2 (1/distance units)
<LI>B (energy units)
<LI>R (distance units)
<LI>D (distance units)
<LI>lambda1 (1/distance units)
<LI>A (energy units)
<LI>Z_i
<LI>Z_j
<LI>ZBLcut (distance units)
<LI>ZBLexpscale (1/distance units)
</UL>
<P>The n, beta, lambda2, B, lambda1, and A parameters are only used for
two-body interactions. The m, gamma, lambda3, c, d, and costheta0
parameters are only used for three-body interactions. The R and D
parameters are used for both two-body and three-body interactions. The
Z_i,Z_j, ZBLcut, ZBLexpscale parameters are used in the ZBL repulsive
portion of the potential and in the Fermi-like function. The
non-annotated parameters are unitless. The value of m must be 3 or 1.
</P>
<P>The Tersoff/ZBL potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
</P>
<P>For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify Tersoff parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
</P>
<P>As annotated above, the first element in the entry is the center atom
in a three-body interaction and it is bonded to the 2nd atom and the
bond is influenced by the 3rd atom. Thus an entry for SiCC means Si
bonded to a C with another C atom influencing the bond. Thus
three-body parameters for SiCSi and SiSiC entries will not, in
general, be the same. The parameters used for the two-body
interaction come from the entry where the 2nd element is repeated.
Thus the two-body parameters for Si interacting with C, comes from the
SiCC entry. By symmetry, the twobody parameters in the SiCC and CSiSi
entries should thus be the same. The parameters used for a particular
three-body interaction come from the entry with the corresponding
three elements. The parameters used only for two-body interactions
(n, beta, lambda2, B, lambda1, and A) in entries whose 2nd and 3rd
element are different (e.g. SiCSi) are not used for anything and can
be set to 0.0 if desired.
</P>
<P>We chose the above form so as to enable users to define all commonly
used variants of the Tersoff portion of the potential. In particular,
our form reduces to the original Tersoff form when m = 3 and gamma =
1, while it reduces to the form of <A HREF = "#Albe">Albe et al.</A> when beta = 1
and m = 1. Note that in the current Tersoff implementation in LAMMPS,
m must be specified as either 3 or 1. Tersoff used a slightly
different but equivalent form for alloys, which we will refer to as
Tersoff_2 potential <A HREF = "#Tersoff_2">(Tersoff_2)</A>.
</P>
<P>LAMMPS parameter values for Tersoff_2 can be obtained as follows:
gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
</P>
<CENTER><IMG SRC = "Eqs/pair_tersoff_2.jpg">
</CENTER>
<P>Values not shown are determined by the first atom type. Finally, the
Tersoff_2 parameters R and S must be converted to the LAMMPS
parameters R and D (R is different in both forms), using the following
relations: R=(R'+S')/2 and D=(S'-R')/2, where the primes indicate the
Tersoff_2 parameters.
</P>
<P>In the potentials directory, the file SiCGe.tersoff provides the
LAMMPS parameters for Tersoff's various versions of Si, as well as his
alloy parameters for Si, C, and Ge. This file can be used for pure Si,
(three different versions), pure C, pure Ge, binary SiC, and binary
SiGe. LAMMPS will generate an error if this file is used with any
combination involving C and Ge, since there are no entries for the GeC
interactions (Tersoff did not publish parameters for this
cross-interaction.) Tersoff files are also provided for the SiC alloy
(SiC.tersoff) and the GaN (GaN.tersoff) alloys.
</P>
<P>Many thanks to Rutuparna Narulkar, David Farrell, and Xiaowang Zhou
for helping clarify how Tersoff parameters for alloys have been
defined in various papers. Also thanks to Ram Devanathan for
providing the base ZBL implementation.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section for more info.
</P>
<P>This pair style requires the <A HREF = "newton.html">newton</A> setting to be "on"
for pair interactions.
</P>
<P>The Tersoff/ZBL potential files provided with LAMMPS (see the
potentials directory) are parameterized for metal <A HREF = "units.html">units</A>.
You can use the Tersoff potential with any LAMMPS units, but you would
need to create your own Tersoff potential file with coefficients
listed in the appropriate units if your simulation doesn't use "metal"
units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Tersoff_1"></A>
<P><B>(Tersoff_1)</B> J. Tersoff, Phys Rev B, 37, 6991 (1988).
</P>
<A NAME = "ZBL"></A>
<P><B>(ZBL)</B> J.F. Ziegler, J.P. Biersack, U. Littmark, 'Stopping and Ranges
of Ions in Matter' Vol 1, 1985, Pergamon Press.
</P>
<A NAME = "Albe"></A>
<P><B>(Albe)</B> J. Nord, K. Albe, P. Erhartand K. Nordlund, J. Phys.:
Condens. Matter, 15, 5649(2003).
</P>
<A NAME = "Tersoff_2"></A>
<P><B>(Tersoff_2)</B> J. Tersoff, Phys Rev B, 39, 5566 (1989)
</P>
</HTML>
diff --git a/doc/pair_tersoff_zbl.txt b/doc/pair_tersoff_zbl.txt
index bf69d712b..53888cd03 100644
--- a/doc/pair_tersoff_zbl.txt
+++ b/doc/pair_tersoff_zbl.txt
@@ -1,257 +1,257 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style tersoff/zbl command :h3
pair_style tersoff/zbl/omp command :h3
[Syntax:]
pair_style tersoff/zbl :pre
[Examples:]
pair_style tersoff/zbl
pair_coeff * * SiC.tersoff.zbl Si C Si :pre
[Description:]
The {tersoff/zbl} style computes a 3-body Tersoff potential
"(Tersoff_1)"_#Tersoff_1 with a close-separation pairwise modification
based on a Coulomb potential and the Ziegler-Biersack-Littmark
universal screening function "(ZBL)"_#ZBL, giving the energy E of a
system of atoms as
:c,image(Eqs/pair_tersoff_zbl.jpg)
The f_F term is a fermi-like function used to smoothly connect the ZBL
repulsive potential with the Tersoff potential. There are 2
parameters used to adjust it: A_F and r_C. A_F controls how "sharp"
the transition is between the two, and r_C is essentially the cutoff
for the ZBL potential.
For the ZBL portion, there are two terms. The first is the Coulomb
repulsive term, with Z1, Z2 as the number of protons in each nucleus,
e as the electron charge (1 for metal and real units) and epsilon0 as
the permittivity of vacuum. The second part is the ZBL universal
screening function, with a0 being the Bohr radius (typically 0.529
Angstroms), and the remainder of the coefficients provided by the
original paper. This screening function should be applicable to most
systems. However, it is only accurate for small separations
(i.e. less than 1 Angstrom).
For the Tersoff portion, f_R is a two-body term and f_A includes
three-body interactions. The summations in the formula are over all
neighbors J and K of atom I within a cutoff distance = R + D.
Only a single pair_coeff command is used with the {tersoff/zbl} style
which specifies a Tersoff/ZBL potential file with parameters for all
needed elements. These are mapped to LAMMPS atom types by specifying
N additional arguments after the filename in the pair_coeff command,
where N is the number of LAMMPS atom types:
filename
N element names = mapping of Tersoff/ZBL elements to atom types :ul
As an example, imagine the SiC.tersoff.zbl file has Tersoff/ZBL values
for Si and C. If your LAMMPS simulation has 4 atoms types and you
want the 1st 3 to be Si, and the 4th to be C, you would use the
following pair_coeff command:
pair_coeff * * SiC.tersoff Si Si Si C :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three Si arguments map LAMMPS atom types 1,2,3 to the Si
element in the Tersoff/ZBL file. The final C argument maps LAMMPS
atom type 4 to the C element in the Tersoff/ZBL file. If a mapping
value is specified as NULL, the mapping is not performed. This can be
used when a {tersoff/zbl} potential is used as part of the {hybrid}
pair style. The NULL values are placeholders for atom types that will
be used with other potentials.
Tersoff/ZBL files in the {potentials} directory of the LAMMPS
distribution have a ".tersoff.zbl" suffix. Lines that are not blank
or comments (starting with #) define parameters for a triplet of
elements. The parameters in a single entry correspond to coefficients
in the formula above:
element 1 (the center atom in a 3-body interaction)
element 2 (the atom bonded to the center atom)
element 3 (the atom influencing the 1-2 bond in a bond-order sense)
m
gamma
lambda3 (1/distance units)
c
d
costheta0 (can be a value < -1 or > 1)
n
beta
lambda2 (1/distance units)
B (energy units)
R (distance units)
D (distance units)
lambda1 (1/distance units)
A (energy units)
Z_i
Z_j
ZBLcut (distance units)
ZBLexpscale (1/distance units) :ul
The n, beta, lambda2, B, lambda1, and A parameters are only used for
two-body interactions. The m, gamma, lambda3, c, d, and costheta0
parameters are only used for three-body interactions. The R and D
parameters are used for both two-body and three-body interactions. The
Z_i,Z_j, ZBLcut, ZBLexpscale parameters are used in the ZBL repulsive
portion of the potential and in the Fermi-like function. The
non-annotated parameters are unitless. The value of m must be 3 or 1.
The Tersoff/ZBL potential file must contain entries for all the
elements listed in the pair_coeff command. It can also contain
entries for additional elements not being used in a particular
simulation; LAMMPS ignores those entries.
For a single-element simulation, only a single entry is required
(e.g. SiSiSi). For a two-element simulation, the file must contain 8
entries (for SiSiSi, SiSiC, SiCSi, SiCC, CSiSi, CSiC, CCSi, CCC), that
specify Tersoff parameters for all permutations of the two elements
interacting in three-body configurations. Thus for 3 elements, 27
entries would be required, etc.
As annotated above, the first element in the entry is the center atom
in a three-body interaction and it is bonded to the 2nd atom and the
bond is influenced by the 3rd atom. Thus an entry for SiCC means Si
bonded to a C with another C atom influencing the bond. Thus
three-body parameters for SiCSi and SiSiC entries will not, in
general, be the same. The parameters used for the two-body
interaction come from the entry where the 2nd element is repeated.
Thus the two-body parameters for Si interacting with C, comes from the
SiCC entry. By symmetry, the twobody parameters in the SiCC and CSiSi
entries should thus be the same. The parameters used for a particular
three-body interaction come from the entry with the corresponding
three elements. The parameters used only for two-body interactions
(n, beta, lambda2, B, lambda1, and A) in entries whose 2nd and 3rd
element are different (e.g. SiCSi) are not used for anything and can
be set to 0.0 if desired.
We chose the above form so as to enable users to define all commonly
used variants of the Tersoff portion of the potential. In particular,
our form reduces to the original Tersoff form when m = 3 and gamma =
1, while it reduces to the form of "Albe et al."_#Albe when beta = 1
and m = 1. Note that in the current Tersoff implementation in LAMMPS,
m must be specified as either 3 or 1. Tersoff used a slightly
different but equivalent form for alloys, which we will refer to as
Tersoff_2 potential "(Tersoff_2)"_#Tersoff_2.
LAMMPS parameter values for Tersoff_2 can be obtained as follows:
gamma = 1, just as for Tersoff_1, but now lambda3 = 0 and the value of
m has no effect. The parameters for species i and j can be calculated
using the Tersoff_2 mixing rules:
:c,image(Eqs/pair_tersoff_2.jpg)
Values not shown are determined by the first atom type. Finally, the
Tersoff_2 parameters R and S must be converted to the LAMMPS
parameters R and D (R is different in both forms), using the following
relations: R=(R'+S')/2 and D=(S'-R')/2, where the primes indicate the
Tersoff_2 parameters.
In the potentials directory, the file SiCGe.tersoff provides the
LAMMPS parameters for Tersoff's various versions of Si, as well as his
alloy parameters for Si, C, and Ge. This file can be used for pure Si,
(three different versions), pure C, pure Ge, binary SiC, and binary
SiGe. LAMMPS will generate an error if this file is used with any
combination involving C and Ge, since there are no entries for the GeC
interactions (Tersoff did not publish parameters for this
cross-interaction.) Tersoff files are also provided for the SiC alloy
(SiC.tersoff) and the GaN (GaN.tersoff) alloys.
Many thanks to Rutuparna Narulkar, David Farrell, and Xiaowang Zhou
for helping clarify how Tersoff parameters for alloys have been
defined in various papers. Also thanks to Ram Devanathan for
providing the base ZBL implementation.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, where types I and J correspond to
two different element types, mixing is performed by LAMMPS as
described above from values in the potential file.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This pair style is part of the MANYBODY package. It is only enabled
if LAMMPS was built with that package (which it is by default). See
the "Making LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires the "newton"_newton.html setting to be "on"
for pair interactions.
The Tersoff/ZBL potential files provided with LAMMPS (see the
potentials directory) are parameterized for metal "units"_units.html.
You can use the Tersoff potential with any LAMMPS units, but you would
need to create your own Tersoff potential file with coefficients
listed in the appropriate units if your simulation doesn't use "metal"
units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Tersoff_1)
[(Tersoff_1)] J. Tersoff, Phys Rev B, 37, 6991 (1988).
:link(ZBL)
[(ZBL)] J.F. Ziegler, J.P. Biersack, U. Littmark, 'Stopping and Ranges
of Ions in Matter' Vol 1, 1985, Pergamon Press.
:link(Albe)
[(Albe)] J. Nord, K. Albe, P. Erhartand K. Nordlund, J. Phys.:
Condens. Matter, 15, 5649(2003).
:link(Tersoff_2)
[(Tersoff_2)] J. Tersoff, Phys Rev B, 39, 5566 (1989)
diff --git a/doc/pair_tri_lj.html b/doc/pair_tri_lj.html
index 76b4455fe..cbf14115e 100644
--- a/doc/pair_tri_lj.html
+++ b/doc/pair_tri_lj.html
@@ -1,120 +1,144 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style tri/lj command
</H3>
+<H3>pair_style tri/lj/omp command
+</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style tri/lj cutoff
</PRE>
<P>cutoff = global cutoff for interactions (distance units)
</P>
<P><B>Examples:</B>
</P>
<PRE>pair_style tri/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>tri/lj</I> treats particles which are triangles as a set of small
spherical particles that tile the triangle surface as explained below.
Interactions between two triangles, each with N1 and N2 spherical
particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
interactions. Interactions between a triangle with N spherical
particles and a point particle are treated as the pairwise sum of N
Lennard-Jones interactions. See the <A HREF = "pair_lj.html">pair_style lj/cut</A>
doc page for the definition of Lennard-Jones interactions.
</P>
<P>The cutoff distance for an interaction between 2 triangles, or between
a triangle and a point particle, is calculated from the position of
the triangle (its centroid), not between pairs of individual spheres
comprising the triangle. Thus an interaction is either calculated in
its entirety or not at all.
</P>
<P>The set of non-overlapping spherical particles that represent a
triangle, for purposes of this pair style, are generated in the
following manner. Assume the triangle is of type I, and sigma_II has
been specified. We want a set of spheres with centers in the plane of
the triangle, none of them larger in diameter than sigma_II, which
completely cover the triangle's area, but with minimial overlap and a
minimal total number of spheres. This is done in a recursive manner.
Place a sphere at the centroid of the original triangle. Calculate
what diameter it must have to just cover all 3 corner points of the
triangle. If that diameter is equal to or smaller than sigma_II, then
include a sphere of the calculated diameter in the set of covering
spheres. It the diameter is larger than sigma_II, then split the
triangle into 2 triangles by bisecting its longest side. Repeat the
process on each sub-triangle, recursing as far as needed to generate a
set of covering spheres. When finished, the original criteria are
met, and the set of covering spheres shoule be near minimal in number
and overlap, at least for input triangles with a reasonable
aspect-ratio.
</P>
<P>The LJ interaction between 2 spheres on different triangles of types
I,J is computed with an arithmetic mixing of the sigma values of the 2
spheres and using the specified epsilon value for I,J atom types.
Note that because the sigma values for triangles spheres is computed
using only sigma_II values, specific to the triangles's type, this
means that any specified sigma_IJ values (for I != J) are effectively
ignored.
</P>
<P>For style <I>tri/lj</I>, the following coefficients must be defined for
each pair of atoms types via the <A HREF = "pair_coeff.html">pair_coeff</A> command
as in the examples above, or in the data file or restart files read by
the <A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands:
</P>
<UL><LI>epsilon (energy units)
<LI>sigma (distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global cutoff
is used.
</P>
<HR>
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+</P>
+<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info.
+</P>
+<P>You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
+switch</A> when you invoke LAMMPS, or you can
+use the <A HREF = "suffix.html">suffix</A> command in your input script.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
+</P>
+<HR>
+
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of this pair style can be mixed. The
default mix value is <I>geometric</I>. See the "pair_modify" command for
details.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
shift, table, and tail options.
</P>
<P>This pair style does not write its information to <A HREF = "restart.html">binary restart
files</A>.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#2_3">Making
LAMMPS</A> section for more info.
</P>
<P>Defining particles to be triangles so they participate in tri/tri or
tri/particle interactions requires the use the <A HREF = "atom_style.html">atom_style
tri</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_line_lj.html">pair_style line/lj</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_tri_lj.txt b/doc/pair_tri_lj.txt
index cfc64c52f..6fb9553bb 100644
--- a/doc/pair_tri_lj.txt
+++ b/doc/pair_tri_lj.txt
@@ -1,115 +1,138 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style tri/lj command :h3
+pair_style tri/lj/omp command :h3
[Syntax:]
pair_style tri/lj cutoff :pre
cutoff = global cutoff for interactions (distance units)
[Examples:]
pair_style tri/lj 3.0
pair_coeff * * 1.0 1.0
pair_coeff 1 1 1.0 1.5 2.5 :pre
[Description:]
Style {tri/lj} treats particles which are triangles as a set of small
spherical particles that tile the triangle surface as explained below.
Interactions between two triangles, each with N1 and N2 spherical
particles, are calculated as the pairwise sum of N1*N2 Lennard-Jones
interactions. Interactions between a triangle with N spherical
particles and a point particle are treated as the pairwise sum of N
Lennard-Jones interactions. See the "pair_style lj/cut"_pair_lj.html
doc page for the definition of Lennard-Jones interactions.
The cutoff distance for an interaction between 2 triangles, or between
a triangle and a point particle, is calculated from the position of
the triangle (its centroid), not between pairs of individual spheres
comprising the triangle. Thus an interaction is either calculated in
its entirety or not at all.
The set of non-overlapping spherical particles that represent a
triangle, for purposes of this pair style, are generated in the
following manner. Assume the triangle is of type I, and sigma_II has
been specified. We want a set of spheres with centers in the plane of
the triangle, none of them larger in diameter than sigma_II, which
completely cover the triangle's area, but with minimial overlap and a
minimal total number of spheres. This is done in a recursive manner.
Place a sphere at the centroid of the original triangle. Calculate
what diameter it must have to just cover all 3 corner points of the
triangle. If that diameter is equal to or smaller than sigma_II, then
include a sphere of the calculated diameter in the set of covering
spheres. It the diameter is larger than sigma_II, then split the
triangle into 2 triangles by bisecting its longest side. Repeat the
process on each sub-triangle, recursing as far as needed to generate a
set of covering spheres. When finished, the original criteria are
met, and the set of covering spheres shoule be near minimal in number
and overlap, at least for input triangles with a reasonable
aspect-ratio.
The LJ interaction between 2 spheres on different triangles of types
I,J is computed with an arithmetic mixing of the sigma values of the 2
spheres and using the specified epsilon value for I,J atom types.
Note that because the sigma values for triangles spheres is computed
using only sigma_II values, specific to the triangles's type, this
means that any specified sigma_IJ values (for I != J) are effectively
ignored.
For style {tri/lj}, the following coefficients must be defined for
each pair of atoms types via the "pair_coeff"_pair_coeff.html command
as in the examples above, or in the data file or restart files read by
the "read_data"_read_data.html or "read_restart"_read_restart.html
commands:
epsilon (energy units)
sigma (distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global cutoff
is used.
:line
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
+
+These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
+packages, respectively. They are only enabled if LAMMPS was built with
+those packages. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info.
+
+You can specify the accelerated styles explicitly in your input script
+by including their suffix, or you can use the "-suffix command-line
+switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
+use the "suffix"_suffix.html command in your input script.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
+
+:line
+
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
and cutoff distance for all of this pair style can be mixed. The
default mix value is {geometric}. See the "pair_modify" command for
details.
This pair style does not support the "pair_modify"_pair_modify.html
shift, table, and tail options.
This pair style does not write its information to "binary restart
files"_restart.html.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This style is part of the ASPHERE package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#2_3 section for more info.
Defining particles to be triangles so they participate in tri/tri or
tri/particle interactions requires the use the "atom_style
tri"_atom_style.html command.
[Related commands:]
"pair_coeff"_pair_coeff.html, "pair_style line/lj"_pair_line_lj.html
[Default:] none
diff --git a/doc/pair_yukawa.html b/doc/pair_yukawa.html
index 51cdc757c..201835362 100644
--- a/doc/pair_yukawa.html
+++ b/doc/pair_yukawa.html
@@ -1,108 +1,108 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style yukawa command
</H3>
<H3>pair_style yukawa/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style yukawa kappa cutoff
</PRE>
<UL><LI>kappa = screening length (inverse distance units)
<LI>cutoff = global cutoff for Yukawa interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style yukawa 2.0 2.5
pair_coeff 1 1 100.0 2.3
pair_coeff * * 100.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>yukawa</I> computes pairwise interactions with the formula
</P>
<CENTER><IMG SRC = "Eqs/pair_yukawa.jpg">
</CENTER>
<P>Rc is the cutoff.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>A (energy*distance units)
<LI>cutoff (distance units)
</UL>
<P>The last coefficient is optional. If not specified, the global yukawa
cutoff is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is an energy value mixed
like a LJ epsilon. The default mix value is <I>geometric</I>. See the
"pair_modify" command for details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_yukawa.txt b/doc/pair_yukawa.txt
index 41b72a83a..a7f6d6eb1 100644
--- a/doc/pair_yukawa.txt
+++ b/doc/pair_yukawa.txt
@@ -1,102 +1,102 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style yukawa command :h3
pair_style yukawa/omp command :h3
[Syntax:]
pair_style yukawa kappa cutoff :pre
kappa = screening length (inverse distance units)
cutoff = global cutoff for Yukawa interactions (distance units) :ul
[Examples:]
pair_style yukawa 2.0 2.5
pair_coeff 1 1 100.0 2.3
pair_coeff * * 100.0 :pre
[Description:]
Style {yukawa} computes pairwise interactions with the formula
:c,image(Eqs/pair_yukawa.jpg)
Rc is the cutoff.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
A (energy*distance units)
cutoff (distance units) :ul
The last coefficient is optional. If not specified, the global yukawa
cutoff is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is an energy value mixed
like a LJ epsilon. The default mix value is {geometric}. See the
"pair_modify" command for details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:] none
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/pair_yukawa_colloid.html b/doc/pair_yukawa_colloid.html
index fcb543318..b41a2f669 100644
--- a/doc/pair_yukawa_colloid.html
+++ b/doc/pair_yukawa_colloid.html
@@ -1,152 +1,152 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>pair_style yukawa/colloid command
</H3>
<H3>pair_style yukawa/colloid/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style yukawa/colloid kappa cutoff
</PRE>
<UL><LI>kappa = screening length (inverse distance units)
<LI>cutoff = global cutoff for colloidal Yukawa interactions (distance units)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style yukawa/colloid 2.0 2.5
pair_coeff 1 1 100.0 2.3
pair_coeff * * 100.0
</PRE>
<P><B>Description:</B>
</P>
<P>Style <I>yukawa/colloid</I> computes pairwise interactions with the formula
</P>
<CENTER><IMG SRC = "Eqs/pair_yukawa_colloid.jpg">
</CENTER>
<P>where Ri and Rj are the radii of the two particles and Rc is the
cutoff.
</P>
<P>In contrast to <A HREF = "pair_yukawa.html">pair_style yukawa</A>, this functional
form arises from the Coulombic interaction between two colloid
particles, screened due to the presence of an electrolyte.
<A HREF = "pair_yukawa.html">Pair_style yukawa</A> is a screened Coulombic potential
between two point-charges and uses no such approximation.
</P>
<P>This potential applies to nearby particle pairs for which the Derjagin
approximation holds, meaning h << Ri + Rj, where h is the
surface-to-surface separation of the two particles.
</P>
<P>When used in combination with <A HREF = "pair_colloid.html">pair_style colloid</A>,
the two terms become the so-called DLVO potential, which combines
electrostatic repulsion and van der Waals attraction.
</P>
<P>The following coefficients must be defined for each pair of atoms
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
above, or in the data file or restart files read by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands, or by mixing as described below:
</P>
<UL><LI>A (energy/distance units)
<LI>cutoff (distance units)
</UL>
<P>The prefactor A is determined from the relationship between surface
charge and surface potential due to the presence of electrolyte. Note
that the A for this potential style has different units than the A
used in <A HREF = "pair_yukawa.html">pair_style yukawa</A>. For low surface
potentials, i.e. less than about 25 mV, A can be written as:
</P>
<PRE>A = 2 * PI * R*eps*eps0 * kappa * psi^2
</PRE>
<P>where
</P>
<UL><LI>R = colloid radius (distance units)
<LI>eps0 = permittivity of free space (charge^2/energy/distance units)
<LI>eps = relative permittivity of fluid medium (dimensionless)
<LI>kappa = inverse screening length (1/distance units)
<LI>psi = surface potential (energy/charge units)
</UL>
<P>The last coefficient is optional. If not specified, the global
yukawa/colloid cutoff is used.
</P>
<HR>
-<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in <A HREF = "Section_accelerate.html">this section</A> of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_6">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
-<P>See <A HREF = "Section_accelerate.html">this section</A> of the manual for more
-instructions on how to use the accelerated styles effectively.
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is an energy value mixed
like a LJ epsilon. The default mix value is <I>geometric</I>. See the
"pair_modify" command for details.
</P>
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
option for the energy of the pair interaction.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> table option is not relevant
for this pair style.
</P>
<P>This pair style does not support the <A HREF = "pair_modify.html">pair_modify</A>
tail option for adding long-range tail corrections to energy and
pressure.
</P>
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
files</A>, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
</P>
<P>This pair style can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. It does not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This style is part of the COLLOID package. It is only enabled if
LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info.
</P>
<P>This pair style requires that atoms be finite-size spheres with a
diameter, as defined by the <A HREF = "atom_style.html">atom_style sphere</A>
command.
</P>
<P>Per-particle polydispersity is not yet supported by this pair style;
per-type polydispersity is allowed. This means all particles of the
same type must have the same diameter. Each type can have a different
diameter.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_yukawa_colloid.txt b/doc/pair_yukawa_colloid.txt
index fc85fe3db..70eb071d5 100644
--- a/doc/pair_yukawa_colloid.txt
+++ b/doc/pair_yukawa_colloid.txt
@@ -1,146 +1,146 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
pair_style yukawa/colloid command :h3
pair_style yukawa/colloid/omp command :h3
[Syntax:]
pair_style yukawa/colloid kappa cutoff :pre
kappa = screening length (inverse distance units)
cutoff = global cutoff for colloidal Yukawa interactions (distance units) :ul
[Examples:]
pair_style yukawa/colloid 2.0 2.5
pair_coeff 1 1 100.0 2.3
pair_coeff * * 100.0 :pre
[Description:]
Style {yukawa/colloid} computes pairwise interactions with the formula
:c,image(Eqs/pair_yukawa_colloid.jpg)
where Ri and Rj are the radii of the two particles and Rc is the
cutoff.
In contrast to "pair_style yukawa"_pair_yukawa.html, this functional
form arises from the Coulombic interaction between two colloid
particles, screened due to the presence of an electrolyte.
"Pair_style yukawa"_pair_yukawa.html is a screened Coulombic potential
between two point-charges and uses no such approximation.
This potential applies to nearby particle pairs for which the Derjagin
approximation holds, meaning h << Ri + Rj, where h is the
surface-to-surface separation of the two particles.
When used in combination with "pair_style colloid"_pair_colloid.html,
the two terms become the so-called DLVO potential, which combines
electrostatic repulsion and van der Waals attraction.
The following coefficients must be defined for each pair of atoms
types via the "pair_coeff"_pair_coeff.html command as in the examples
above, or in the data file or restart files read by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands, or by mixing as described below:
A (energy/distance units)
cutoff (distance units) :ul
The prefactor A is determined from the relationship between surface
charge and surface potential due to the presence of electrolyte. Note
that the A for this potential style has different units than the A
used in "pair_style yukawa"_pair_yukawa.html. For low surface
potentials, i.e. less than about 25 mV, A can be written as:
A = 2 * PI * R*eps*eps0 * kappa * psi^2 :pre
where
R = colloid radius (distance units)
eps0 = permittivity of free space (charge^2/energy/distance units)
eps = relative permittivity of fluid medium (dimensionless)
kappa = inverse screening length (1/distance units)
psi = surface potential (energy/charge units) :ul
The last coefficient is optional. If not specified, the global
yukawa/colloid cutoff is used.
:line
-Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
-the same as the corresponding style without the suffix. They have
-been optimized to run faster, depending on your available hardware,
-as discussed in "this section"_Section_accelerate.html of the manual.
-The accelerated styles take the same arguments and should produce the
-same results, except for round-off and precision issues.
+Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
+the same as the corresponding style without the suffix. They have
+been optimized to run faster, depending on your available hardware, as
+discussed in "Section_accelerate"_Section_accelerate.html of the
+manual. The accelerated styles take the same arguments and should
+produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_6 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
-See "this section"_Section_accelerate.html of the manual for more
-instructions on how to use the accelerated styles effectively.
+See "Section_accelerate"_Section_accelerate.html of the manual for
+more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
For atom type pairs I,J and I != J, the A coefficient and cutoff
distance for this pair style can be mixed. A is an energy value mixed
like a LJ epsilon. The default mix value is {geometric}. See the
"pair_modify" command for details.
This pair style supports the "pair_modify"_pair_modify.html shift
option for the energy of the pair interaction.
The "pair_modify"_pair_modify.html table option is not relevant
for this pair style.
This pair style does not support the "pair_modify"_pair_modify.html
tail option for adding long-range tail corrections to energy and
pressure.
This pair style writes its information to "binary restart
files"_restart.html, so pair_style and pair_coeff commands do not need
to be specified in an input script that reads a restart file.
This pair style can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. It does not support the
{inner}, {middle}, {outer} keywords.
:line
[Restrictions:]
This style is part of the COLLOID package. It is only enabled if
LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info.
This pair style requires that atoms be finite-size spheres with a
diameter, as defined by the "atom_style sphere"_atom_style.html
command.
Per-particle polydispersity is not yet supported by this pair style;
per-type polydispersity is allowed. This means all particles of the
same type must have the same diameter. Each type can have a different
diameter.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
diff --git a/doc/partition.html b/doc/partition.html
new file mode 100644
index 000000000..643565368
--- /dev/null
+++ b/doc/partition.html
@@ -0,0 +1,78 @@
+<HTML>
+<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
+</CENTER>
+
+
+
+
+
+
+<HR>
+
+<H3>partition command
+</H3>
+<P><B>Syntax:</B>
+</P>
+<PRE>partition style Np command ...
+</PRE>
+<UL><LI>style = <I>yes</I> or <I>no</I>
+<LI>Np = partition number (see asterisk form below)
+<LI>command = any LAMMPS command
+</UL>
+<P><B>Examples:</B>
+</P>
+<PRE>partition yes 1 processors 4 10 6
+partition no 5 print "Active partition"
+partition yes *5 fix all nve
+partition yes 6* fix all nvt temp 1.0 1.0 0.1
+</PRE>
+<P><B>Description:</B>
+</P>
+<P>This command invokes the specified command on a subset of the
+partitions of processors you have defined via the -partition
+command-line switch. See <A HREF = "Section_start.html#start_6">Section_start 6</A>
+for an explanation of the switch.
+</P>
+<P>Normally, every input script command in your script is invoked by
+every partition. This behavior can be modified by defining world- or
+universe-style <A HREF = "variable.html">variables</A> that have different values
+for each partition. This mechanism can be used to cause your script
+to jump to different input script files on different partitions, if
+such a variable is used in a <A HREF = "jump.html">jump</A> command.
+</P>
+<P>The "partition" command is another mechanism for having as input
+script operate differently on different partitions. It is basically a
+prefix on any LAMMPS command. The commmand will only be invoked on
+the partition(s) specified by the <I>style</I> and <I>Np</I> arguments.
+</P>
+<P>If the <I>style</I> is <I>yes</I>, the command will be invoked on any
+partition which matches the Np argument. If the <I>style</I> is <I>no</I>
+the command will be invoked on all the partitions which do not
+match the Np argument.
+</P>
+<P>Partitions are numbered from 1 to N, where N is the number of
+partitions specified by the <A HREF = "Section_start.html#start_6">-partition command-line
+switch</A>.
+</P>
+<P>Np can be specified in one of two ways. An explicit numeric value can
+be used, as in the 1st example above. Or a wild-card asterisk can be
+used to span a range of partition numbers. This takes the form "*" or
+"*n" or "n*" or "m*n". An asterisk with no numeric values means all
+partitions from 1 to N. A leading asterisk means all partitions from
+1 to n (inclusive). A trailing asterisk means all partitions from n
+to N (inclusive). A middle asterisk means all partitions from m to n
+(inclusive).
+</P>
+<P>This command can be useful for the "run_style verlet/split" command
+which imposed requirements on how the <A HREF = "processors.html">processors</A>
+command lays out a 3d grid of processors in each of 2 partitions.
+</P>
+<P><B>Restrictions:</B> none
+</P>
+<P><B>Related commands:</B> none
+</P>
+<P><A HREF = "run_style.html">run_style verlet/split</A>
+</P>
+<P><B>Default:</B> none
+</P>
+</HTML>
diff --git a/doc/partition.txt b/doc/partition.txt
new file mode 100644
index 000000000..65f98b545
--- /dev/null
+++ b/doc/partition.txt
@@ -0,0 +1,73 @@
+"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
+
+partition command :h3
+
+[Syntax:]
+
+partition style Np command ... :pre
+
+style = {yes} or {no}
+Np = partition number (see asterisk form below)
+command = any LAMMPS command :ul
+
+[Examples:]
+
+partition yes 1 processors 4 10 6
+partition no 5 print "Active partition"
+partition yes *5 fix all nve
+partition yes 6* fix all nvt temp 1.0 1.0 0.1 :pre
+
+[Description:]
+
+This command invokes the specified command on a subset of the
+partitions of processors you have defined via the -partition
+command-line switch. See "Section_start 6"_Section_start.html#start_6
+for an explanation of the switch.
+
+Normally, every input script command in your script is invoked by
+every partition. This behavior can be modified by defining world- or
+universe-style "variables"_variable.html that have different values
+for each partition. This mechanism can be used to cause your script
+to jump to different input script files on different partitions, if
+such a variable is used in a "jump"_jump.html command.
+
+The "partition" command is another mechanism for having as input
+script operate differently on different partitions. It is basically a
+prefix on any LAMMPS command. The commmand will only be invoked on
+the partition(s) specified by the {style} and {Np} arguments.
+
+If the {style} is {yes}, the command will be invoked on any
+partition which matches the Np argument. If the {style} is {no}
+the command will be invoked on all the partitions which do not
+match the Np argument.
+
+Partitions are numbered from 1 to N, where N is the number of
+partitions specified by the "-partition command-line
+switch"_Section_start.html#start_6.
+
+Np can be specified in one of two ways. An explicit numeric value can
+be used, as in the 1st example above. Or a wild-card asterisk can be
+used to span a range of partition numbers. This takes the form "*" or
+"*n" or "n*" or "m*n". An asterisk with no numeric values means all
+partitions from 1 to N. A leading asterisk means all partitions from
+1 to n (inclusive). A trailing asterisk means all partitions from n
+to N (inclusive). A middle asterisk means all partitions from m to n
+(inclusive).
+
+This command can be useful for the "run_style verlet/split" command
+which imposed requirements on how the "processors"_processors.html
+command lays out a 3d grid of processors in each of 2 partitions.
+
+[Restrictions:] none
+
+[Related commands:] none
+
+"run_style verlet/split"_run_style.html
+
+[Default:] none
diff --git a/doc/prd.html b/doc/prd.html
index 270a48c0a..baad8b3df 100644
--- a/doc/prd.html
+++ b/doc/prd.html
@@ -1,314 +1,314 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>prd command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>prd N t_event n_dephase t_dephase t_correlate compute-ID seed keyword value ...
</PRE>
<UL><LI>N = # of timesteps to run (not including dephasing/quenching)
<LI>t_event = timestep interval between event checks
<LI>n_dephase = number of velocity randomizations to perform in each dephase run
<LI>t_dephase = number of timesteps to run dynamics after each velocity randomization during dephase
<LI>t_correlate = number of timesteps within which 2 consecutive events are considered to be correlated
<LI>compute-ID = ID of the compute used for event detection
<LI>random_seed = random # seed (positive integer)
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>min</I> or <I>temp</I> or <I>vel</I>
<PRE> <I>min</I> values = etol ftol maxiter maxeval
etol = stopping tolerance for energy, used in quenching
ftol = stopping tolerance for force, used in quenching
maxiter = max iterations of minimize, used in quenching
maxeval = max number of force/energy evaluations, used in quenching
<I>temp</I> value = Tdephase
Tdephase = target temperature for velocity randomization, used in dephasing
<I>vel</I> values = loop dist
loop = <I>all</I> or <I>local</I> or <I>geom</I>, used in dephasing
dist = <I>uniform</I> or <I>gaussian</I>, used in dephasing
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>prd 5000 100 10 10 100 1 54982
prd 5000 100 10 10 100 1 54982 min 0.1 0.1 100 200
</PRE>
<P><B>Description:</B>
</P>
<P>Run a parallel replica dynamics (PRD) simulation using multiple
replicas of a system. One or more replicas can be used.
</P>
<P>PRD is described in <A HREF = "#Voter">this paper</A> by Art Voter. It is a method
for performing accelerated dynamics that is suitable for
infrequent-event systems that obey first-order kinetics. A good
overview of accelerated dynamics methods for such systems in given in
<A HREF = "#Voter2">this review paper</A> from the same group. To quote from the
paper: "The dynamical evolution is characterized by vibrational
excursions within a potential basin, punctuated by occasional
transitions between basins." The transition probability is
characterized by p(t) = k*exp(-kt) where k is the rate constant.
Running multiple replicas gives an effective enhancement in the
timescale spanned by the multiple simulations, while waiting for an
event to occur.
</P>
<P>Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see <A HREF = "Section_start.html#start_6">this section</A> of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. For PRD, this makes little sense, since this offers no
-effective parallel speed-up in searching for infrequent events. See
-<A HREF = "Section_howto.html#howto_5">this section</A> of the manual for further
+switch; see <A HREF = "Section_start.html#start_6">Section_start 6</A> of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. For PRD, this makes little sense, since this offers
+no effective parallel speed-up in searching for infrequent events. See
+<A HREF = "Section_howto.html#howto_5">Section_howto 5</A> of the manual for further
discussion.
</P>
<P>When a PRD simulation is performed, it is assumed that each replica is
running the same model, though LAMMPS does not check for this.
I.e. the simulation domain, the number of atoms, the interaction
potentials, etc should be the same for every replica.
</P>
<P>A PRD run has several stages, which are repeated each time an "event"
occurs in one of the replicas, as defined below. The logic for a PRD
run is as follows:
</P>
<PRE>while (time remains):
dephase for n_dephase*t_dephase steps
until (event occurs on some replica):
run dynamics for t_event steps
quench
check for uncorrelated event on any replica
until (no correlated event occurs):
run dynamics for t_correlate steps
quench
check for correlated event on this replica
event replica shares state with all replicas
</PRE>
<P>Before this loop begins, the state of the system on replica 0 is
shared with all replicas, so that all replicas begin from the same
initial state. The first potential energy basin is identified by
quenching (an energy minimization, see below) the initial state and
storing the resulting coordinates for reference.
</P>
<P>In the first stage, dephasing is performed by each replica
independently to eliminate correlations between replicas. This is
done by choosing a random set of velocities, based on the
<I>random_seed</I> that is specified, and running <I>t_dephase</I> timesteps of
dynamics. This is repeated <I>n_dephase</I> times. If the <I>temp</I> keyword
is not specified, the target temperature for velocity randomization
for each replica is the current temperature of that replica.
Otherwise, it is the specified <I>Tdephase</I> temperature. The style of
velocity randomization is controlled using the keyword <I>vel</I> with
arguments that have the same meaning as their counterparts in the
<A HREF = "velocity.html">velocity</A> command.
</P>
<P>In the second stage, each replica runs dynamics continuously, stopping
every <I>t_event</I> steps to check if a transition event has occurred.
This check is performed by quenching the system and comparing the
resulting atom coordinates to the coordinates from the previous basin.
The first time through the PRD loop, the "previous basin" is the set
of quenched coordinates from the initial state of the system.
</P>
<P>A quench is an energy minimization and is performed by whichever
algorithm has been defined by the <A HREF = "min_style.html">min_style</A> command.
Minimization parameters may be set via the
<A HREF = "min_modify.html">min_modify</A> command and by the <I>min</I> keyword of the
PRD command. The latter are the settings that would be used with the
<A HREF = "minimize.html">minimize</A> command. Note that typically, you do not
need to perform a highly-converged minimization to detect a transition
event.
</P>
<P>The event check is performed by a compute with the specified
<I>compute-ID</I>. Currently there is only one compute that works with the
PRD commmand, which is the <A HREF = "compute_event_displace.html">compute
event/displace</A> command. Other
event-checking computes may be added. <A HREF = "compute_event_displace.html">Compute
event/displace</A> checks whether any atom in
the compute group has moved further than a specified threshold
distance. If so, an "event" has occurred.
</P>
<P>In the third stage, the replica on which the event occurred (event
replica) continues to run dynamics to search for correlated events.
This is done by running dynamics for <I>t_correlate</I> steps, quenching
every <I>t_event</I> steps, and checking if another event has occurred.
The first time no correlated event occurs, the final state of the
event replica is shared with all replicas, the new basin reference
coordinates are updated with the quenched state, and the outer loop
begins again. While the replica event is searching for correlated
events, all the other replicas also run dynamics and event checking
with the same schedule, but the final states are always overwritten by
the state of the event replica.
</P>
<HR>
<P>Four kinds of output can be generated during a PRD run: event
statistics, thermodynamic output by each replica, dump files, and
restart files.
</P>
<P>When running with multiple partitions (each of which is a replica in
this case), the print-out to the screen and master log.lammps file is
limited to event statistics. Note that if a PRD run is performed on
only a single replica then the event statistics will be intermixed
with the usual thermodynamic output discussed below.
</P>
<P>The quantities printed each time an event occurs are the timestep,
CPU time, clock, event number, a correlation flag,
the number of coincident events, and the replica number of the chosen event.
</P>
<P>The timestep is the usual LAMMPS timestep, except that time does not
advance during dephasing or quenches, but only during dynamics. Note
that are two kinds of dynamics in the PRD loop listed above. The
first is when all replicas are performing independent dynamics. The
second is when correlated events are being searched for and only one
replica is running dynamics.
</P>
<P>The CPU time is the total processor time since the start of the PRD
run.
</P>
<P>The clock is the same as the timestep except that it advances by M
steps every timestep during the first kind of dynamics when the M
replicas are running independently. The clock represents the real
time that effectively elapses during a PRD simulation of <I>N</I> steps on
M replicas. If most of the PRD run is spent in the second stage of
the loop above, searching for infrequent events, then the clock will
advance nearly N*M steps. Note the clock time between events will be
drawn from p(t).
</P>
<P>The event number is a counter that increments with each event, whether
it is uncorrelated or correlated.
</P>
<P>The correlation flag will be 0 when an uncorrelated event occurs
during the second stage of the loop listed above, i.e. when all
replicas are running independently. The correlation flag will be 1
when a correlated event occurs during the third stage of the loop
listed above, i.e. when only one replica is running dynamics.
</P>
<P>When more than one replica detects an event at the end of the second
stage, then one of them is chosen at random. The number of coincident
events is the number of replicas that detected an event. Normally, we
expect this value to be 1. If it is often greater than 1, then either
the number of replicas is too large, or <I>t_event</I> is too large.
</P>
<P>The replica number is the ID of the replica (from 0 to M-1) that
found the event.
</P>
<HR>
<P>When running on multiple partitions, LAMMPS produces additional log
files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For
the PRD command, these contain the thermodynamic output for each
replica. You will see short runs and minimizations corresponding to
the dynamics and quench operations of the loop listed above. The
timestep will be reset aprpopriately depending on whether the
operation advances time or not.
</P>
<P>After the PRD command completes, timing statistics for the PRD run are
printed in each replica's log file, giving a breakdown of how much CPU
time was spent in each stage (dephasing, dynamics, quenching, etc).
</P>
<HR>
<P>Any <A HREF = "dump.html">dump files</A> defined in the input script, will be
written to during a PRD run at timesteps corresponding to both
uncorrelated and correlated events. This means the the requested dump
frequency in the <A HREF = "dump.html">dump</A> command is ignored. There will be
one dump file (per dump command) created for all partitions.
</P>
<P>The atom coordinates of the dump snapshot are those of the minimum
energy configuration resulting from quenching following a transition
event. The timesteps written into the dump files correspond to the
timestep at which the event occurred and NOT the clock. A dump
snapshot corresponding to the initial minimum state used for event
detection is written to the dump file at the beginning of each PRD
run.
</P>
<HR>
<P>If the <A HREF = "restart.html">restart</A> command is used, a single restart file
for all the partitions is generated, which allows a PRD run to be
continued by a new input script in the usual manner.
</P>
<P>The restart file is generated at the end of the loop listed above. If
no correlated events are found, this means it contains a snapshot of
the system at time T + <I>t_correlate</I>, where T is the time at which the
uncorrelated event occurred. If correlated events were found, then it
contains a snapshot of the system at time T + <I>t_correlate</I>, where T
is the time of the last correlated event.
</P>
<P>The restart frequency specified in the <A HREF = "restart.html">restart</A> command
is interpreted differently when performing a PRD run. It does not
mean the timestep interval between restart files. Instead it means an
event interval for uncorrelated events. Thus a frequency of 1 means
write a restart file every time an uncorrelated event occurs. A
frequency of 10 means write a restart file every 10th uncorrelated
event.
</P>
<P>When an input script reads a restart file from a previous PRD run, the
new script can be run on a different number of replicas or processors.
However, it is assumed that <I>t_correlate</I> in the new PRD command is
the same as it was previously. If not, the calculation of the "clock"
value for the first event in the new run will be slightly off.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><I>N</I> and <I>t_correlate</I> settings must be integer multiples of
<I>t_event</I>.
</P>
<P>Runs restarted from restart file written during a PRD run will not
produce identical results due to changes in the random numbers used
for dephasing.
</P>
<P>This command cannot be used when any fixes are defined that keep track
of elapsed time to perform time-dependent operations. Examples
include the "ave" fixes such as <A HREF = "fix_ave_spatial.html">fix
ave/spatial</A>. Also <A HREF = "fix_dt_reset.html">fix
dt/reset</A> and <A HREF = "fix_deposit.html">fix deposit</A>.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_event_displace.html">compute event/displace</A>,
<A HREF = "min_modify.html">min_modify</A>, <A HREF = "min_style.html">min_style</A>,
<A HREF = "run_style.html">run_style</A>, <A HREF = "minimize.html">minimize</A>,
<A HREF = "velocity.html">velocity</A>, <A HREF = "temper.html">temper</A>, <A HREF = "neb.html">neb</A>,
<A HREF = "tad.html">tad</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are <I>min</I> = 0.1 0.1 40 50, no <I>temp</I> setting, and
<I>vel</I> = <I>geom</I> <I>gaussian</I>.
</P>
<HR>
<A NAME = "Voter"></A>
<P><B>(Voter)</B> Voter, Phys Rev B, 57, 13985 (1998).
</P>
<A NAME = "Voter2"></A>
<P><B>(Voter2)</B> Voter, Montalenti, Germann, Annual Review of Materials
Research 32, 321 (2002).
</P>
</HTML>
diff --git a/doc/prd.txt b/doc/prd.txt
index 33130c17b..52c5406ee 100644
--- a/doc/prd.txt
+++ b/doc/prd.txt
@@ -1,297 +1,297 @@
"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
prd command :h3
[Syntax:]
prd N t_event n_dephase t_dephase t_correlate compute-ID seed keyword value ... :pre
N = # of timesteps to run (not including dephasing/quenching) :ulb,l
t_event = timestep interval between event checks :l
n_dephase = number of velocity randomizations to perform in each dephase run :l
t_dephase = number of timesteps to run dynamics after each velocity randomization during dephase :l
t_correlate = number of timesteps within which 2 consecutive events are considered to be correlated :l
compute-ID = ID of the compute used for event detection :l
random_seed = random # seed (positive integer) :l
zero or more keyword/value pairs may be appended :l
keyword = {min} or {temp} or {vel} :l
{min} values = etol ftol maxiter maxeval
etol = stopping tolerance for energy, used in quenching
ftol = stopping tolerance for force, used in quenching
maxiter = max iterations of minimize, used in quenching
maxeval = max number of force/energy evaluations, used in quenching
{temp} value = Tdephase
Tdephase = target temperature for velocity randomization, used in dephasing
{vel} values = loop dist
loop = {all} or {local} or {geom}, used in dephasing
dist = {uniform} or {gaussian}, used in dephasing :pre
:ule
[Examples:]
prd 5000 100 10 10 100 1 54982
prd 5000 100 10 10 100 1 54982 min 0.1 0.1 100 200 :pre
[Description:]
Run a parallel replica dynamics (PRD) simulation using multiple
replicas of a system. One or more replicas can be used.
PRD is described in "this paper"_#Voter by Art Voter. It is a method
for performing accelerated dynamics that is suitable for
infrequent-event systems that obey first-order kinetics. A good
overview of accelerated dynamics methods for such systems in given in
"this review paper"_#Voter2 from the same group. To quote from the
paper: "The dynamical evolution is characterized by vibrational
excursions within a potential basin, punctuated by occasional
transitions between basins." The transition probability is
characterized by p(t) = k*exp(-kt) where k is the rate constant.
Running multiple replicas gives an effective enhancement in the
timescale spanned by the multiple simulations, while waiting for an
event to occur.
Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see "this section"_Section_start.html#start_6 of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. For PRD, this makes little sense, since this offers no
-effective parallel speed-up in searching for infrequent events. See
-"this section"_Section_howto.html#howto_5 of the manual for further
+switch; see "Section_start 6"_Section_start.html#start_6 of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. For PRD, this makes little sense, since this offers
+no effective parallel speed-up in searching for infrequent events. See
+"Section_howto 5"_Section_howto.html#howto_5 of the manual for further
discussion.
When a PRD simulation is performed, it is assumed that each replica is
running the same model, though LAMMPS does not check for this.
I.e. the simulation domain, the number of atoms, the interaction
potentials, etc should be the same for every replica.
A PRD run has several stages, which are repeated each time an "event"
occurs in one of the replicas, as defined below. The logic for a PRD
run is as follows:
while (time remains):
dephase for n_dephase*t_dephase steps
until (event occurs on some replica):
run dynamics for t_event steps
quench
check for uncorrelated event on any replica
until (no correlated event occurs):
run dynamics for t_correlate steps
quench
check for correlated event on this replica
event replica shares state with all replicas :pre
Before this loop begins, the state of the system on replica 0 is
shared with all replicas, so that all replicas begin from the same
initial state. The first potential energy basin is identified by
quenching (an energy minimization, see below) the initial state and
storing the resulting coordinates for reference.
In the first stage, dephasing is performed by each replica
independently to eliminate correlations between replicas. This is
done by choosing a random set of velocities, based on the
{random_seed} that is specified, and running {t_dephase} timesteps of
dynamics. This is repeated {n_dephase} times. If the {temp} keyword
is not specified, the target temperature for velocity randomization
for each replica is the current temperature of that replica.
Otherwise, it is the specified {Tdephase} temperature. The style of
velocity randomization is controlled using the keyword {vel} with
arguments that have the same meaning as their counterparts in the
"velocity"_velocity.html command.
In the second stage, each replica runs dynamics continuously, stopping
every {t_event} steps to check if a transition event has occurred.
This check is performed by quenching the system and comparing the
resulting atom coordinates to the coordinates from the previous basin.
The first time through the PRD loop, the "previous basin" is the set
of quenched coordinates from the initial state of the system.
A quench is an energy minimization and is performed by whichever
algorithm has been defined by the "min_style"_min_style.html command.
Minimization parameters may be set via the
"min_modify"_min_modify.html command and by the {min} keyword of the
PRD command. The latter are the settings that would be used with the
"minimize"_minimize.html command. Note that typically, you do not
need to perform a highly-converged minimization to detect a transition
event.
The event check is performed by a compute with the specified
{compute-ID}. Currently there is only one compute that works with the
PRD commmand, which is the "compute
event/displace"_compute_event_displace.html command. Other
event-checking computes may be added. "Compute
event/displace"_compute_event_displace.html checks whether any atom in
the compute group has moved further than a specified threshold
distance. If so, an "event" has occurred.
In the third stage, the replica on which the event occurred (event
replica) continues to run dynamics to search for correlated events.
This is done by running dynamics for {t_correlate} steps, quenching
every {t_event} steps, and checking if another event has occurred.
The first time no correlated event occurs, the final state of the
event replica is shared with all replicas, the new basin reference
coordinates are updated with the quenched state, and the outer loop
begins again. While the replica event is searching for correlated
events, all the other replicas also run dynamics and event checking
with the same schedule, but the final states are always overwritten by
the state of the event replica.
:line
Four kinds of output can be generated during a PRD run: event
statistics, thermodynamic output by each replica, dump files, and
restart files.
When running with multiple partitions (each of which is a replica in
this case), the print-out to the screen and master log.lammps file is
limited to event statistics. Note that if a PRD run is performed on
only a single replica then the event statistics will be intermixed
with the usual thermodynamic output discussed below.
The quantities printed each time an event occurs are the timestep,
CPU time, clock, event number, a correlation flag,
the number of coincident events, and the replica number of the chosen event.
The timestep is the usual LAMMPS timestep, except that time does not
advance during dephasing or quenches, but only during dynamics. Note
that are two kinds of dynamics in the PRD loop listed above. The
first is when all replicas are performing independent dynamics. The
second is when correlated events are being searched for and only one
replica is running dynamics.
The CPU time is the total processor time since the start of the PRD
run.
The clock is the same as the timestep except that it advances by M
steps every timestep during the first kind of dynamics when the M
replicas are running independently. The clock represents the real
time that effectively elapses during a PRD simulation of {N} steps on
M replicas. If most of the PRD run is spent in the second stage of
the loop above, searching for infrequent events, then the clock will
advance nearly N*M steps. Note the clock time between events will be
drawn from p(t).
The event number is a counter that increments with each event, whether
it is uncorrelated or correlated.
The correlation flag will be 0 when an uncorrelated event occurs
during the second stage of the loop listed above, i.e. when all
replicas are running independently. The correlation flag will be 1
when a correlated event occurs during the third stage of the loop
listed above, i.e. when only one replica is running dynamics.
When more than one replica detects an event at the end of the second
stage, then one of them is chosen at random. The number of coincident
events is the number of replicas that detected an event. Normally, we
expect this value to be 1. If it is often greater than 1, then either
the number of replicas is too large, or {t_event} is too large.
The replica number is the ID of the replica (from 0 to M-1) that
found the event.
:line
When running on multiple partitions, LAMMPS produces additional log
files for each partition, e.g. log.lammps.0, log.lammps.1, etc. For
the PRD command, these contain the thermodynamic output for each
replica. You will see short runs and minimizations corresponding to
the dynamics and quench operations of the loop listed above. The
timestep will be reset aprpopriately depending on whether the
operation advances time or not.
After the PRD command completes, timing statistics for the PRD run are
printed in each replica's log file, giving a breakdown of how much CPU
time was spent in each stage (dephasing, dynamics, quenching, etc).
:line
Any "dump files"_dump.html defined in the input script, will be
written to during a PRD run at timesteps corresponding to both
uncorrelated and correlated events. This means the the requested dump
frequency in the "dump"_dump.html command is ignored. There will be
one dump file (per dump command) created for all partitions.
The atom coordinates of the dump snapshot are those of the minimum
energy configuration resulting from quenching following a transition
event. The timesteps written into the dump files correspond to the
timestep at which the event occurred and NOT the clock. A dump
snapshot corresponding to the initial minimum state used for event
detection is written to the dump file at the beginning of each PRD
run.
:line
If the "restart"_restart.html command is used, a single restart file
for all the partitions is generated, which allows a PRD run to be
continued by a new input script in the usual manner.
The restart file is generated at the end of the loop listed above. If
no correlated events are found, this means it contains a snapshot of
the system at time T + {t_correlate}, where T is the time at which the
uncorrelated event occurred. If correlated events were found, then it
contains a snapshot of the system at time T + {t_correlate}, where T
is the time of the last correlated event.
The restart frequency specified in the "restart"_restart.html command
is interpreted differently when performing a PRD run. It does not
mean the timestep interval between restart files. Instead it means an
event interval for uncorrelated events. Thus a frequency of 1 means
write a restart file every time an uncorrelated event occurs. A
frequency of 10 means write a restart file every 10th uncorrelated
event.
When an input script reads a restart file from a previous PRD run, the
new script can be run on a different number of replicas or processors.
However, it is assumed that {t_correlate} in the new PRD command is
the same as it was previously. If not, the calculation of the "clock"
value for the first event in the new run will be slightly off.
:line
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
{N} and {t_correlate} settings must be integer multiples of
{t_event}.
Runs restarted from restart file written during a PRD run will not
produce identical results due to changes in the random numbers used
for dephasing.
This command cannot be used when any fixes are defined that keep track
of elapsed time to perform time-dependent operations. Examples
include the "ave" fixes such as "fix
ave/spatial"_fix_ave_spatial.html. Also "fix
dt/reset"_fix_dt_reset.html and "fix deposit"_fix_deposit.html.
[Related commands:]
"compute event/displace"_compute_event_displace.html,
"min_modify"_min_modify.html, "min_style"_min_style.html,
"run_style"_run_style.html, "minimize"_minimize.html,
"velocity"_velocity.html, "temper"_temper.html, "neb"_neb.html,
"tad"_tad.html
[Default:]
The option defaults are {min} = 0.1 0.1 40 50, no {temp} setting, and
{vel} = {geom} {gaussian}.
:line
:link(Voter)
[(Voter)] Voter, Phys Rev B, 57, 13985 (1998).
:link(Voter2)
[(Voter2)] Voter, Montalenti, Germann, Annual Review of Materials
Research 32, 321 (2002).
diff --git a/doc/processors.html b/doc/processors.html
index 4839bee67..7538de61a 100644
--- a/doc/processors.html
+++ b/doc/processors.html
@@ -1,68 +1,331 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>processors command
</H3>
<P><B>Syntax:</B>
</P>
-<PRE>processors Px Py Pz
+<PRE>processors Px Py Pz keyword args ...
</PRE>
-<UL><LI>Px,Py,Pz = # of processors in each dimension of a 3d grid
+<UL><LI>Px,Py,Pz = # of processors in each dimension of 3d grid overlaying the simulation domain
+
+<LI>zero or more keyword/arg pairs may be appended
+
+<LI>keyword = <I>grid</I> or <I>map</I> or <I>part</I> or <I>file</I>
+
+<PRE> <I>grid</I> arg = gstyle params ...
+ gstyle = <I>onelevel</I> or <I>twolevel</I> or <I>numa</I> or <I>custom</I>
+ onelevel params = none
+ twolevel params = Nc Cx Cy Cz
+ Nc = number of cores per node
+ Cx,Cy,Cz = # of cores in each dimension of 3d sub-grid assigned to each node
+ numa params = none
+ custom params = infile
+ infile = file containing grid layout
+ <I>map</I> arg = <I>cart</I> or <I>cart/reorder</I> or <I>xyz</I> or <I>xzy</I> or <I>yxz</I> or <I>yzx</I> or <I>zxy</I> or <I>zyx</I>
+ cart = use MPI_Cart() methods to map processors to 3d grid with reorder = 0
+ cart/reorder = use MPI_Cart() methods to map processors to 3d grid with reorder = 1
+ xyz,xzy,yxz,yzx,zxy,zyx = map procesors to 3d grid in IJK ordering
+ <I>numa</I> arg = none
+ <I>part</I> args = Psend Precv cstyle
+ Psend = partition # (1 to Np) which will send its processor layout
+ Precv = partition # (1 to Np) which will recv the processor layout
+ cstyle = <I>multiple</I>
+ <I>multiple</I> = Psend grid will be multiple of Precv grid in each dimension
+ <I>file</I> arg = outfile
+ outfile = name of file to write 3d grid of processors to
+</PRE>
+
</UL>
<P><B>Examples:</B>
</P>
-<PRE>processors 2 4 4
-processors * * 5
-processors * 1 10
+<PRE>processors * * 5
+processors 2 4 4
+processors * * 8 map xyz
+processors * * * grid numa
+processors * * * grid twolevel 4 * * 1
+processors 4 8 16 grid custom myfile
+processors * * * part 1 2 multiple
</PRE>
<P><B>Description:</B>
</P>
<P>Specify how processors are mapped as a 3d logical grid to the global
-simulation box, namely Px by Py by Pz.
+simulation box. This involves 2 steps. First if there are P
+processors it means choosing a factorization P = Px by Py by Pz so
+that there are Px processors in the x dimension, and similarly for the
+y and z dimensions. Second, the P processors are mapped to the
+logical 3d grid. The arguments to this command control each of these
+2 steps.
</P>
-<P>Any of the Px, Py, Pz parameters can be specified with an asterisk
-"*", which means LAMMPS will choose the number of processors in that
-dimension. It will do this based on the size and shape of the global
-simulation box so as to minimize the surface-to-volume ratio of each
-processor's sub-domain.
+<P>The Px, Py, Pz parameters affect the factorization. Any of the 3
+parameters can be specified with an asterisk "*", which means LAMMPS
+will choose the number of processors in that dimension of the grid.
+It will do this based on the size and shape of the global simulation
+box so as to minimize the surface-to-volume ratio of each processor's
+sub-domain.
</P>
<P>Since LAMMPS does not load-balance by changing the grid of 3d
-processors on-the-fly, this command can be used to override the LAMMPS
-default if it is known to be sub-optimal for a particular problem.
-For example, a problem where the atom's extent will change
-dramatically in a particular dimension over the course of the
-simulation.
+processors on-the-fly, choosing explicit values for Px or Py or Pz can
+be used to override the LAMMPS default if it is known to be
+sub-optimal for a particular problem. E.g. a problem where the extent
+of atoms will change dramatically in a particular dimension over the
+course of the simulation.
</P>
<P>The product of Px, Py, Pz must equal P, the total # of processors
LAMMPS is running on. For a <A HREF = "dimension.html">2d simulation</A>, Pz must
-equal 1. If multiple partitions are being used then P is the number
-of processors in this partition; see <A HREF = "Section_start.html#start_6">this
+equal 1.
+</P>
+<P>Note that if you run on a prime number of processors P, then a grid
+such as 1 x P x 1 will be required, which may incur extra
+communication costs due to the high surface area of each processor's
+sub-domain.
+</P>
+<P>Also note that if multiple partitions are being used then P is the
+number of processors in this partition; see <A HREF = "Section_start.html#start_6">this
section</A> for an explanation of the
--partition command-line switch.
+-partition command-line switch. Also note that you can prefix the
+processors command with the <A HREF = "partition.html">partition</A> command to
+easily specify different Px,Py,Pz values for different partitions.
+</P>
+<P>You can use the <A HREF = "partition.html">partition</A> command to specify
+different processor grids for different partitions, e.g.
+</P>
+<PRE>partition yes 1 processors 4 4 4
+partition yes 2 processors 2 3 2
+</PRE>
+<HR>
+
+<P>The <I>grid</I> keyword affects the factorization of P into Px,Py,Pz and it
+can also affect how the P processor IDs are mapped to the 3d grid of
+processors.
+</P>
+<P>The <I>onelevel</I> style creates a 3d grid that is compatible with the
+Px,Py,Pz settings, and which minimizes the surface-to-volume ratio of
+each processor's sub-domain, as described above. The mapping of
+processors to the grid is determined by the <I>map</I> keyword setting.
+</P>
+<P>The <I>twolevel</I> style can be used on machines with multicore nodes to
+minimize off-node communication. It insures that contiguous
+sub-sections of the 3d grid are assigned to all the cores of a node.
+For example if <I>Nc</I> is 4, then 2x2x1 or 2x1x2 or 1x2x2 sub-sections of
+the 3d grid will correspond to the cores of each node. This affects
+both the factorization and mapping steps.
</P>
-<P>Note that if you run on a large, prime number of processors P, then a
-grid such as 1 x P x 1 will be required, which may incur extra
-communication costs.
+<P>The <I>Cx</I>, <I>Cy</I>, <I>Cz</I> settings are similar to the <I>Px</I>, <I>Py</I>, <I>Pz</I>
+settings, only their product should equal <I>Nc</I>. Any of the 3
+parameters can be specified with an asterisk "*", which means LAMMPS
+will choose the number of cores in that dimension of the node's
+sub-grid. As with Px,Py,Pz, it will do this based on the size and
+shape of the global simulation box so as to minimize the
+surface-to-volume ratio of each processor's sub-domain.
+</P>
+<P>IMPORTANT NOTE: For the <I>twolevel</I> style to work correctly, it
+assumes the MPI ranks of processors LAMMPS is running on are ordered
+by core and then by node. E.g. if you are running on 2 quad-core
+nodes, for a total of 8 processors, then it assumes processors 0,1,2,3
+are on node 1, and processors 4,5,6,7 are on node 2. This is the
+default rank ordering for most MPI implementations, but some MPIs
+provide options for this ordering, e.g. via environment variable
+settings.
+</P>
+<P>The <I>numa</I> style operates similar to the <I>twolevel</I> keyword except
+that it auto-detects the core count within the nodes. Currently, it
+does this in only 2 levels, but it may be extended in the future to
+account for socket topology and other non-uniform memory access (NUMA)
+costs. It also uses a different algorithm (iterative) than the
+<I>twolevel</I> keyword for doing the two-level factorization of the
+simulation box into a 3d processor grid to minimize off-node
+communication, and it does its own mapping of nodes and cores to the
+logical 3d grid. Thus it may produce a different or improved layout
+of the processors.
+</P>
+<P>The <I>numa</I> style will give an error if (a) there are less than 4 cores
+per node, or (b) the number of MPI processes is not divisible by the
+number of cores used per node, or (c) only 1 node is allocated, or (d)
+any of the Px or Py of Pz values is greater than 1.
+</P>
+<P>IMPORTANT NOTE: For the <I>numa</I> style to work correctly, it assumes
+the MPI ranks of processors LAMMPS is running on are ordered by core
+and then by node. See the same note for the <I>twolevel</I> keyword.
+</P>
+<P>The <I>custom</I> style uses the file <I>infile</I> to define both the 3d
+factorization and the mapping of processors to the grid.
+</P>
+<P>The file should have the following format. Any number of initial
+blank or comment lines (starting with a "#" character) can be present.
+The first non-blank, non-comment line should have
+3 values:
+</P>
+<PRE>Px Py Py
+</PRE>
+<P>These must be compatible with the total number of processors
+and the Px, Py, Pz settings of the processors commmand.
+</P>
+<P>This line should be immediately followed by
+P = Px*Py*Pz lines of the form:
+</P>
+<PRE>ID I J K
+</PRE>
+<P>where ID is a processor ID (from 0 to P-1) and I,J,K are the
+processors location in the 3d grid. I must be a number from 1 to Px
+(inclusive) and similarly for J and K. The P lines can be listed in
+any order, but no processor ID should appear more than once.
+</P>
+<HR>
+
+<P>The <I>map</I> keyword affects how the P processor IDs (from 0 to P-1) are
+mapped to the 3d grid of processors. It is only used by the
+<I>onelevel</I> and <I>twolevel</I> grid settings.
</P>
+<P>The <I>cart</I> style uses the family of MPI Cartesian functions to perform
+the mapping, namely MPI_Cart_create(), MPI_Cart_get(),
+MPI_Cart_shift(), and MPI_Cart_rank(). It invokes the
+MPI_Cart_create() function with its reorder flag = 0, so that MPI is
+not free to reorder the processors.
+</P>
+<P>The <I>cart/reorder</I> style does the same thing as the <I>cart</I> style
+except it sets the reorder flag to 1, so that MPI can reorder
+processors if it desires.
+</P>
+<P>The <I>xyz</I>, <I>xzy</I>, <I>yxz</I>, <I>yzx</I>, <I>zxy</I>, and <I>zyx</I> styles are all
+similar. If the style is IJK, then it maps the P processors to the
+grid so that the processor ID in the I direction varies fastest, the
+processor ID in the J direction varies next fastest, and the processor
+ID in the K direction varies slowest. For example, if you select
+style <I>xyz</I> and you have a 2x2x2 grid of 8 processors, the assignments
+of the 8 octants of the simulation domain will be:
+</P>
+<PRE>proc 0 = lo x, lo y, lo z octant
+proc 1 = hi x, lo y, lo z octant
+proc 2 = lo x, hi y, lo z octant
+proc 3 = hi x, hi y, lo z octant
+proc 4 = lo x, lo y, hi z octant
+proc 5 = hi x, lo y, hi z octant
+proc 6 = lo x, hi y, hi z octant
+proc 7 = hi x, hi y, hi z octant
+</PRE>
+<P>Note that, in principle, an MPI implementation on a particular machine
+should be aware of both the machine's network topology and the
+specific subset of processors and nodes that were assigned to your
+simulation. Thus its MPI_Cart calls can optimize the assignment of
+MPI processes to the 3d grid to minimize communication costs. In
+practice, however, few if any MPI implementations actually do this.
+So it is likely that the <I>cart</I> and <I>cart/reorder</I> styles simply give
+the same result as one of the IJK styles.
+</P>
+<P>Also note, that for the <I>twolevel</I> grid style, the <I>map</I> setting is
+used to first map the nodes to the 3d grid, then again to the cores
+within each node. For the latter step, the <I>cart</I> and <I>cart/reorder</I>
+styles are not supported, so an <I>xyz</I> style is used in their place.
+</P>
+<HR>
+
+<P>The <I>part</I> keyword affects the factorization of P into Px,Py,Pz.
+</P>
+<P>It can be useful when running in multi-partition mode, e.g. with the
+<A HREF = "run_style.html">run_style verlet/split</A> command. It specifies a
+dependency bewteen a sending partition <I>Psend</I> and a receiving
+partition <I>Precv</I> which is enforced when each is setting up their own
+mapping of their processors to the simulation box. Each of <I>Psend</I>
+and <I>Precv</I> must be integers from 1 to Np, where Np is the number of
+partitions you have defined via the <A HREF = "Section_start.html#start_6">-partition command-line
+switch</A>.
+</P>
+<P>A "dependency" means that the sending partition will create its 3d
+logical grid as Px by Py by Pz and after it has done this, it will
+send the Px,Py,Pz values to the receiving partition. The receiving
+partition will wait to receive these values before creating its own 3d
+logical grid and will use the sender's Px,Py,Pz values as a
+constraint. The nature of the constraint is determined by the
+<I>cstyle</I> argument.
+</P>
+<P>For a <I>cstyle</I> of <I>multiple</I>, each dimension of the sender's processor
+grid is required to be an integer multiple of the corresponding
+dimension in the receiver's processor grid. This is a requirement of
+the <A HREF = "run_style.html">run_style verlet/split</A> command.
+</P>
+<P>For example, assume the sending partition creates a 4x6x10 grid = 240
+processor grid. If the receiving partition is running on 80
+processors, it could create a 4x2x10 grid, but it will not create a
+2x4x10 grid, since in the y-dimension, 6 is not an integer multiple of
+4.
+</P>
+<P>IMPORTANT NOTE: If you use the <A HREF = "partition.html">partition</A> command to
+invoke different "processsors" commands on different partitions, and
+you also use the <I>part</I> keyword, then you must insure that both the
+sending and receiving partitions invoke the "processors" command that
+connects the 2 partitions via the <I>part</I> keyword. LAMMPS cannot
+easily check for this, but your simulation will likely hang in its
+setup phase if this error has been made.
+</P>
+<HR>
+
+<P>The <I>file</I> keyword writes the mapping of the factorization of P
+processors and their mapping to the 3d grid to the specified file
+<I>outfile</I>. This is useful to check that you assigned physical
+processors in the manner you desired, which can be tricky to figure
+out, especially when running on multiple partitions or on, a multicore
+machine or when the processor ranks were reordered by use of the
+<A HREF = "Section_start.html#start_6">-reorder command-line switch</A> or due to
+use of MPI-specific launch options such as a config file.
+</P>
+<P>If you have multiple partitions you should insure that each one writes
+to a different file, e.g. using a <A HREF = "variable.html">world-style variable</A>
+for the filename. The file has a self-explanatory header, followed by
+one-line per processor in this format:
+</P>
+<P>world-ID universe-ID original-ID: I J K: name
+</P>
+<P>The IDs are the processor's rank in this simulation (the world), the
+universe (of multiple simulations), and the original MPI communicator
+used to instantiate LAMMPS, respectively. The world and universe IDs
+will only be different if you are running on more than one partition;
+see the <A HREF = "Section_start.html#start_6">-partition command-line switch</A>.
+The universe and original IDs will only be different if you used the
+<A HREF = "Section_start.html#start_6">-reorder command-line switch</A> to reorder
+the processors differently than their rank in the original
+communicator LAMMPS was instantiated with.
+</P>
+<P>I,J,K are the indices of the processor in the 3d logical grid, each
+from 1 to Nd, where Nd is the number of processors in that dimension
+of the grid.
+</P>
+<P>The <I>name</I> is what is returned by a call to MPI_Get_processor_name()
+and should represent an identifier relevant to the physical processors
+in your machine. Note that depending on the MPI implementation,
+multiple cores can have the same <I>name</I>.
+</P>
+<HR>
+
<P><B>Restrictions:</B>
</P>
<P>This command cannot be used after the simulation box is defined by a
<A HREF = "read_data.html">read_data</A> or <A HREF = "create_box.html">create_box</A> command.
It can be used before a restart file is read to change the 3d
processor grid from what is specified in the restart file.
</P>
-<P><B>Related commands:</B> none
+<P>The <I>grid numa</I> keyword only currently works with the <I>map cart</I>
+option.
+</P>
+<P>The <I>part</I> keyword (for the receiving partition) only works with the
+<I>grid onelevel</I> or <I>twolevel</I> options.
+</P>
+<P><B>Related commands:</B>
+</P>
+<P><A HREF = "partition.html">partition</A>, <A HREF = "Section_start.html#start_6">-reorder command-line
+switch</A>
</P>
<P><B>Default:</B>
</P>
-<P>Px Py Pz = * * *
+<P>The option defaults are Px Py Pz = * * *, grid = onelevel, and map =
+cart.
</P>
</HTML>
diff --git a/doc/processors.txt b/doc/processors.txt
index ae5b89f8c..84a604514 100644
--- a/doc/processors.txt
+++ b/doc/processors.txt
@@ -1,63 +1,322 @@
"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
processors command :h3
[Syntax:]
-processors Px Py Pz :pre
+processors Px Py Pz keyword args ... :pre
-Px,Py,Pz = # of processors in each dimension of a 3d grid :ul
+Px,Py,Pz = # of processors in each dimension of 3d grid overlaying the simulation domain :ulb,l
+zero or more keyword/arg pairs may be appended :l
+keyword = {grid} or {map} or {part} or {file} :l
+ {grid} arg = gstyle params ...
+ gstyle = {onelevel} or {twolevel} or {numa} or {custom}
+ onelevel params = none
+ twolevel params = Nc Cx Cy Cz
+ Nc = number of cores per node
+ Cx,Cy,Cz = # of cores in each dimension of 3d sub-grid assigned to each node
+ numa params = none
+ custom params = infile
+ infile = file containing grid layout
+ {map} arg = {cart} or {cart/reorder} or {xyz} or {xzy} or {yxz} or {yzx} or {zxy} or {zyx}
+ cart = use MPI_Cart() methods to map processors to 3d grid with reorder = 0
+ cart/reorder = use MPI_Cart() methods to map processors to 3d grid with reorder = 1
+ xyz,xzy,yxz,yzx,zxy,zyx = map procesors to 3d grid in IJK ordering
+ {numa} arg = none
+ {part} args = Psend Precv cstyle
+ Psend = partition # (1 to Np) which will send its processor layout
+ Precv = partition # (1 to Np) which will recv the processor layout
+ cstyle = {multiple}
+ {multiple} = Psend grid will be multiple of Precv grid in each dimension
+ {file} arg = outfile
+ outfile = name of file to write 3d grid of processors to :pre
+:ule
[Examples:]
+processors * * 5
processors 2 4 4
-processors * * 5
-processors * 1 10 :pre
+processors * * 8 map xyz
+processors * * * grid numa
+processors * * * grid twolevel 4 * * 1
+processors 4 8 16 grid custom myfile
+processors * * * part 1 2 multiple :pre
[Description:]
Specify how processors are mapped as a 3d logical grid to the global
-simulation box, namely Px by Py by Pz.
+simulation box. This involves 2 steps. First if there are P
+processors it means choosing a factorization P = Px by Py by Pz so
+that there are Px processors in the x dimension, and similarly for the
+y and z dimensions. Second, the P processors are mapped to the
+logical 3d grid. The arguments to this command control each of these
+2 steps.
-Any of the Px, Py, Pz parameters can be specified with an asterisk
-"*", which means LAMMPS will choose the number of processors in that
-dimension. It will do this based on the size and shape of the global
-simulation box so as to minimize the surface-to-volume ratio of each
-processor's sub-domain.
+The Px, Py, Pz parameters affect the factorization. Any of the 3
+parameters can be specified with an asterisk "*", which means LAMMPS
+will choose the number of processors in that dimension of the grid.
+It will do this based on the size and shape of the global simulation
+box so as to minimize the surface-to-volume ratio of each processor's
+sub-domain.
Since LAMMPS does not load-balance by changing the grid of 3d
-processors on-the-fly, this command can be used to override the LAMMPS
-default if it is known to be sub-optimal for a particular problem.
-For example, a problem where the atom's extent will change
-dramatically in a particular dimension over the course of the
-simulation.
+processors on-the-fly, choosing explicit values for Px or Py or Pz can
+be used to override the LAMMPS default if it is known to be
+sub-optimal for a particular problem. E.g. a problem where the extent
+of atoms will change dramatically in a particular dimension over the
+course of the simulation.
The product of Px, Py, Pz must equal P, the total # of processors
LAMMPS is running on. For a "2d simulation"_dimension.html, Pz must
-equal 1. If multiple partitions are being used then P is the number
-of processors in this partition; see "this
+equal 1.
+
+Note that if you run on a prime number of processors P, then a grid
+such as 1 x P x 1 will be required, which may incur extra
+communication costs due to the high surface area of each processor's
+sub-domain.
+
+Also note that if multiple partitions are being used then P is the
+number of processors in this partition; see "this
section"_Section_start.html#start_6 for an explanation of the
--partition command-line switch.
+-partition command-line switch. Also note that you can prefix the
+processors command with the "partition"_partition.html command to
+easily specify different Px,Py,Pz values for different partitions.
+
+You can use the "partition"_partition.html command to specify
+different processor grids for different partitions, e.g.
+
+partition yes 1 processors 4 4 4
+partition yes 2 processors 2 3 2 :pre
+
+:line
+
+The {grid} keyword affects the factorization of P into Px,Py,Pz and it
+can also affect how the P processor IDs are mapped to the 3d grid of
+processors.
+
+The {onelevel} style creates a 3d grid that is compatible with the
+Px,Py,Pz settings, and which minimizes the surface-to-volume ratio of
+each processor's sub-domain, as described above. The mapping of
+processors to the grid is determined by the {map} keyword setting.
+
+The {twolevel} style can be used on machines with multicore nodes to
+minimize off-node communication. It insures that contiguous
+sub-sections of the 3d grid are assigned to all the cores of a node.
+For example if {Nc} is 4, then 2x2x1 or 2x1x2 or 1x2x2 sub-sections of
+the 3d grid will correspond to the cores of each node. This affects
+both the factorization and mapping steps.
+
+The {Cx}, {Cy}, {Cz} settings are similar to the {Px}, {Py}, {Pz}
+settings, only their product should equal {Nc}. Any of the 3
+parameters can be specified with an asterisk "*", which means LAMMPS
+will choose the number of cores in that dimension of the node's
+sub-grid. As with Px,Py,Pz, it will do this based on the size and
+shape of the global simulation box so as to minimize the
+surface-to-volume ratio of each processor's sub-domain.
+
+IMPORTANT NOTE: For the {twolevel} style to work correctly, it
+assumes the MPI ranks of processors LAMMPS is running on are ordered
+by core and then by node. E.g. if you are running on 2 quad-core
+nodes, for a total of 8 processors, then it assumes processors 0,1,2,3
+are on node 1, and processors 4,5,6,7 are on node 2. This is the
+default rank ordering for most MPI implementations, but some MPIs
+provide options for this ordering, e.g. via environment variable
+settings.
+
+The {numa} style operates similar to the {twolevel} keyword except
+that it auto-detects the core count within the nodes. Currently, it
+does this in only 2 levels, but it may be extended in the future to
+account for socket topology and other non-uniform memory access (NUMA)
+costs. It also uses a different algorithm (iterative) than the
+{twolevel} keyword for doing the two-level factorization of the
+simulation box into a 3d processor grid to minimize off-node
+communication, and it does its own mapping of nodes and cores to the
+logical 3d grid. Thus it may produce a different or improved layout
+of the processors.
+
+The {numa} style will give an error if (a) there are less than 4 cores
+per node, or (b) the number of MPI processes is not divisible by the
+number of cores used per node, or (c) only 1 node is allocated, or (d)
+any of the Px or Py of Pz values is greater than 1.
+
+IMPORTANT NOTE: For the {numa} style to work correctly, it assumes
+the MPI ranks of processors LAMMPS is running on are ordered by core
+and then by node. See the same note for the {twolevel} keyword.
+
+The {custom} style uses the file {infile} to define both the 3d
+factorization and the mapping of processors to the grid.
+
+The file should have the following format. Any number of initial
+blank or comment lines (starting with a "#" character) can be present.
+The first non-blank, non-comment line should have
+3 values:
+
+Px Py Py :pre
+
+These must be compatible with the total number of processors
+and the Px, Py, Pz settings of the processors commmand.
+
+This line should be immediately followed by
+P = Px*Py*Pz lines of the form:
+
+ID I J K :pre
+
+where ID is a processor ID (from 0 to P-1) and I,J,K are the
+processors location in the 3d grid. I must be a number from 1 to Px
+(inclusive) and similarly for J and K. The P lines can be listed in
+any order, but no processor ID should appear more than once.
+
+:line
+
+The {map} keyword affects how the P processor IDs (from 0 to P-1) are
+mapped to the 3d grid of processors. It is only used by the
+{onelevel} and {twolevel} grid settings.
+
+The {cart} style uses the family of MPI Cartesian functions to perform
+the mapping, namely MPI_Cart_create(), MPI_Cart_get(),
+MPI_Cart_shift(), and MPI_Cart_rank(). It invokes the
+MPI_Cart_create() function with its reorder flag = 0, so that MPI is
+not free to reorder the processors.
-Note that if you run on a large, prime number of processors P, then a
-grid such as 1 x P x 1 will be required, which may incur extra
-communication costs.
+The {cart/reorder} style does the same thing as the {cart} style
+except it sets the reorder flag to 1, so that MPI can reorder
+processors if it desires.
+
+The {xyz}, {xzy}, {yxz}, {yzx}, {zxy}, and {zyx} styles are all
+similar. If the style is IJK, then it maps the P processors to the
+grid so that the processor ID in the I direction varies fastest, the
+processor ID in the J direction varies next fastest, and the processor
+ID in the K direction varies slowest. For example, if you select
+style {xyz} and you have a 2x2x2 grid of 8 processors, the assignments
+of the 8 octants of the simulation domain will be:
+
+proc 0 = lo x, lo y, lo z octant
+proc 1 = hi x, lo y, lo z octant
+proc 2 = lo x, hi y, lo z octant
+proc 3 = hi x, hi y, lo z octant
+proc 4 = lo x, lo y, hi z octant
+proc 5 = hi x, lo y, hi z octant
+proc 6 = lo x, hi y, hi z octant
+proc 7 = hi x, hi y, hi z octant :pre
+
+Note that, in principle, an MPI implementation on a particular machine
+should be aware of both the machine's network topology and the
+specific subset of processors and nodes that were assigned to your
+simulation. Thus its MPI_Cart calls can optimize the assignment of
+MPI processes to the 3d grid to minimize communication costs. In
+practice, however, few if any MPI implementations actually do this.
+So it is likely that the {cart} and {cart/reorder} styles simply give
+the same result as one of the IJK styles.
+
+Also note, that for the {twolevel} grid style, the {map} setting is
+used to first map the nodes to the 3d grid, then again to the cores
+within each node. For the latter step, the {cart} and {cart/reorder}
+styles are not supported, so an {xyz} style is used in their place.
+
+:line
+
+The {part} keyword affects the factorization of P into Px,Py,Pz.
+
+It can be useful when running in multi-partition mode, e.g. with the
+"run_style verlet/split"_run_style.html command. It specifies a
+dependency bewteen a sending partition {Psend} and a receiving
+partition {Precv} which is enforced when each is setting up their own
+mapping of their processors to the simulation box. Each of {Psend}
+and {Precv} must be integers from 1 to Np, where Np is the number of
+partitions you have defined via the "-partition command-line
+switch"_Section_start.html#start_6.
+
+A "dependency" means that the sending partition will create its 3d
+logical grid as Px by Py by Pz and after it has done this, it will
+send the Px,Py,Pz values to the receiving partition. The receiving
+partition will wait to receive these values before creating its own 3d
+logical grid and will use the sender's Px,Py,Pz values as a
+constraint. The nature of the constraint is determined by the
+{cstyle} argument.
+
+For a {cstyle} of {multiple}, each dimension of the sender's processor
+grid is required to be an integer multiple of the corresponding
+dimension in the receiver's processor grid. This is a requirement of
+the "run_style verlet/split"_run_style.html command.
+
+For example, assume the sending partition creates a 4x6x10 grid = 240
+processor grid. If the receiving partition is running on 80
+processors, it could create a 4x2x10 grid, but it will not create a
+2x4x10 grid, since in the y-dimension, 6 is not an integer multiple of
+4.
+
+IMPORTANT NOTE: If you use the "partition"_partition.html command to
+invoke different "processsors" commands on different partitions, and
+you also use the {part} keyword, then you must insure that both the
+sending and receiving partitions invoke the "processors" command that
+connects the 2 partitions via the {part} keyword. LAMMPS cannot
+easily check for this, but your simulation will likely hang in its
+setup phase if this error has been made.
+
+:line
+
+The {file} keyword writes the mapping of the factorization of P
+processors and their mapping to the 3d grid to the specified file
+{outfile}. This is useful to check that you assigned physical
+processors in the manner you desired, which can be tricky to figure
+out, especially when running on multiple partitions or on, a multicore
+machine or when the processor ranks were reordered by use of the
+"-reorder command-line switch"_Section_start.html#start_6 or due to
+use of MPI-specific launch options such as a config file.
+
+If you have multiple partitions you should insure that each one writes
+to a different file, e.g. using a "world-style variable"_variable.html
+for the filename. The file has a self-explanatory header, followed by
+one-line per processor in this format:
+
+world-ID universe-ID original-ID: I J K: name
+
+The IDs are the processor's rank in this simulation (the world), the
+universe (of multiple simulations), and the original MPI communicator
+used to instantiate LAMMPS, respectively. The world and universe IDs
+will only be different if you are running on more than one partition;
+see the "-partition command-line switch"_Section_start.html#start_6.
+The universe and original IDs will only be different if you used the
+"-reorder command-line switch"_Section_start.html#start_6 to reorder
+the processors differently than their rank in the original
+communicator LAMMPS was instantiated with.
+
+I,J,K are the indices of the processor in the 3d logical grid, each
+from 1 to Nd, where Nd is the number of processors in that dimension
+of the grid.
+
+The {name} is what is returned by a call to MPI_Get_processor_name()
+and should represent an identifier relevant to the physical processors
+in your machine. Note that depending on the MPI implementation,
+multiple cores can have the same {name}.
+
+:line
[Restrictions:]
This command cannot be used after the simulation box is defined by a
"read_data"_read_data.html or "create_box"_create_box.html command.
It can be used before a restart file is read to change the 3d
processor grid from what is specified in the restart file.
-[Related commands:] none
+The {grid numa} keyword only currently works with the {map cart}
+option.
+
+The {part} keyword (for the receiving partition) only works with the
+{grid onelevel} or {twolevel} options.
+
+[Related commands:]
+
+"partition"_partition.html, "-reorder command-line
+switch"_Section_start.html#start_6
[Default:]
-Px Py Pz = * * *
+The option defaults are Px Py Pz = * * *, grid = onelevel, and map =
+cart.
diff --git a/doc/read_data.html b/doc/read_data.html
index fcf68f468..bf57ec18e 100644
--- a/doc/read_data.html
+++ b/doc/read_data.html
@@ -1,811 +1,811 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>read_data command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>read_data file
</PRE>
<UL><LI>file = name of data file to read in
</UL>
<P><B>Examples:</B>
</P>
<PRE>read_data data.lj
read_data ../run7/data.polymer.gz
</PRE>
<P><B>Description:</B>
</P>
<P>Read in a data file containing information LAMMPS needs to run a
simulation. The file can be ASCII text or a gzipped text file
(detected by a .gz suffix). This is one of 3 ways to specify initial
atom coordinates; see the <A HREF = "read_restart.html">read_restart</A> and
<A HREF = "create_atoms.html">create_atoms</A> commands for alternative methods.
</P>
<P>The structure of the data file is important, though many settings and
sections are optional or can come in any order. See the examples
directory for sample data files for different problems.
</P>
<P>A data file has a header and a body. The header appears first. The
first line of the header is always skipped; it typically contains a
description of the file. Then lines are read one at a time. Lines
can have a trailing comment starting with '#' that is ignored. If the
line is blank (only whitespace after comment is deleted), it is
skipped. If the line contains a header keyword, the corresponding
value(s) is read from the line. If it doesn't contain a header
keyword, the line begins the body of the file.
</P>
<P>The body of the file contains zero or more sections. The first line
of a section has only a keyword. The next line is skipped. The
remaining lines of the section contain values. The number of lines
depends on the section keyword as described below. Zero or more blank
lines can be used between sections. Sections can appear in any order,
with a few exceptions as noted below.
</P>
<P>The formatting of individual lines in the data file (indentation,
spacing between words and numbers) is not important except that header
and section keywords (e.g. atoms, xlo xhi, Masses, Bond Coeffs) must
be capitalized as shown and can't have extra white space between their
words - e.g. two spaces or a tab between "Bond" and "Coeffs" is not
valid.
</P>
<HR>
<P>These are the recognized header keywords. Header lines can come in
any order. The value(s) are read from the beginning of the line.
Thus the keyword <I>atoms</I> should be in a line like "1000 atoms"; the
keyword <I>ylo yhi</I> should be in a line like "-10.0 10.0 ylo yhi"; the
keyword <I>xy xz yz</I> should be in a line like "0.0 5.0 6.0 xy xz yz".
All these settings have a default value of 0, except the lo/hi box
size defaults are -0.5 and 0.5. A line need only appear if the value
is different than the default.
</P>
<UL><LI><I>atoms</I> = # of atoms in system
<LI><I>bonds</I> = # of bonds in system
<LI><I>angles</I> = # of angles in system
<LI><I>dihedrals</I> = # of dihedrals in system
<LI><I>impropers</I> = # of impropers in system
<LI><I>atom types</I> = # of atom types in system
<LI><I>bond types</I> = # of bond types in system
<LI><I>angle types</I> = # of angle types in system
<LI><I>dihedral types</I> = # of dihedral types in system
<LI><I>improper types</I> = # of improper types in system
<LI><I>extra bond per atom</I> = leave space for this many new bonds per atom
<LI><I>ellipsoids</I> = # of ellipsoids in system
<LI><I>lines</I> = # of line segments in system
<LI><I>triangles</I> = # of triangles in system
<LI><I>xlo xhi</I> = simulation box boundaries in x dimension
<LI><I>ylo yhi</I> = simulation box boundaries in y dimension
<LI><I>zlo zhi</I> = simulation box boundaries in z dimension
<LI><I>xy xz yz</I> = simulation box tilt factors for triclinic system
</UL>
<P>The initial simulation box size is determined by the lo/hi settings.
In any dimension, the system may be periodic or non-periodic; see the
<A HREF = "boundary.html">boundary</A> command.
</P>
<P>If the <I>xy xz yz</I> line does not appear, LAMMPS will set up an
axis-aligned (orthogonal) simulation box. If the line does appear,
LAMMPS creates a non-orthogonal simulation domain shaped as a
parallelepiped with triclinic symmetry. The parallelepiped has its
"origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting
from the origin given by A = (xhi-xlo,0,0); B = (xy,yhi-ylo,0); C =
(xz,yz,zhi-zlo). <I>Xy,xz,yz</I> can be 0.0 or positive or negative values
and are called "tilt factors" because they are the amount of
displacement applied to faces of an originally orthogonal box to
transform it into the parallelepiped.
</P>
<P>The tilt factors (xy,xz,yz) can not skew the box more than half the
distance of the corresponding parallel box length. For example, if
xlo = 2 and xhi = 12, then the x box length is 10 and the xy tilt
factor must be between -5 and 5. Similarly, both xz and yz must be
between -(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a
limitation, since if the maximum tilt factor is 5 (as in this
example), then configurations with tilt = ..., -15, -5, 5, 15, 25,
... are all geometrically equivalent.
</P>
-<P>See <A HREF = "Section_howto.html#howto_12">this section</A> of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+<P>See <A HREF = "Section_howto.html#howto_12">Section_howto 12</A> of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
</P>
<P>When a triclinic system is used, the simulation domain must be
periodic in any dimensions with a non-zero tilt factor, as defined by
the <A HREF = "boundary.html">boundary</A> command. I.e. if the xy tilt factor is
non-zero, then both the x and y dimensions must be periodic.
Similarly, x and z must be periodic if xz is non-zero and y and z must
be periodic if yz is non-zero. Also note that if your simulation will
tilt the box, e.g. via the <A HREF = "fix_deform.html">fix deform</A> command, the
simulation box must be defined as triclinic, even if the tilt factors
are initially 0.0.
</P>
<P>For 2d simulations, the <I>zlo zhi</I> values should be set to bound the z
coords for atoms that appear in the file; the default of -0.5 0.5 is
valid if all z coords are 0.0. For 2d triclinic simulations, the xz
and yz tilt factors must be 0.0.
</P>
<P>If the system is periodic (in a dimension), then atom coordinates can
be outside the bounds (in that dimension); they will be remapped (in a
periodic sense) back inside the box.
</P>
<P>IMPORTANT NOTE: If the system is non-periodic (in a dimension), then
all atoms in the data file must have coordinates (in that dimension)
that are "greater than or equal to" the lo value and "less than or
equal to" the hi value. If the non-periodic dimension is of style
"fixed" (see the <A HREF = "boundary.html">boundary</A> command), then the atom
coords must be strictly "less than" the hi value, due to the way
LAMMPS assign atoms to processors. Note that you should not make the
lo/hi values radically smaller/larger than the extent of the atoms.
For example, if your atoms extend from 0 to 50, you should not specify
the box bounds as -10000 and 10000. This is because LAMMPS uses the
specified box size to layout the 3d grid of processors. A huge
(mostly empty) box will be sub-optimal for performance when using
"fixed" boundary conditions (see the <A HREF = "boundary.html">boundary</A>
command). When using "shrink-wrap" boundary conditions (see the
<A HREF = "boundary.html">boundary</A> command), a huge (mostly empty) box may cause
a parallel simulation to lose atoms the first time that LAMMPS
shrink-wraps the box around the atoms.
</P>
<P>The "extra bond per atom" setting should be used if new bonds will be
added to the system when a simulation runs, e.g. by using the <A HREF = "fix_bond_create.html">fix
bond/create</A> command. This will pre-allocate
space in LAMMPS data structures for storing the new bonds.
</P>
<P>The "ellipsoids" and "lines" and "triangles" settings are only used
with <A HREF = "atom_style.html">atom_style ellipsoid or line or tri</A> and
specifies how many of the atoms are finite-size ellipsoids or lines or
triangles; the remainder are point particles. See the discussion of
ellipsoidflag and the <I>Ellipsoids</I> section below. See the discussion
of lineflag and the <I>Lines</I> section below. See the discussion of
triangleflag and the <I>Triangles</I> section below.
</P>
<HR>
<P>These are the section keywords for the body of the file.
</P>
<UL><LI><I>Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles</I> = atom-property sections
<LI><I>Bonds, Angles, Dihedrals, Impropers</I> = molecular topology sections
<LI><I>Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, Improper Coeffs</I> = force field sections
<LI><I>BondBond Coeffs, BondAngle Coeffs, MiddleBondTorsion Coeffs, EndBondTorsion Coeffs, AngleTorsion Coeffs, AngleAngleTorsion Coeffs, BondBond13 Coeffs, AngleAngle Coeffs</I> = class 2 force field sections
</UL>
<P>Each section is listed below in alphabetic order. The format of each
section is described including the number of lines it must contain and
rules (if any) for where it can appear in the data file.
</P>
<P>Any individual line in the various sections can have a trailing
comment starting with "#" for annotation purposes. E.g. in the
Atoms section:
</P>
<PRE>10 1 17 -1.0 10.0 5.0 6.0 # salt ion
</PRE>
<HR>
<P><I>Angle Coeffs</I> section:
</P>
<UL><LI>one line per angle type
<LI>line syntax: ID coeffs
<PRE> ID = angle type (1-N)
coeffs = list of coeffs
</PRE>
<LI>example:
<PRE> 6 70 108.5 0 0
</PRE>
</UL>
<P>The number and meaning of the coefficients are specific to the defined
angle style. See the <A HREF = "angle_style.html">angle_style</A> and
<A HREF = "angle_coeff.html">angle_coeff</A> commands for details. Coefficients can
also be set via the <A HREF = "angle_coeff.html">angle_coeff</A> command in the
input script.
</P>
<HR>
<P><I>AngleAngle Coeffs</I> section:
</P>
<UL><LI>one line per improper type
<LI>line syntax: ID coeffs
<PRE> ID = improper type (1-N)
coeffs = list of coeffs (see <A HREF = "improper_coeff.html">improper_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>AngleAngleTorsion Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs (see <A HREF = "dihedral_coeff.html">dihedral_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>Angles</I> section:
</P>
<UL><LI>one line per angle
<LI>line syntax: ID type atom1 atom2 atom3
<PRE> ID = number of angle (1-Nangles)
type = angle type (1-Nangletype)
atom1,atom2,atom3 = IDs of 1st,2nd,3rd atoms in angle
</PRE>
example:
<BR>
<PRE> 2 2 17 29 430
</PRE>
</UL>
<P>The 3 atoms are ordered linearly within the angle. Thus the central
atom (around which the angle is computed) is the atom2 in the list.
E.g. H,O,H for a water molecule. The <I>Angles</I> section must appear
after the <I>Atoms</I> section. All values in this section must be
integers (1, not 1.0).
</P>
<HR>
<P><I>AngleTorsion Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs (see <A HREF = "dihedral_coeff.html">dihedral_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>Atoms</I> section:
</P>
<UL><LI>one line per atom
<LI>line syntax: depends on atom style
</UL>
<P>An <I>Atoms</I> section must appear in the data file if natoms > 0 in the
header section. The atoms can be listed in any order. These are the
line formats for each <A HREF = "atom_style.html">atom style</A> in LAMMPS. As
discussed below, each line can optionally have 3 flags (nx,ny,nz)
appended to it, which indicate which image of a periodic simulation
box the atom is in. These may be important to include for some kinds
of analysis.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >angle</TD><TD > atom-ID molecule-ID atom-type x y z</TD></TR>
<TR><TD >atomic</TD><TD > atom-ID atom-type x y z</TD></TR>
<TR><TD >bond</TD><TD > atom-ID molecule-ID atom-type x y z</TD></TR>
<TR><TD >charge</TD><TD > atom-ID atom-type q x y z</TD></TR>
<TR><TD >dipole</TD><TD > atom-ID atom-type q x y z mux muy muz</TD></TR>
<TR><TD >electron</TD><TD > atom-ID atom-type q spin eradius x y z</TD></TR>
<TR><TD >ellipsoid</TD><TD > atom-ID atom-type ellipsoidflag density x y z</TD></TR>
<TR><TD >full</TD><TD > atom-ID molecule-ID atom-type q x y z</TD></TR>
<TR><TD >line</TD><TD > atom-ID molecule-ID atom-type lineflag density x y z</TD></TR>
<TR><TD >meso</TD><TD > atom-ID atom-type rho e cv x y z</TD></TR>
<TR><TD >molecular</TD><TD > atom-ID molecule-ID atom-type x y z</TD></TR>
<TR><TD >peri</TD><TD > atom-ID atom-type volume density x y z</TD></TR>
<TR><TD >sphere</TD><TD > atom-ID atom-type diameter density x y z</TD></TR>
<TR><TD >tri</TD><TD > atom-ID molecule-ID atom-type triangleflag density x y z</TD></TR>
<TR><TD >wavepacket</TD><TD > atom-ID atom-type charge spin eradius etag cs_re cs_im x y z</TD></TR>
<TR><TD >hybrid</TD><TD > atom-ID atom-type x y z sub-style1 sub-style2 ...
</TD></TR></TABLE></DIV>
<P>The keywords have these meanings:
</P>
<UL><LI>atom-ID = integer ID of atom
<LI>molecule-ID = integer ID of molecule the atom belongs to
<LI>atom-type = type of atom (1-Ntype)
<LI>q = charge on atom (charge units)
<LI>diameter = diameter of spherical atom (distance units)
<LI>ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles
<LI>lineflag = 1 for line segment particles, 0 for point particles
<LI>triangleflag = 1 for triangular particles, 0 for point particles
<LI>density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
<LI>volume = volume of atom (distance^3 units)
<LI>x,y,z = coordinates of atom
<LI>mux,muy,muz = components of dipole moment of atom (dipole units)
<LI>rho = density (need units) for SPH particles
<LI>e = energy (need units) for SPH particles
<LI>cv = heat capacity (need units) for SPH particles
<LI>spin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP)
<LI>eradius = electron radius (or fixed-core radius)
<LI>etag = integer ID of electron that each wavepacket belongs to
<LI>cs_re,cs_im = real/imaginary parts of wavepacket coefficients
</UL>
<P>The units for these quantities depend on the unit style; see the
<A HREF = "units.html">units</A> command for details.
</P>
<P>For 2d simulations specify z as 0.0, or a value within the <I>zlo zhi</I>
setting in the data file header.
</P>
<P>The atom-ID is used to identify the atom throughout the simulation and
in dump files. Normally, it is a unique value from 1 to Natoms for
each atom. Unique values larger than Natoms can be used, but they
will cause extra memory to be allocated on each processor, if an atom
map array is used (see the <A HREF = "atom_modify.html">atom_modify</A> command).
If an atom map array is not used (e.g. an atomic system with no
bonds), and velocities are not assigned in the data file, and you
don't care if unique atom IDs appear in dump files, then the atom-IDs
can all be set to 0.
</P>
<P>The molecule ID is a 2nd identifier attached to an atom. Normally, it
is a number from 1 to N, identifying which molecule the atom belongs
to. It can be 0 if it is an unbonded atom or if you don't care to
keep track of molecule assignments.
</P>
<P>The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
</P>
<P>The ellipsoidflag, lineflag, and triangleflag determine whether the
particle is a finite-size ellipsoid or line or triangle of finite
size, or a point particle. Additional attributes must be defined for
each ellipsoid in the <I>Ellipsoids</I> section. Additional attributes
must be defined for each line in the <I>Lines</I> section. Additional
attributes must be defined for each triangle in the <I>Triangles</I>
section.
</P>
<P>Some pair styles and fixes and computes that operate on finite-size
particles allow for a mixture of finite-size and point particles. See
the doc pages of individual commands for details.
</P>
<P>The density is used in conjunction with the particle volume for
finite-size particles to set the mass of the particle as mass =
density * volume. In this context, volume can be a 3d quantity (for
spheres or ellipsoids), a 2d quantity (for triangles), or a 1d
quantity (for line segments). If the volume is 0.0, meaning a point
particle, then the density value is used as the mass.
</P>
<P>For atom_style hybrid, following the 5 initial values (ID,type,x,y,z),
specific values for each sub-style must be listed. The order of the
sub-styles is the same as they were listed in the
<A HREF = "atom_style.html">atom_style</A> command. The sub-style specific values
are those that are not the 5 standard ones (ID,type,x,y,z). For
example, for the "charge" sub-style, a "q" value would appear. For
the "full" sub-style, a "molecule-ID" and "q" would appear. These are
listed in the same order they appear as listed above. Thus if
</P>
<PRE>atom_style hybrid charge sphere
</PRE>
<P>were used in the input script, each atom line would have these fields:
</P>
<PRE>atom-ID atom-type x y z q diameter density
</PRE>
<P>Atom lines (all lines or none of them) can optionally list 3 trailing
integer values: nx,ny,nz. For periodic dimensions, they specify which
image of the simulation box the atom is considered to be in. An image
of 0 means it is inside the box as defined. A value of 2 means add 2
box lengths to get the true value. A value of -1 means subtract 1 box
length to get the true value. LAMMPS updates these flags as atoms
cross periodic boundaries during the simulation. The flags can be
output with atom snapshots via the <A HREF = "dump.html">dump</A> command.
</P>
<P>If nx,ny,nz values are not set in the data file, LAMMPS initializes
them to 0. If image information is needed for later analysis and they
are not all initially 0, it's important to set them correctly in the
data file. Also, if you plan to use the <A HREF = "replicate.html">replicate</A>
command to generate a larger system, these flags must be listed
correctly for bonded atoms when the bond crosses a periodic boundary.
I.e. the values of the image flags should be different by 1 (in the
appropriate dimension) for the two atoms in such a bond.
</P>
<P>Atom velocities and other atom quantities not defined above are set to
0.0 when the <I>Atoms</I> section is read. Velocities can be set later by
a <I>Velocities</I> section in the data file or by a
<A HREF = "velocity.html">velocity</A> or <A HREF = "set.html">set</A> command in the input
script.
</P>
<HR>
<P><I>Bond Coeffs</I> section:
</P>
<UL><LI>one line per bond type
<LI>line syntax: ID coeffs
<PRE> ID = bond type (1-N)
coeffs = list of coeffs
</PRE>
<LI>example:
<PRE> 4 250 1.49
</PRE>
</UL>
<P>The number and meaning of the coefficients are specific to the defined
bond style. See the <A HREF = "bond_style.html">bond_style</A> and
<A HREF = "bond_coeff.html">bond_coeff</A> commands for details. Coefficients can
also be set via the <A HREF = "bond_coeff.html">bond_coeff</A> command in the input
script.
</P>
<HR>
<P><I>BondAngle Coeffs</I> section:
</P>
<UL><LI>one line per angle type
<LI>line syntax: ID coeffs
<PRE> ID = angle type (1-N)
coeffs = list of coeffs (see class 2 section of <A HREF = "angle_coeff.html">angle_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>BondBond Coeffs</I> section:
</P>
<UL><LI>one line per angle type
<LI>line syntax: ID coeffs
<PRE> ID = angle type (1-N)
coeffs = list of coeffs (see class 2 section of <A HREF = "angle_coeff.html">angle_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>BondBond13 Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of <A HREF = "dihedral_coeff.html">dihedral_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>Bonds</I> section:
</P>
<UL><LI>one line per bond
<LI>line syntax: ID type atom1 atom2
<PRE> ID = bond number (1-Nbonds)
type = bond type (1-Nbondtype)
atom1,atom2 = IDs of 1st,2nd atoms in bond
</PRE>
<LI>example:
<PRE> 12 3 17 29
</PRE>
</UL>
<P>The <I>Bonds</I> section must appear after the <I>Atoms</I> section. All values
in this section must be integers (1, not 1.0).
</P>
<HR>
<P><I>Dihedral Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs
</PRE>
<LI>example:
<PRE> 3 0.6 1 0 1
</PRE>
</UL>
<P>The number and meaning of the coefficients are specific to the defined
dihedral style. See the <A HREF = "dihedral_style.html">dihedral_style</A> and
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> commands for details.
Coefficients can also be set via the
<A HREF = "dihedral_coeff.html">dihedral_coeff</A> command in the input script.
</P>
<HR>
<P><I>Dihedrals</I> section:
</P>
<UL><LI>one line per dihedral
<LI>line syntax: ID type atom1 atom2 atom3 atom4
<PRE> ID = number of dihedral (1-Ndihedrals)
type = dihedral type (1-Ndihedraltype)
atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atoms in dihedral
</PRE>
<LI>example:
<PRE> 12 4 17 29 30 21
</PRE>
</UL>
<P>The 4 atoms are ordered linearly within the dihedral. The <I>Dihedrals</I>
section must appear after the <I>Atoms</I> section. All values in this
section must be integers (1, not 1.0).
</P>
<HR>
<P><I>Ellipsoids</I> section:
</P>
<UL><LI>one line per ellipsoid
<LI>line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk
<LI> atom-ID = ID of atom which is an ellipsoid
shapex,shapey,shapez = 3 diameters of ellipsoid (distance units)
quatw,quati,quatj,quatk = quaternion components for orientation of atom
example:
<PRE> 12 1 2 1 1 0 0 0
</PRE>
</UL>
<P>The <I>Ellipsoids</I> section must appear if <A HREF = "atom_style.html">atom_style
ellipsoid</A> is used and any atoms are listed in the
<I>Atoms</I> section with an ellipsoidflag = 1. The number of ellipsoids
should be specified in the header section via the "ellipsoids"
keyword.
</P>
<P>The 3 shape values specify the 3 diameters or aspect ratios of a
finite-size ellipsoidal particle, when it is oriented along the 3
coordinate axes. They must all be non-zero values.
</P>
<P>The values <I>quatw</I>, <I>quati</I>, <I>quatj</I>, and <I>quatk</I> set the orientation
of the atom as a quaternion (4-vector). Note that the shape
attributes specify the aspect ratios of an ellipsoidal particle, which
is oriented by default with its x-axis along the simulation box's
x-axis, and similarly for y and z. If this body is rotated (via the
right-hand rule) by an angle theta around a unit vector (a,b,c), then
the quaternion that represents its new orientation is given by
(cos(theta/2), a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). These
4 components are quatw, quati, quatj, and quatk as specified above.
LAMMPS normalizes each atom's quaternion in case (a,b,c) is not
specified as a unit vector.
</P>
<P>The <I>Ellipsoids</I> section must appear after the <I>Atoms</I> section.
</P>
<HR>
<P><I>EndBondTorsion Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of <A HREF = "dihedral_coeff.html">dihedral_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>Improper Coeffs</I> section:
</P>
<UL><LI>one line per improper type
<LI>line syntax: ID coeffs
<PRE> ID = improper type (1-N)
coeffs = list of coeffs
</PRE>
<LI>example:
<PRE> 2 20 0.0548311
</PRE>
</UL>
<P>The number and meaning of the coefficients are specific to the defined
improper style. See the <A HREF = "improper_style.html">improper_style</A> and
<A HREF = "improper_coeff.html">improper_coeff</A> commands for details.
Coefficients can also be set via the
<A HREF = "improper_coeff.html">improper_coeff</A> command in the input script.
</P>
<HR>
<P><I>Impropers</I> section:
</P>
<UL><LI>one line per improper
<LI>line syntax: ID type atom1 atom2 atom3 atom4
<PRE> ID = number of improper (1-Nimpropers)
type = improper type (1-Nimpropertype)
atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atoms in improper
</PRE>
<LI>example:
<PRE> 12 3 17 29 13 100
</PRE>
</UL>
<P>The ordering of the 4 atoms determines the definition of the improper
angle used in the formula for each <A HREF = "improper_style.html">improper
style</A>. See the doc pages for individual styles
for details.
</P>
<P>The <I>Impropers</I> section must appear after the <I>Atoms</I> section. All
values in this section must be integers (1, not 1.0).
</P>
<HR>
<P><I>Lines</I> section:
</P>
<UL><LI>one line per line segment
<LI>line syntax: atom-ID x1 y1 x2 y2
<LI> atom-ID = ID of atom which is a line segment
x1,y1 = 1st end point
x2,y2 = 2nd end point
example:
<PRE> 12 1.0 0.0 2.0 0.0
</PRE>
</UL>
<P>The <I>Lines</I> section must appear if <A HREF = "atom_style.html">atom_style line</A>
is used and any atoms are listed in the <I>Atoms</I> section with a
lineflag = 1. The number of lines should be specified in the header
section via the "lines" keyword.
</P>
<P>The 2 end points are the end points of the line segment. The ordering
of the 2 points should be such that using a right-hand rule to cross
the line segment with a unit vector in the +z direction, gives an
"outward" normal vector perpendicular to the line segment.
I.e. normal = (c2-c1) x (0,0,1). This orientation may be important
for defining some interactions.
</P>
<P>The <I>Lines</I> section must appear after the <I>Atoms</I> section.
</P>
<HR>
<P><I>Masses</I> section:
</P>
<UL><LI>one line per atom type
<LI>line syntax: ID mass
<PRE> ID = atom type (1-N)
mass = mass value
</PRE>
<LI>example:
<PRE> 3 1.01
</PRE>
</UL>
<P>This defines the mass of each atom type. This can also be set via the
<A HREF = "mass.html">mass</A> command in the input script. This section cannot be
used for atom styles that define a mass for individual atoms -
e.g. <A HREF = "atom_style.html">atom_style sphere</A>.
</P>
<HR>
<P><I>MiddleBondTorsion Coeffs</I> section:
</P>
<UL><LI>one line per dihedral type
<LI>line syntax: ID coeffs
<PRE> ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of <A HREF = "dihedral_coeff.html">dihedral_coeff</A>)
</PRE>
</UL>
<HR>
<P><I>Pair Coeffs</I> section:
</P>
<UL><LI>one line per atom type
<LI>line syntax: ID coeffs
<PRE> ID = atom type (1-N)
coeffs = list of coeffs
</PRE>
<LI>example:
<PRE> 3 0.022 2.35197 0.022 2.35197
</PRE>
</UL>
<P>The number and meaning of the coefficients are specific to the defined
pair style. See the <A HREF = "pair_style.html">pair_style</A> and
<A HREF = "pair_coeff.html">pair_coeff</A> commands for details. Coefficients can
also be set via the <A HREF = "pair_coeff.html">pair_coeff</A> command in the input
script.
</P>
<HR>
<P><I>Triangles</I> section:
</P>
<UL><LI>one line per triangle
<LI>line syntax: atom-ID x1 y1 x2 y2
<LI> atom-ID = ID of atom which is a line segment
x1,y1,z1 = 1st corner point
x2,y2,z2 = 2nd corner point
x3,y3,z3 = 3rd corner point
example:
<PRE> 12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0
</PRE>
</UL>
<P>The <I>Triangles</I> section must appear if <A HREF = "atom_style.html">atom_style
tri</A> is used and any atoms are listed in the <I>Atoms</I>
section with a triangleflag = 1. The number of lines should be
specified in the header section via the "triangles" keyword.
</P>
<P>The 3 corner points are the corner points of the triangle. The
ordering of the 3 points should be such that using a right-hand rule
to go from point1 to point2 to point3 gives an "outward" normal vector
to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This
orientation may be important for defining some interactions.
</P>
<P>The <I>Triangles</I> section must appear after the <I>Atoms</I> section.
</P>
<HR>
<P><I>Velocities</I> section:
</P>
<UL><LI>one line per atom
<LI>line syntax: depends on atom style
</UL>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR><TD >all styles except those listed</TD><TD > atom-ID vx vy vz</TD></TR>
<TR><TD >dipole</TD><TD > atom-ID vx vy vz wx wy wz</TD></TR>
<TR><TD >electron</TD><TD > atom-ID vx vy vz evel</TD></TR>
<TR><TD >ellipsoid</TD><TD > atom-ID vx vy vz lx ly lz</TD></TR>
<TR><TD >sphere</TD><TD > atom-ID vx vy vz wx wy wz
</TD></TR></TABLE></DIV>
<P>where the keywords have these meanings:
</P>
<P>vx,vy,vz = translational velocity of atom
lx,ly,lz = angular momentum of aspherical atom
wx,wy,wz = angular velocity of spherical atom
evel = electron radial velocity (0 for fixed-core):ul
</P>
<P>The velocity lines can appear in any order. This section can only be
used after an <I>Atoms</I> section. This is because the <I>Atoms</I> section
must have assigned a unique atom ID to each atom so that velocities
can be assigned to them.
</P>
<P>Vx, vy, vz, and evel are in <A HREF = "units.html">units</A> of velocity. Lx, ly,
lz are in units of angular momentum (distance-velocity-mass). Wx, Wy,
Wz are in units of angular velocity (radians/time).
</P>
<P>Translational velocities can also be set by the
<A HREF = "velocity.html">velocity</A> command in the input script.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>To read gzipped data files, you must compile LAMMPS with the
-DLAMMPS_GZIP option - see the <A HREF = "Section_start.html#start_2">Making
LAMMPS</A> section of the documentation.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "read_restart.html">read_restart</A>, <A HREF = "create_atoms.html">create_atoms</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/read_data.txt b/doc/read_data.txt
index b9fcccd0f..fd28395df 100644
--- a/doc/read_data.txt
+++ b/doc/read_data.txt
@@ -1,719 +1,719 @@
"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
read_data command :h3
[Syntax:]
read_data file :pre
file = name of data file to read in :ul
[Examples:]
read_data data.lj
read_data ../run7/data.polymer.gz :pre
[Description:]
Read in a data file containing information LAMMPS needs to run a
simulation. The file can be ASCII text or a gzipped text file
(detected by a .gz suffix). This is one of 3 ways to specify initial
atom coordinates; see the "read_restart"_read_restart.html and
"create_atoms"_create_atoms.html commands for alternative methods.
The structure of the data file is important, though many settings and
sections are optional or can come in any order. See the examples
directory for sample data files for different problems.
A data file has a header and a body. The header appears first. The
first line of the header is always skipped; it typically contains a
description of the file. Then lines are read one at a time. Lines
can have a trailing comment starting with '#' that is ignored. If the
line is blank (only whitespace after comment is deleted), it is
skipped. If the line contains a header keyword, the corresponding
value(s) is read from the line. If it doesn't contain a header
keyword, the line begins the body of the file.
The body of the file contains zero or more sections. The first line
of a section has only a keyword. The next line is skipped. The
remaining lines of the section contain values. The number of lines
depends on the section keyword as described below. Zero or more blank
lines can be used between sections. Sections can appear in any order,
with a few exceptions as noted below.
The formatting of individual lines in the data file (indentation,
spacing between words and numbers) is not important except that header
and section keywords (e.g. atoms, xlo xhi, Masses, Bond Coeffs) must
be capitalized as shown and can't have extra white space between their
words - e.g. two spaces or a tab between "Bond" and "Coeffs" is not
valid.
:line
These are the recognized header keywords. Header lines can come in
any order. The value(s) are read from the beginning of the line.
Thus the keyword {atoms} should be in a line like "1000 atoms"; the
keyword {ylo yhi} should be in a line like "-10.0 10.0 ylo yhi"; the
keyword {xy xz yz} should be in a line like "0.0 5.0 6.0 xy xz yz".
All these settings have a default value of 0, except the lo/hi box
size defaults are -0.5 and 0.5. A line need only appear if the value
is different than the default.
{atoms} = # of atoms in system
{bonds} = # of bonds in system
{angles} = # of angles in system
{dihedrals} = # of dihedrals in system
{impropers} = # of impropers in system
{atom types} = # of atom types in system
{bond types} = # of bond types in system
{angle types} = # of angle types in system
{dihedral types} = # of dihedral types in system
{improper types} = # of improper types in system
{extra bond per atom} = leave space for this many new bonds per atom
{ellipsoids} = # of ellipsoids in system
{lines} = # of line segments in system
{triangles} = # of triangles in system
{xlo xhi} = simulation box boundaries in x dimension
{ylo yhi} = simulation box boundaries in y dimension
{zlo zhi} = simulation box boundaries in z dimension
{xy xz yz} = simulation box tilt factors for triclinic system :ul
The initial simulation box size is determined by the lo/hi settings.
In any dimension, the system may be periodic or non-periodic; see the
"boundary"_boundary.html command.
If the {xy xz yz} line does not appear, LAMMPS will set up an
axis-aligned (orthogonal) simulation box. If the line does appear,
LAMMPS creates a non-orthogonal simulation domain shaped as a
parallelepiped with triclinic symmetry. The parallelepiped has its
"origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting
from the origin given by A = (xhi-xlo,0,0); B = (xy,yhi-ylo,0); C =
(xz,yz,zhi-zlo). {Xy,xz,yz} can be 0.0 or positive or negative values
and are called "tilt factors" because they are the amount of
displacement applied to faces of an originally orthogonal box to
transform it into the parallelepiped.
The tilt factors (xy,xz,yz) can not skew the box more than half the
distance of the corresponding parallel box length. For example, if
xlo = 2 and xhi = 12, then the x box length is 10 and the xy tilt
factor must be between -5 and 5. Similarly, both xz and yz must be
between -(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a
limitation, since if the maximum tilt factor is 5 (as in this
example), then configurations with tilt = ..., -15, -5, 5, 15, 25,
... are all geometrically equivalent.
-See "this section"_Section_howto.html#howto_12 of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+See "Section_howto 12"_Section_howto.html#howto_12 of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
When a triclinic system is used, the simulation domain must be
periodic in any dimensions with a non-zero tilt factor, as defined by
the "boundary"_boundary.html command. I.e. if the xy tilt factor is
non-zero, then both the x and y dimensions must be periodic.
Similarly, x and z must be periodic if xz is non-zero and y and z must
be periodic if yz is non-zero. Also note that if your simulation will
tilt the box, e.g. via the "fix deform"_fix_deform.html command, the
simulation box must be defined as triclinic, even if the tilt factors
are initially 0.0.
For 2d simulations, the {zlo zhi} values should be set to bound the z
coords for atoms that appear in the file; the default of -0.5 0.5 is
valid if all z coords are 0.0. For 2d triclinic simulations, the xz
and yz tilt factors must be 0.0.
If the system is periodic (in a dimension), then atom coordinates can
be outside the bounds (in that dimension); they will be remapped (in a
periodic sense) back inside the box.
IMPORTANT NOTE: If the system is non-periodic (in a dimension), then
all atoms in the data file must have coordinates (in that dimension)
that are "greater than or equal to" the lo value and "less than or
equal to" the hi value. If the non-periodic dimension is of style
"fixed" (see the "boundary"_boundary.html command), then the atom
coords must be strictly "less than" the hi value, due to the way
LAMMPS assign atoms to processors. Note that you should not make the
lo/hi values radically smaller/larger than the extent of the atoms.
For example, if your atoms extend from 0 to 50, you should not specify
the box bounds as -10000 and 10000. This is because LAMMPS uses the
specified box size to layout the 3d grid of processors. A huge
(mostly empty) box will be sub-optimal for performance when using
"fixed" boundary conditions (see the "boundary"_boundary.html
command). When using "shrink-wrap" boundary conditions (see the
"boundary"_boundary.html command), a huge (mostly empty) box may cause
a parallel simulation to lose atoms the first time that LAMMPS
shrink-wraps the box around the atoms.
The "extra bond per atom" setting should be used if new bonds will be
added to the system when a simulation runs, e.g. by using the "fix
bond/create"_fix_bond_create.html command. This will pre-allocate
space in LAMMPS data structures for storing the new bonds.
The "ellipsoids" and "lines" and "triangles" settings are only used
with "atom_style ellipsoid or line or tri"_atom_style.html and
specifies how many of the atoms are finite-size ellipsoids or lines or
triangles; the remainder are point particles. See the discussion of
ellipsoidflag and the {Ellipsoids} section below. See the discussion
of lineflag and the {Lines} section below. See the discussion of
triangleflag and the {Triangles} section below.
:line
These are the section keywords for the body of the file.
{Atoms, Velocities, Masses, Ellipsoids, Lines, Triangles} = atom-property sections
{Bonds, Angles, Dihedrals, Impropers} = molecular topology sections
{Pair Coeffs, Bond Coeffs, Angle Coeffs, Dihedral Coeffs, \
Improper Coeffs} = force field sections
{BondBond Coeffs, BondAngle Coeffs, MiddleBondTorsion Coeffs, \
EndBondTorsion Coeffs, AngleTorsion Coeffs, AngleAngleTorsion Coeffs, \
BondBond13 Coeffs, AngleAngle Coeffs} = class 2 force field sections :ul
Each section is listed below in alphabetic order. The format of each
section is described including the number of lines it must contain and
rules (if any) for where it can appear in the data file.
Any individual line in the various sections can have a trailing
comment starting with "#" for annotation purposes. E.g. in the
Atoms section:
10 1 17 -1.0 10.0 5.0 6.0 # salt ion :pre
:line
{Angle Coeffs} section:
one line per angle type :ulb,l
line syntax: ID coeffs :l
ID = angle type (1-N)
coeffs = list of coeffs :pre
example: :l
6 70 108.5 0 0 :pre
:ule
The number and meaning of the coefficients are specific to the defined
angle style. See the "angle_style"_angle_style.html and
"angle_coeff"_angle_coeff.html commands for details. Coefficients can
also be set via the "angle_coeff"_angle_coeff.html command in the
input script.
:line
{AngleAngle Coeffs} section:
one line per improper type :ulb,l
line syntax: ID coeffs :l
ID = improper type (1-N)
coeffs = list of coeffs (see "improper_coeff"_improper_coeff.html) :pre
:ule
:line
{AngleAngleTorsion Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs (see "dihedral_coeff"_dihedral_coeff.html) :pre
:ule
:line
{Angles} section:
one line per angle :ulb,l
line syntax: ID type atom1 atom2 atom3 :l
ID = number of angle (1-Nangles)
type = angle type (1-Nangletype)
atom1,atom2,atom3 = IDs of 1st,2nd,3rd atoms in angle :pre
example: :b
2 2 17 29 430 :pre
:ule
The 3 atoms are ordered linearly within the angle. Thus the central
atom (around which the angle is computed) is the atom2 in the list.
E.g. H,O,H for a water molecule. The {Angles} section must appear
after the {Atoms} section. All values in this section must be
integers (1, not 1.0).
:line
{AngleTorsion Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs (see "dihedral_coeff"_dihedral_coeff.html) :pre
:ule
:line
{Atoms} section:
one line per atom
line syntax: depends on atom style :ul
An {Atoms} section must appear in the data file if natoms > 0 in the
header section. The atoms can be listed in any order. These are the
line formats for each "atom style"_atom_style.html in LAMMPS. As
discussed below, each line can optionally have 3 flags (nx,ny,nz)
appended to it, which indicate which image of a periodic simulation
box the atom is in. These may be important to include for some kinds
of analysis.
angle: atom-ID molecule-ID atom-type x y z
atomic: atom-ID atom-type x y z
bond: atom-ID molecule-ID atom-type x y z
charge: atom-ID atom-type q x y z
dipole: atom-ID atom-type q x y z mux muy muz
electron: atom-ID atom-type q spin eradius x y z
ellipsoid: atom-ID atom-type ellipsoidflag density x y z
full: atom-ID molecule-ID atom-type q x y z
line: atom-ID molecule-ID atom-type lineflag density x y z
meso: atom-ID atom-type rho e cv x y z
molecular: atom-ID molecule-ID atom-type x y z
peri: atom-ID atom-type volume density x y z
sphere: atom-ID atom-type diameter density x y z
tri: atom-ID molecule-ID atom-type triangleflag density x y z
wavepacket: atom-ID atom-type charge spin eradius etag cs_re cs_im x y z
hybrid: atom-ID atom-type x y z sub-style1 sub-style2 ... :tb(s=:)
The keywords have these meanings:
atom-ID = integer ID of atom
molecule-ID = integer ID of molecule the atom belongs to
atom-type = type of atom (1-Ntype)
q = charge on atom (charge units)
diameter = diameter of spherical atom (distance units)
ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles
lineflag = 1 for line segment particles, 0 for point particles
triangleflag = 1 for triangular particles, 0 for point particles
density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
volume = volume of atom (distance^3 units)
x,y,z = coordinates of atom
mux,muy,muz = components of dipole moment of atom (dipole units)
rho = density (need units) for SPH particles
e = energy (need units) for SPH particles
cv = heat capacity (need units) for SPH particles
spin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP)
eradius = electron radius (or fixed-core radius)
etag = integer ID of electron that each wavepacket belongs to
cs_re,cs_im = real/imaginary parts of wavepacket coefficients :ul
The units for these quantities depend on the unit style; see the
"units"_units.html command for details.
For 2d simulations specify z as 0.0, or a value within the {zlo zhi}
setting in the data file header.
The atom-ID is used to identify the atom throughout the simulation and
in dump files. Normally, it is a unique value from 1 to Natoms for
each atom. Unique values larger than Natoms can be used, but they
will cause extra memory to be allocated on each processor, if an atom
map array is used (see the "atom_modify"_atom_modify.html command).
If an atom map array is not used (e.g. an atomic system with no
bonds), and velocities are not assigned in the data file, and you
don't care if unique atom IDs appear in dump files, then the atom-IDs
can all be set to 0.
The molecule ID is a 2nd identifier attached to an atom. Normally, it
is a number from 1 to N, identifying which molecule the atom belongs
to. It can be 0 if it is an unbonded atom or if you don't care to
keep track of molecule assignments.
The diameter specifies the size of a finite-size spherical particle.
It can be set to 0.0, which means that atom is a point particle.
The ellipsoidflag, lineflag, and triangleflag determine whether the
particle is a finite-size ellipsoid or line or triangle of finite
size, or a point particle. Additional attributes must be defined for
each ellipsoid in the {Ellipsoids} section. Additional attributes
must be defined for each line in the {Lines} section. Additional
attributes must be defined for each triangle in the {Triangles}
section.
Some pair styles and fixes and computes that operate on finite-size
particles allow for a mixture of finite-size and point particles. See
the doc pages of individual commands for details.
The density is used in conjunction with the particle volume for
finite-size particles to set the mass of the particle as mass =
density * volume. In this context, volume can be a 3d quantity (for
spheres or ellipsoids), a 2d quantity (for triangles), or a 1d
quantity (for line segments). If the volume is 0.0, meaning a point
particle, then the density value is used as the mass.
For atom_style hybrid, following the 5 initial values (ID,type,x,y,z),
specific values for each sub-style must be listed. The order of the
sub-styles is the same as they were listed in the
"atom_style"_atom_style.html command. The sub-style specific values
are those that are not the 5 standard ones (ID,type,x,y,z). For
example, for the "charge" sub-style, a "q" value would appear. For
the "full" sub-style, a "molecule-ID" and "q" would appear. These are
listed in the same order they appear as listed above. Thus if
atom_style hybrid charge sphere :pre
were used in the input script, each atom line would have these fields:
atom-ID atom-type x y z q diameter density :pre
Atom lines (all lines or none of them) can optionally list 3 trailing
integer values: nx,ny,nz. For periodic dimensions, they specify which
image of the simulation box the atom is considered to be in. An image
of 0 means it is inside the box as defined. A value of 2 means add 2
box lengths to get the true value. A value of -1 means subtract 1 box
length to get the true value. LAMMPS updates these flags as atoms
cross periodic boundaries during the simulation. The flags can be
output with atom snapshots via the "dump"_dump.html command.
If nx,ny,nz values are not set in the data file, LAMMPS initializes
them to 0. If image information is needed for later analysis and they
are not all initially 0, it's important to set them correctly in the
data file. Also, if you plan to use the "replicate"_replicate.html
command to generate a larger system, these flags must be listed
correctly for bonded atoms when the bond crosses a periodic boundary.
I.e. the values of the image flags should be different by 1 (in the
appropriate dimension) for the two atoms in such a bond.
Atom velocities and other atom quantities not defined above are set to
0.0 when the {Atoms} section is read. Velocities can be set later by
a {Velocities} section in the data file or by a
"velocity"_velocity.html or "set"_set.html command in the input
script.
:line
{Bond Coeffs} section:
one line per bond type :ulb,l
line syntax: ID coeffs :l
ID = bond type (1-N)
coeffs = list of coeffs :pre
example: :l
4 250 1.49 :pre
:ule
The number and meaning of the coefficients are specific to the defined
bond style. See the "bond_style"_bond_style.html and
"bond_coeff"_bond_coeff.html commands for details. Coefficients can
also be set via the "bond_coeff"_bond_coeff.html command in the input
script.
:line
{BondAngle Coeffs} section:
one line per angle type :ulb,l
line syntax: ID coeffs :l
ID = angle type (1-N)
coeffs = list of coeffs (see class 2 section of "angle_coeff"_angle_coeff.html) :pre
:ule
:line
{BondBond Coeffs} section:
one line per angle type :ulb,l
line syntax: ID coeffs :l
ID = angle type (1-N)
coeffs = list of coeffs (see class 2 section of "angle_coeff"_angle_coeff.html) :pre
:ule
:line
{BondBond13 Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of "dihedral_coeff"_dihedral_coeff.html) :pre
:ule
:line
{Bonds} section:
one line per bond :ulb,l
line syntax: ID type atom1 atom2 :l
ID = bond number (1-Nbonds)
type = bond type (1-Nbondtype)
atom1,atom2 = IDs of 1st,2nd atoms in bond :pre
example: :l
12 3 17 29 :pre
:ule
The {Bonds} section must appear after the {Atoms} section. All values
in this section must be integers (1, not 1.0).
:line
{Dihedral Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs :pre
example: :l
3 0.6 1 0 1 :pre
:ule
The number and meaning of the coefficients are specific to the defined
dihedral style. See the "dihedral_style"_dihedral_style.html and
"dihedral_coeff"_dihedral_coeff.html commands for details.
Coefficients can also be set via the
"dihedral_coeff"_dihedral_coeff.html command in the input script.
:line
{Dihedrals} section:
one line per dihedral :ulb,l
line syntax: ID type atom1 atom2 atom3 atom4 :l
ID = number of dihedral (1-Ndihedrals)
type = dihedral type (1-Ndihedraltype)
atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atoms in dihedral :pre
example: :l
12 4 17 29 30 21 :pre
:ule
The 4 atoms are ordered linearly within the dihedral. The {Dihedrals}
section must appear after the {Atoms} section. All values in this
section must be integers (1, not 1.0).
:line
{Ellipsoids} section:
one line per ellipsoid :ulb,l
line syntax: atom-ID shapex shapey shapez quatw quati quatj quatk :l
atom-ID = ID of atom which is an ellipsoid
shapex,shapey,shapez = 3 diameters of ellipsoid (distance units)
quatw,quati,quatj,quatk = quaternion components for orientation of atom
example: :l
12 1 2 1 1 0 0 0 :pre
:ule
The {Ellipsoids} section must appear if "atom_style
ellipsoid"_atom_style.html is used and any atoms are listed in the
{Atoms} section with an ellipsoidflag = 1. The number of ellipsoids
should be specified in the header section via the "ellipsoids"
keyword.
The 3 shape values specify the 3 diameters or aspect ratios of a
finite-size ellipsoidal particle, when it is oriented along the 3
coordinate axes. They must all be non-zero values.
The values {quatw}, {quati}, {quatj}, and {quatk} set the orientation
of the atom as a quaternion (4-vector). Note that the shape
attributes specify the aspect ratios of an ellipsoidal particle, which
is oriented by default with its x-axis along the simulation box's
x-axis, and similarly for y and z. If this body is rotated (via the
right-hand rule) by an angle theta around a unit vector (a,b,c), then
the quaternion that represents its new orientation is given by
(cos(theta/2), a*sin(theta/2), b*sin(theta/2), c*sin(theta/2)). These
4 components are quatw, quati, quatj, and quatk as specified above.
LAMMPS normalizes each atom's quaternion in case (a,b,c) is not
specified as a unit vector.
The {Ellipsoids} section must appear after the {Atoms} section.
:line
{EndBondTorsion Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of "dihedral_coeff"_dihedral_coeff.html) :pre
:ule
:line
{Improper Coeffs} section:
one line per improper type :ulb,l
line syntax: ID coeffs :l
ID = improper type (1-N)
coeffs = list of coeffs :pre
example: :l
2 20 0.0548311 :pre
:ule
The number and meaning of the coefficients are specific to the defined
improper style. See the "improper_style"_improper_style.html and
"improper_coeff"_improper_coeff.html commands for details.
Coefficients can also be set via the
"improper_coeff"_improper_coeff.html command in the input script.
:line
{Impropers} section:
one line per improper :ulb,l
line syntax: ID type atom1 atom2 atom3 atom4 :l
ID = number of improper (1-Nimpropers)
type = improper type (1-Nimpropertype)
atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atoms in improper :pre
example: :l
12 3 17 29 13 100 :pre
:ule
The ordering of the 4 atoms determines the definition of the improper
angle used in the formula for each "improper
style"_improper_style.html. See the doc pages for individual styles
for details.
The {Impropers} section must appear after the {Atoms} section. All
values in this section must be integers (1, not 1.0).
:line
{Lines} section:
one line per line segment :ulb,l
line syntax: atom-ID x1 y1 x2 y2 :l
atom-ID = ID of atom which is a line segment
x1,y1 = 1st end point
x2,y2 = 2nd end point
example: :l
12 1.0 0.0 2.0 0.0 :pre
:ule
The {Lines} section must appear if "atom_style line"_atom_style.html
is used and any atoms are listed in the {Atoms} section with a
lineflag = 1. The number of lines should be specified in the header
section via the "lines" keyword.
The 2 end points are the end points of the line segment. The ordering
of the 2 points should be such that using a right-hand rule to cross
the line segment with a unit vector in the +z direction, gives an
"outward" normal vector perpendicular to the line segment.
I.e. normal = (c2-c1) x (0,0,1). This orientation may be important
for defining some interactions.
The {Lines} section must appear after the {Atoms} section.
:line
{Masses} section:
one line per atom type :ulb,l
line syntax: ID mass :l
ID = atom type (1-N)
mass = mass value :pre
example: :l
3 1.01 :pre
:ule
This defines the mass of each atom type. This can also be set via the
"mass"_mass.html command in the input script. This section cannot be
used for atom styles that define a mass for individual atoms -
e.g. "atom_style sphere"_atom_style.html.
:line
{MiddleBondTorsion Coeffs} section:
one line per dihedral type :ulb,l
line syntax: ID coeffs :l
ID = dihedral type (1-N)
coeffs = list of coeffs (see class 2 section of "dihedral_coeff"_dihedral_coeff.html) :pre
:ule
:line
{Pair Coeffs} section:
one line per atom type :ulb,l
line syntax: ID coeffs :l
ID = atom type (1-N)
coeffs = list of coeffs :pre
example: :l
3 0.022 2.35197 0.022 2.35197 :pre
:ule
The number and meaning of the coefficients are specific to the defined
pair style. See the "pair_style"_pair_style.html and
"pair_coeff"_pair_coeff.html commands for details. Coefficients can
also be set via the "pair_coeff"_pair_coeff.html command in the input
script.
:line
{Triangles} section:
one line per triangle :ulb,l
line syntax: atom-ID x1 y1 x2 y2 :l
atom-ID = ID of atom which is a line segment
x1,y1,z1 = 1st corner point
x2,y2,z2 = 2nd corner point
x3,y3,z3 = 3rd corner point
example: :l
12 0.0 0.0 0.0 2.0 0.0 1.0 0.0 2.0 1.0 :pre
:ule
The {Triangles} section must appear if "atom_style
tri"_atom_style.html is used and any atoms are listed in the {Atoms}
section with a triangleflag = 1. The number of lines should be
specified in the header section via the "triangles" keyword.
The 3 corner points are the corner points of the triangle. The
ordering of the 3 points should be such that using a right-hand rule
to go from point1 to point2 to point3 gives an "outward" normal vector
to the face of the triangle. I.e. normal = (c2-c1) x (c3-c1). This
orientation may be important for defining some interactions.
The {Triangles} section must appear after the {Atoms} section.
:line
{Velocities} section:
one line per atom
line syntax: depends on atom style :ul
all styles except those listed: atom-ID vx vy vz
dipole: atom-ID vx vy vz wx wy wz
electron: atom-ID vx vy vz evel
ellipsoid: atom-ID vx vy vz lx ly lz
sphere: atom-ID vx vy vz wx wy wz :tb(s=:)
where the keywords have these meanings:
vx,vy,vz = translational velocity of atom
lx,ly,lz = angular momentum of aspherical atom
wx,wy,wz = angular velocity of spherical atom
evel = electron radial velocity (0 for fixed-core):ul
The velocity lines can appear in any order. This section can only be
used after an {Atoms} section. This is because the {Atoms} section
must have assigned a unique atom ID to each atom so that velocities
can be assigned to them.
Vx, vy, vz, and evel are in "units"_units.html of velocity. Lx, ly,
lz are in units of angular momentum (distance-velocity-mass). Wx, Wy,
Wz are in units of angular velocity (radians/time).
Translational velocities can also be set by the
"velocity"_velocity.html command in the input script.
:line
[Restrictions:]
To read gzipped data files, you must compile LAMMPS with the
-DLAMMPS_GZIP option - see the "Making
LAMMPS"_Section_start.html#start_2 section of the documentation.
[Related commands:]
"read_restart"_read_restart.html, "create_atoms"_create_atoms.html
[Default:] none
diff --git a/doc/region.html b/doc/region.html
index a9b089de7..58832093d 100644
--- a/doc/region.html
+++ b/doc/region.html
@@ -1,309 +1,309 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>region command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>region ID style args keyword arg ...
</PRE>
<UL><LI>ID = user-assigned name for the region
<LI>style = <I>delete</I> or <I>block</I> or <I>cone</I> or <I>cylinder</I> or <I>plane</I> or <I>prism</I> or <I>sphere</I> or <I>union</I> or <I>intersect</I>
<PRE> <I>delete</I> = no args
<I>block</I> args = xlo xhi ylo yhi zlo zhi
xlo,xhi,ylo,yhi,zlo,zhi = bounds of block in all dimensions (distance units)
<I>cone</I> args = dim c1 c2 radlo radhi lo hi
dim = <I>x</I> or <I>y</I> or <I>z</I> = axis of cone
c1,c2 = coords of cone axis in other 2 dimensions (distance units)
radlo,radhi = cone radii at lo and hi end (distance units)
lo,hi = bounds of cone in dim (distance units)
<I>cylinder</I> args = dim c1 c2 radius lo hi
dim = <I>x</I> or <I>y</I> or <I>z</I> = axis of cylinder
c1,c2 = coords of cylinder axis in other 2 dimensions (distance units)
radius = cylinder radius (distance units)
lo,hi = bounds of cylinder in dim (distance units)
<I>plane</I> args = px py pz nx ny nz
px,py,pz = point on the plane (distance units)
nx,ny,nz = direction normal to plane (distance units)
<I>prism</I> args = xlo xhi ylo yhi zlo zhi xy xz yz
xlo,xhi,ylo,yhi,zlo,zhi = bounds of untilted prism (distance units)
xy = distance to tilt y in x direction (distance units)
xz = distance to tilt z in x direction (distance units)
yz = distance to tilt z in y direction (distance units)
<I>sphere</I> args = x y z radius
x,y,z = center of sphere (distance units)
radius = radius of sphere (distance units)
<I>union</I> args = N reg-ID1 reg-ID2 ...
N = # of regions to follow, must be 2 or greater
reg-ID1,reg-ID2, ... = IDs of regions to join together
<I>intersect</I> args = N reg-ID1 reg-ID2 ...
N = # of regions to follow, must be 2 or greater
reg-ID1,reg-ID2, ... = IDs of regions to intersect
</PRE>
<LI>zero or more keyword/arg pairs may be appended
<LI>keyword = <I>side</I> or <I>units</I> or <I>move</I> or <I>rotate</I>
<PRE> <I>side</I> value = <I>in</I> or <I>out</I>
<I>in</I> = the region is inside the specified geometry
<I>out</I> = the region is outside the specified geometry
<I>units</I> value = <I>lattice</I> or <I>box</I>
<I>lattice</I> = the geometry is defined in lattice units
<I>box</I> = the geometry is defined in simulation box units
<I>move</I> args = v_x v_y v_z
v_x,v_y,v_z = equal-style variables for x,y,z displacement of region over time
<I>rotate</I> args = v_theta Px Py Pz Rx Ry Rz
v_theta = equal-style variable for rotaton of region over time (in radians)
Px,Py,Pz = origin for axis of rotation (distance units)
Rx,Ry,Rz = axis of rotation vector
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>region 1 block -3.0 5.0 INF 10.0 INF INF
region 2 sphere 0.0 0.0 0.0 5 side out
region void cylinder y 2 3 5 -5.0 EDGE units box
region 1 prism 0 10 0 10 0 10 2 0 0
region outside union 4 side1 side2 side3 side4
region 2 sphere 0.0 0.0 0.0 5 side out move v_left v_up NULL
</PRE>
<P><B>Description:</B>
</P>
<P>This command defines a geometric region of space. Various other
commands use regions. For example, the region can be filled with
atoms via the <A HREF = "create_atoms.html">create_atoms</A> command. Or a bounding
box around the region, can be used to define the simulation box via
the <A HREF = "create_box.html">create_box</A> command. Or the atoms in the region
can be identified as a group via the <A HREF = "group.html">group</A> command, or
deleted via the <A HREF = "delete_atoms.html">delete_atoms</A> command. Or the
surface of the region can be used as a boundary wall via the <A HREF = "fix_wall_region.html">fix
wall/region</A> command.
</P>
<P>Commands which use regions typically test whether an atom's position
is contained in the region or not. For this purpose, coordinates
exactly on the region boundary are considered to be interior to the
region. This means, for example, for a spherical region, an atom on
the sphere surface would be part of the region if the sphere were
defined with the <I>side in</I> keyword, but would not be part of the
region if it were defined using the <I>side out</I> keyword. See more
details on the <I>side</I> keyword below.
</P>
<P>Normally, regions in LAMMPS are "static", meaning their geometric
extent does not change with time. If the <I>move</I> or <I>rotate</I> keyword
is used, as described below, the region becomes "dynamic", meaning
it's location or orientation changes with time. This may be useful,
for example, when thermostatting a region, via the compute temp/region
command, or when the fix wall/region command uses a region surface as
a bounding wall on particle motion, i.e. a rotating container.
</P>
<P>The <I>delete</I> style removes the named region. Since there is little
overhead to defining extra regions, there is normally no need to do
this, unless you are defining and discarding large numbers of regions
in your input script.
</P>
<P>The lo/hi values for <I>block</I> or <I>cone</I> or <I>cylinder</I> or <I>prism</I> styles
can be specified as EDGE or INF. EDGE means they extend all the way
to the global simulation box boundary. Note that this is the current
box boundary; if the box changes size during a simulation, the region
does not. INF means a large negative or positive number (1.0e20), so
it should encompass the simulation box even if it changes size. If a
region is defined before the simulation box has been created (via
<A HREF = "create_box.html">create_box</A> or <A HREF = "read_data.html">read_data</A> or
<A HREF = "read_restart.html">read_restart</A> commands), then an EDGE or INF
parameter cannot be used. For a <I>prism</I> region, a non-zero tilt
factor in any pair of dimensions cannot be used if both the lo/hi
values in either of those dimensions are INF. E.g. if the xy tilt is
non-zero, then xlo and xhi cannot both be INF, nor can ylo and yhi.
</P>
<P>IMPORTANT NOTE: Regions in LAMMPS do not get wrapped across periodic
boundaries, as specified by the <A HREF = "boundary.html">boundary</A> command. For
example, a spherical region that is defined so that it overlaps a
periodic boundary is not treated as 2 half-spheres, one on either side
of the simulation box.
</P>
<P>IMPORTANT NOTE: Regions in LAMMPS are always 3d geometric objects,
regardless of whether the <A HREF = "dimension.html">dimension</A> of a simulation
is 2d or 3d. Thus when using regions in a 2d simulation, you should
be careful to define the region so that its intersection with the 2d
x-y plane of the simulation has the 2d geometric extent you want.
</P>
<P>For style <I>cone</I>, an axis-aligned cone is defined which is like a
<I>cylinder</I> except that two different radii (one at each end) can be
defined. Either of the radii (but not both) can be 0.0.
</P>
<P>For style <I>cone</I> and <I>cylinder</I>, the c1,c2 params are coordinates in
the 2 other dimensions besides the cylinder axis dimension. For dim =
x, c1/c2 = y/z; for dim = y, c1/c2 = x/z; for dim = z, c1/c2 = x/y.
Thus the third example above specifies a cylinder with its axis in the
y-direction located at x = 2.0 and z = 3.0, with a radius of 5.0, and
extending in the y-direction from -5.0 to the upper box boundary.
</P>
<P>For style <I>plane</I>, a plane is defined which contain the point
(px,py,pz) and has a normal vector (nx,ny,nz). The normal vector does
not have to be of unit length. The "inside" of the plane is the
half-space in the direction of the normal vector; see the discussion
of the <I>side</I> option below.
</P>
<P>For style <I>prism</I>, a parallelepiped is defined (it's too hard to spell
parallelepiped in an input script!). The parallelepiped has its
"origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting
from the origin given by A = (xhi-xlo,0,0); B = (xy,yhi-ylo,0); C =
(xz,yz,zhi-zlo). <I>Xy,xz,yz</I> can be 0.0 or positive or negative values
and are called "tilt factors" because they are the amount of
displacement applied to faces of an originally orthogonal box to
transform it into the parallelepiped.
</P>
<P>A prism region that will be used with the <A HREF = "create_box.html">create_box</A>
command to define a triclinic simulation box must have tilt factors
(xy,xz,yz) that do not skew the box more than half the distance of
corresponding the parallel box length. For example, if xlo = 2 and
xhi = 12, then the x box length is 10 and the xy tilt factor must be
between -5 and 5. Similarly, both xz and yz must be between
-(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation,
since if the maximum tilt factor is 5 (as in this example), then
configurations with tilt = ..., -15, -5, 5, 15, 25, ... are all
geometrically equivalent.
</P>
-<P>See <A HREF = "Section_howto.html#howto_12">this section</A> of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+<P>See <A HREF = "Section_howto.html#howto_12">Section_howto 12</A> of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
</P>
<P>The <I>union</I> style creates a region consisting of the volume of all the
listed regions combined. The <I>intersect</I> style creates a region
consisting of the volume that is common to all the listed regions.
</P>
<HR>
<P>The <I>side</I> keyword determines whether the region is considered to be
inside or outside of the specified geometry. Using this keyword in
conjunction with <I>union</I> and <I>intersect</I> regions, complex geometries
can be built up. For example, if the interior of two spheres were
each defined as regions, and a <I>union</I> style with <I>side</I> = out was
constructed listing the region-IDs of the 2 spheres, the resulting
region would be all the volume in the simulation box that was outside
both of the spheres.
</P>
<P>The <I>units</I> keyword determines the meaning of the distance units used
to define the region for any argument above listed as having distance
units. It also affects the scaling of the velocity vector specfied
with the <I>vel</I> keyword, the amplitude vector specified with the
<I>wiggle</I> keyword, and the rotation point specified with the <I>rotate</I>
keyword, since they each involve a distance metric.
</P>
<P>A <I>box</I> value selects standard distance units as defined by the
<A HREF = "units.html">units</A> command, e.g. Angstroms for units = real or metal.
A <I>lattice</I> value means the distance units are in lattice spacings.
The <A HREF = "lattice.html">lattice</A> command must have been previously used to
define the lattice spacings which are used as follows:
</P>
<UL><LI>For style <I>block</I>, the lattice spacing in dimension x is applied to
xlo and xhi, similarly the spacings in dimensions y,z are applied to
ylo/yhi and zlo/zhi.
<LI>For style <I>cone</I>, the lattice spacing in argument <I>dim</I> is applied to
lo and hi. The spacings in the two radial dimensions are applied to
c1 and c2. The two cone radii are scaled by the lattice
spacing in the dimension corresponding to c1.
<LI>For style <I>cylinder</I>, the lattice spacing in argument <I>dim</I> is applied
to lo and hi. The spacings in the two radial dimensions are applied
to c1 and c2. The cylinder radius is scaled by the lattice
spacing in the dimension corresponding to c1.
<LI>For style <I>plane</I>, the lattice spacing in dimension x is applied to
px and nx, similarly the spacings in dimensions y,z are applied to
py/ny and pz/nz.
<LI>For style <I>prism</I>, the lattice spacing in dimension x is applied to
xlo and xhi, similarly for ylo/yhi and zlo/zhi. The lattice spacing
in dimension x is applied to xy and xz, and the spacing in dimension y
to yz.
<LI>For style <I>sphere</I>, the lattice spacing in dimensions x,y,z are
applied to the sphere center x,y,z. The spacing in dimension x is
applied to the sphere radius.
</UL>
<HR>
<P>If the <I>move</I> or <I>rotate</I> keywords are used, the region is "dynamic",
meaning its location or orientation changes with time. These keywords
cannot be used with a <I>union</I> or <I>intersect</I> style region. Instead,
the keywords should be used to make the individual sub-regions of the
<I>union</I> or <I>intersect</I> region dynamic. Normally, each sub-region
should be "dynamic" in the same manner (e.g. rotate around the same
point), though this is not a requirement.
</P>
<P>The <I>move</I> keyword allows one or more <A HREF = "variable.html">equal-style
variables</A> to be used to specify the x,y,z displacement
of the region, typically as a function of time. A variable is
specified as v_name, where name is the variable name. Any of the
three variables can be specified as NULL, in which case no
displacement is calculated in that dimension.
</P>
<P>Note that equal-style variables can specify formulas with various
mathematical functions, and include <A HREF = "thermo_style.html">thermo_style</A>
command keywords for the simulation box parameters and timestep and
elapsed time. Thus it is easy to specify a region displacement that
change as a function of time or spans consecutive runs in a continuous
fashion. For the latter, see the <I>start</I> and <I>stop</I> keywords of the
<A HREF = "run.html">run</A> command and the <I>elaplong</I> keyword of <A HREF = "thermo_style.html">thermo_style
custom</A> for details.
</P>
<P>For example, these commands would displace a region from its initial
position, in the positive x direction, effectively at a constant
velocity:
</P>
<PRE>variable dx equal ramp(0,10)
region 2 sphere 10.0 10.0 0.0 5 move v_dx NULL NULL
</PRE>
<P>Note that the initial displacemet is 0.0, though that is not required.
</P>
<P>Either of these varaibles would "wiggle" the region back and forth in
the y direction:
</P>
<PRE>variable dy equal swiggle(0,5,100)
variable dysame equal 5*sin(2*PI*elaplong*dt/100)
region 2 sphere 10.0 10.0 0.0 5 move NULL v_dy NULL
</PRE>
<P>The <I>rotate</I> keyword rotates the region around a rotation axis <I>R</I> =
(Rx,Ry,Rz) that goes thru a point <I>P</I> = (Px,Py,Pz). The rotation
angle is calculated, presumably as a function of time, by a variable
specified as v_theta, where theta is the variable name. The variable
should generate its result in radians. The direction of rotation for
the region around the rotation axis is consistent with the right-hand
rule: if your right-hand thumb points along <I>R</I>, then your fingers
wrap around the axis in the direction of rotation.
</P>
<P>The <I>move</I> and <I>rotate</I> keywords can be used together. In this case,
the displacement specified by the <I>move</I> keyword is applied to the <I>P</I>
point of the <I>rotate</I> keyword.
</P>
<P><B>Restrictions:</B>
</P>
<P>A prism cannot be of 0.0 thickness in any dimension; use a small z
thickness for 2d simulations. For 2d simulations, the xz and yz
parameters must be 0.0.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "lattice.html">lattice</A>, <A HREF = "create_atoms.html">create_atoms</A>,
<A HREF = "delete_atoms.html">delete_atoms</A>, <A HREF = "group.html">group</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are side = in, units = lattice, and no move or
rotation.
</P>
</HTML>
diff --git a/doc/region.txt b/doc/region.txt
index c8da7594f..74744ab50 100644
--- a/doc/region.txt
+++ b/doc/region.txt
@@ -1,298 +1,298 @@
"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
region command :h3
[Syntax:]
region ID style args keyword arg ... :pre
ID = user-assigned name for the region :ulb,l
style = {delete} or {block} or {cone} or {cylinder} or {plane} or {prism} or {sphere} or {union} or {intersect} :l
{delete} = no args
{block} args = xlo xhi ylo yhi zlo zhi
xlo,xhi,ylo,yhi,zlo,zhi = bounds of block in all dimensions (distance units)
{cone} args = dim c1 c2 radlo radhi lo hi
dim = {x} or {y} or {z} = axis of cone
c1,c2 = coords of cone axis in other 2 dimensions (distance units)
radlo,radhi = cone radii at lo and hi end (distance units)
lo,hi = bounds of cone in dim (distance units)
{cylinder} args = dim c1 c2 radius lo hi
dim = {x} or {y} or {z} = axis of cylinder
c1,c2 = coords of cylinder axis in other 2 dimensions (distance units)
radius = cylinder radius (distance units)
lo,hi = bounds of cylinder in dim (distance units)
{plane} args = px py pz nx ny nz
px,py,pz = point on the plane (distance units)
nx,ny,nz = direction normal to plane (distance units)
{prism} args = xlo xhi ylo yhi zlo zhi xy xz yz
xlo,xhi,ylo,yhi,zlo,zhi = bounds of untilted prism (distance units)
xy = distance to tilt y in x direction (distance units)
xz = distance to tilt z in x direction (distance units)
yz = distance to tilt z in y direction (distance units)
{sphere} args = x y z radius
x,y,z = center of sphere (distance units)
radius = radius of sphere (distance units)
{union} args = N reg-ID1 reg-ID2 ...
N = # of regions to follow, must be 2 or greater
reg-ID1,reg-ID2, ... = IDs of regions to join together
{intersect} args = N reg-ID1 reg-ID2 ...
N = # of regions to follow, must be 2 or greater
reg-ID1,reg-ID2, ... = IDs of regions to intersect :pre
zero or more keyword/arg pairs may be appended :l
keyword = {side} or {units} or {move} or {rotate} :l
{side} value = {in} or {out}
{in} = the region is inside the specified geometry
{out} = the region is outside the specified geometry
{units} value = {lattice} or {box}
{lattice} = the geometry is defined in lattice units
{box} = the geometry is defined in simulation box units
{move} args = v_x v_y v_z
v_x,v_y,v_z = equal-style variables for x,y,z displacement of region over time
{rotate} args = v_theta Px Py Pz Rx Ry Rz
v_theta = equal-style variable for rotaton of region over time (in radians)
Px,Py,Pz = origin for axis of rotation (distance units)
Rx,Ry,Rz = axis of rotation vector :pre
:ule
[Examples:]
region 1 block -3.0 5.0 INF 10.0 INF INF
region 2 sphere 0.0 0.0 0.0 5 side out
region void cylinder y 2 3 5 -5.0 EDGE units box
region 1 prism 0 10 0 10 0 10 2 0 0
region outside union 4 side1 side2 side3 side4
region 2 sphere 0.0 0.0 0.0 5 side out move v_left v_up NULL :pre
[Description:]
This command defines a geometric region of space. Various other
commands use regions. For example, the region can be filled with
atoms via the "create_atoms"_create_atoms.html command. Or a bounding
box around the region, can be used to define the simulation box via
the "create_box"_create_box.html command. Or the atoms in the region
can be identified as a group via the "group"_group.html command, or
deleted via the "delete_atoms"_delete_atoms.html command. Or the
surface of the region can be used as a boundary wall via the "fix
wall/region"_fix_wall_region.html command.
Commands which use regions typically test whether an atom's position
is contained in the region or not. For this purpose, coordinates
exactly on the region boundary are considered to be interior to the
region. This means, for example, for a spherical region, an atom on
the sphere surface would be part of the region if the sphere were
defined with the {side in} keyword, but would not be part of the
region if it were defined using the {side out} keyword. See more
details on the {side} keyword below.
Normally, regions in LAMMPS are "static", meaning their geometric
extent does not change with time. If the {move} or {rotate} keyword
is used, as described below, the region becomes "dynamic", meaning
it's location or orientation changes with time. This may be useful,
for example, when thermostatting a region, via the compute temp/region
command, or when the fix wall/region command uses a region surface as
a bounding wall on particle motion, i.e. a rotating container.
The {delete} style removes the named region. Since there is little
overhead to defining extra regions, there is normally no need to do
this, unless you are defining and discarding large numbers of regions
in your input script.
The lo/hi values for {block} or {cone} or {cylinder} or {prism} styles
can be specified as EDGE or INF. EDGE means they extend all the way
to the global simulation box boundary. Note that this is the current
box boundary; if the box changes size during a simulation, the region
does not. INF means a large negative or positive number (1.0e20), so
it should encompass the simulation box even if it changes size. If a
region is defined before the simulation box has been created (via
"create_box"_create_box.html or "read_data"_read_data.html or
"read_restart"_read_restart.html commands), then an EDGE or INF
parameter cannot be used. For a {prism} region, a non-zero tilt
factor in any pair of dimensions cannot be used if both the lo/hi
values in either of those dimensions are INF. E.g. if the xy tilt is
non-zero, then xlo and xhi cannot both be INF, nor can ylo and yhi.
IMPORTANT NOTE: Regions in LAMMPS do not get wrapped across periodic
boundaries, as specified by the "boundary"_boundary.html command. For
example, a spherical region that is defined so that it overlaps a
periodic boundary is not treated as 2 half-spheres, one on either side
of the simulation box.
IMPORTANT NOTE: Regions in LAMMPS are always 3d geometric objects,
regardless of whether the "dimension"_dimension.html of a simulation
is 2d or 3d. Thus when using regions in a 2d simulation, you should
be careful to define the region so that its intersection with the 2d
x-y plane of the simulation has the 2d geometric extent you want.
For style {cone}, an axis-aligned cone is defined which is like a
{cylinder} except that two different radii (one at each end) can be
defined. Either of the radii (but not both) can be 0.0.
For style {cone} and {cylinder}, the c1,c2 params are coordinates in
the 2 other dimensions besides the cylinder axis dimension. For dim =
x, c1/c2 = y/z; for dim = y, c1/c2 = x/z; for dim = z, c1/c2 = x/y.
Thus the third example above specifies a cylinder with its axis in the
y-direction located at x = 2.0 and z = 3.0, with a radius of 5.0, and
extending in the y-direction from -5.0 to the upper box boundary.
For style {plane}, a plane is defined which contain the point
(px,py,pz) and has a normal vector (nx,ny,nz). The normal vector does
not have to be of unit length. The "inside" of the plane is the
half-space in the direction of the normal vector; see the discussion
of the {side} option below.
For style {prism}, a parallelepiped is defined (it's too hard to spell
parallelepiped in an input script!). The parallelepiped has its
"origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors starting
from the origin given by A = (xhi-xlo,0,0); B = (xy,yhi-ylo,0); C =
(xz,yz,zhi-zlo). {Xy,xz,yz} can be 0.0 or positive or negative values
and are called "tilt factors" because they are the amount of
displacement applied to faces of an originally orthogonal box to
transform it into the parallelepiped.
A prism region that will be used with the "create_box"_create_box.html
command to define a triclinic simulation box must have tilt factors
(xy,xz,yz) that do not skew the box more than half the distance of
corresponding the parallel box length. For example, if xlo = 2 and
xhi = 12, then the x box length is 10 and the xy tilt factor must be
between -5 and 5. Similarly, both xz and yz must be between
-(xhi-xlo)/2 and +(yhi-ylo)/2. Note that this is not a limitation,
since if the maximum tilt factor is 5 (as in this example), then
configurations with tilt = ..., -15, -5, 5, 15, 25, ... are all
geometrically equivalent.
-See "this section"_Section_howto.html#howto_12 of the doc pages for a
-geometric description of triclinic boxes, as defined by LAMMPS, and
-how to transform these parameters to and from other commonly used
+See "Section_howto 12"_Section_howto.html#howto_12 of the doc pages
+for a geometric description of triclinic boxes, as defined by LAMMPS,
+and how to transform these parameters to and from other commonly used
triclinic representations.
The {union} style creates a region consisting of the volume of all the
listed regions combined. The {intersect} style creates a region
consisting of the volume that is common to all the listed regions.
:line
The {side} keyword determines whether the region is considered to be
inside or outside of the specified geometry. Using this keyword in
conjunction with {union} and {intersect} regions, complex geometries
can be built up. For example, if the interior of two spheres were
each defined as regions, and a {union} style with {side} = out was
constructed listing the region-IDs of the 2 spheres, the resulting
region would be all the volume in the simulation box that was outside
both of the spheres.
The {units} keyword determines the meaning of the distance units used
to define the region for any argument above listed as having distance
units. It also affects the scaling of the velocity vector specfied
with the {vel} keyword, the amplitude vector specified with the
{wiggle} keyword, and the rotation point specified with the {rotate}
keyword, since they each involve a distance metric.
A {box} value selects standard distance units as defined by the
"units"_units.html command, e.g. Angstroms for units = real or metal.
A {lattice} value means the distance units are in lattice spacings.
The "lattice"_lattice.html command must have been previously used to
define the lattice spacings which are used as follows:
For style {block}, the lattice spacing in dimension x is applied to
xlo and xhi, similarly the spacings in dimensions y,z are applied to
ylo/yhi and zlo/zhi. :ulb,l
For style {cone}, the lattice spacing in argument {dim} is applied to
lo and hi. The spacings in the two radial dimensions are applied to
c1 and c2. The two cone radii are scaled by the lattice
spacing in the dimension corresponding to c1. :l
For style {cylinder}, the lattice spacing in argument {dim} is applied
to lo and hi. The spacings in the two radial dimensions are applied
to c1 and c2. The cylinder radius is scaled by the lattice
spacing in the dimension corresponding to c1. :l
For style {plane}, the lattice spacing in dimension x is applied to
px and nx, similarly the spacings in dimensions y,z are applied to
py/ny and pz/nz. :l
For style {prism}, the lattice spacing in dimension x is applied to
xlo and xhi, similarly for ylo/yhi and zlo/zhi. The lattice spacing
in dimension x is applied to xy and xz, and the spacing in dimension y
to yz. :l
For style {sphere}, the lattice spacing in dimensions x,y,z are
applied to the sphere center x,y,z. The spacing in dimension x is
applied to the sphere radius. :l,ule
:line
If the {move} or {rotate} keywords are used, the region is "dynamic",
meaning its location or orientation changes with time. These keywords
cannot be used with a {union} or {intersect} style region. Instead,
the keywords should be used to make the individual sub-regions of the
{union} or {intersect} region dynamic. Normally, each sub-region
should be "dynamic" in the same manner (e.g. rotate around the same
point), though this is not a requirement.
The {move} keyword allows one or more "equal-style
variables"_variable.html to be used to specify the x,y,z displacement
of the region, typically as a function of time. A variable is
specified as v_name, where name is the variable name. Any of the
three variables can be specified as NULL, in which case no
displacement is calculated in that dimension.
Note that equal-style variables can specify formulas with various
mathematical functions, and include "thermo_style"_thermo_style.html
command keywords for the simulation box parameters and timestep and
elapsed time. Thus it is easy to specify a region displacement that
change as a function of time or spans consecutive runs in a continuous
fashion. For the latter, see the {start} and {stop} keywords of the
"run"_run.html command and the {elaplong} keyword of "thermo_style
custom"_thermo_style.html for details.
For example, these commands would displace a region from its initial
position, in the positive x direction, effectively at a constant
velocity:
variable dx equal ramp(0,10)
region 2 sphere 10.0 10.0 0.0 5 move v_dx NULL NULL :pre
Note that the initial displacemet is 0.0, though that is not required.
Either of these varaibles would "wiggle" the region back and forth in
the y direction:
variable dy equal swiggle(0,5,100)
variable dysame equal 5*sin(2*PI*elaplong*dt/100)
region 2 sphere 10.0 10.0 0.0 5 move NULL v_dy NULL :pre
The {rotate} keyword rotates the region around a rotation axis {R} =
(Rx,Ry,Rz) that goes thru a point {P} = (Px,Py,Pz). The rotation
angle is calculated, presumably as a function of time, by a variable
specified as v_theta, where theta is the variable name. The variable
should generate its result in radians. The direction of rotation for
the region around the rotation axis is consistent with the right-hand
rule: if your right-hand thumb points along {R}, then your fingers
wrap around the axis in the direction of rotation.
The {move} and {rotate} keywords can be used together. In this case,
the displacement specified by the {move} keyword is applied to the {P}
point of the {rotate} keyword.
[Restrictions:]
A prism cannot be of 0.0 thickness in any dimension; use a small z
thickness for 2d simulations. For 2d simulations, the xz and yz
parameters must be 0.0.
[Related commands:]
"lattice"_lattice.html, "create_atoms"_create_atoms.html,
"delete_atoms"_delete_atoms.html, "group"_group.html
[Default:]
The option defaults are side = in, units = lattice, and no move or
rotation.
diff --git a/doc/run_style.html b/doc/run_style.html
index f3f1e25ac..abe21ecdd 100644
--- a/doc/run_style.html
+++ b/doc/run_style.html
@@ -1,192 +1,263 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>run_style command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>run_style style args
</PRE>
-<UL><LI>style = <I>verlet</I> or <I>respa</I>
+<UL><LI>style = <I>verlet</I> or <I>verlet/split</I> or <I>respa</I>
<PRE> <I>verlet</I> args = none
+ <I>verlet/split</I> args = none
<I>respa</I> args = N n1 n2 ... keyword values ...
N = # of levels of rRESPA
n1, n2, ... = loop factor between rRESPA levels (N-1 values)
zero or more keyword/value pairings may be appended to the loop factors
keyword = <I>bond</I> or <I>angle</I> or <I>dihedral</I> or <I>improper</I> or
<I>pair</I> or <I>inner</I> or <I>middle</I> or <I>outer</I> or <I>kspace</I>
<I>bond</I> value = M
M = which level (1-N) to compute bond forces in
<I>angle</I> value = M
M = which level (1-N) to compute angle forces in
<I>dihedral</I> value = M
M = which level (1-N) to compute dihedral forces in
<I>improper</I> value = M
M = which level (1-N) to compute improper forces in
<I>pair</I> value = M
M = which level (1-N) to compute pair forces in
<I>inner</I> values = M cut1 cut2
M = which level (1-N) to compute pair inner forces in
cut1 = inner cutoff between pair inner and
pair middle or outer (distance units)
cut2 = outer cutoff between pair inner and
pair middle or outer (distance units)
<I>middle</I> values = M cut1 cut2
M = which level (1-N) to compute pair middle forces in
cut1 = inner cutoff between pair middle and pair outer (distance units)
cut2 = outer cutoff between pair middle and pair outer (distance units)
<I>outer</I> value = M
M = which level (1-N) to compute pair outer forces in
<I>kspace</I> value = M
M = which level (1-N) to compute kspace forces in
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>run_style verlet
run_style respa 4 2 2 2 bond 1 dihedral 2 pair 3 kspace 4
run_style respa 4 2 2 2 bond 1 dihedral 2 inner 3 5.0 6.0 outer 4 kspace 4
</PRE>
<P><B>Description:</B>
</P>
<P>Choose the style of time integrator used for molecular dynamics
simulations performed by LAMMPS.
</P>
-<P>The <I>verlet</I> style is a velocity-Verlet integrator.
+<P>The <I>verlet</I> style is a standard velocity-Verlet integrator.
</P>
+<HR>
+
+<P>The <I>verlet/split</I> style is also a velocity-Verlet integrator, but it
+splits the force calculation within each timestep over 2 partitions of
+processors. See <A HREF = "Section_start.html#start_6">Section_start 6</A> for an
+explanation of the -partition command-line switch.
+</P>
+<P>Specifically, this style performs all computation except the
+<A HREF = "kspace_style.html">kspace_style</A> portion of the force field on the 1st
+partition. This include the <A HREF = "pair_style.html">pair style</A>, <A HREF = "bond_style.html">bond
+style</A>, <A HREF = "neighbor.html">neighbor list building</A>,
+<A HREF = "fix.html">fixes</A> including time intergration, and output. The
+<A HREF = "kspace_style.html">kspace_style</A> portion of the calculation is
+performed on the 2nd partition.
+</P>
+<P>This is most useful for the PPPM kspace_style when its performance on
+a large number of processors degrades due to the cost of communication
+in its 3d FFTs. In this scenario, splitting your P total processors
+into 2 subsets of processors, P1 in the 1st partition and P2 in the
+2nd partition, can enable your simulation to run faster. This is
+because the long-range forces in PPPM can be calculated at the same
+time as pair-wise and bonded forces are being calculated, and the FFTs
+can actually speed up when running on fewer processors.
+</P>
+<P>To use this style, you must define 2 partitions where P1 is a multiple
+of P2. Typically having P1 be 3x larger than P2 is a good choice.
+The 3d processor layouts in each partition must overlay in the
+following sense. If P1 is a Px1 by Py1 by Pz1 grid, and P2 = Px2 by
+Py2 by Pz2, then Px1 must be an integer multiple of Px2, and similarly
+for Py1 a multiple of Py2, and Pz1 a multiple of Pz2.
+</P>
+<P>Typically the best way to do this is to let the 1st partition choose
+its onn optimal layout, then require the 2nd partition's layout to
+match the integer multiple constraint. See the
+<A HREF = "processors.html">processors</A> command with its <I>part</I> keyword for a way
+to control this, e.g.
+</P>
+<PRE>procssors * * * part 1 2 multiple
+</PRE>
+<P>You can also use the <A HREF = "partition.html">partition</A> command to explicitly
+specity the processor layout on each partition. E.g. for 2 partitions
+of 60 and 15 processors each:
+</P>
+<PRE>partition yes 1 processors 3 4 5
+partition yes 2 processors 3 1 5
+</PRE>
+<P>When you run in 2-partition mode with the <I>verlet/split</I> style, the
+thermodyanmic data for the entire simulation will be output to the log
+and screen file of the 1st partition, which are log.lammps.0 and
+screen.0 by default; see the "-plog and -pscreen command-line
+switches"Section_start.html#start_6 to change this. The log and
+screen file for the 2nd partition will not contain thermodynamic
+output beyone the 1st timestep of the run.
+</P>
+<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
+performance details of the speed-up offered by the <I>verlet/split</I>
+style. One important performance consideration is the assignemnt of
+logical processors in the 2 partitions to the physical cores of a
+parallel machine. The <A HREF = "processors.html">processors</A> command has
+options to support this, and strategies are discussed in
+<A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual.
+</P>
+<HR>
+
<P>The <I>respa</I> style implements the rRESPA multi-timescale integrator
<A HREF = "#Tuckerman">(Tuckerman)</A> with N hierarchical levels, where level 1 is
the innermost loop (shortest timestep) and level N is the outermost
loop (largest timestep). The loop factor arguments specify what the
looping factor is between levels. N1 specifies the number of
iterations of level 1 for a single iteration of level 2, N2 is the
iterations of level 2 per iteration of level 3, etc. N-1 looping
parameters must be specified.
</P>
<P>The <A HREF = "timestep.html">timestep</A> command sets the timestep for the
outermost rRESPA level. Thus if the example command above for a
4-level rRESPA had an outer timestep of 4.0 fmsec, the inner timestep
would be 8x smaller or 0.5 fmsec. All other LAMMPS commands that
specify number of timesteps (e.g. <A HREF = "neigh_modify.html">neigh_modify</A>
parameters, <A HREF = "dump.html">dump</A> every N timesteps, etc) refer to the
outermost timesteps.
</P>
<P>The rRESPA keywords enable you to specify at what level of the
hierarchy various forces will be computed. If not specified, the
defaults are that bond forces are computed at level 1 (innermost
loop), angle forces are computed where bond forces are, dihedral
forces are computed where angle forces are, improper forces are
computed where dihedral forces are, pair forces are computed at the
outermost level, and kspace forces are computed where pair forces are.
The inner, middle, outer forces have no defaults.
</P>
<P>The <I>inner</I> and <I>middle</I> keywords take additional arguments for
cutoffs that are used by the pairwise force computations. If the 2
cutoffs for <I>inner</I> are 5.0 and 6.0, this means that all pairs up to
6.0 apart are computed by the inner force. Those between 5.0 and 6.0
have their force go ramped to 0.0 so the overlap with the next regime
(middle or outer) is smooth. The next regime (middle or outer) will
compute forces for all pairs from 5.0 outward, with those from 5.0 to
6.0 having their value ramped in an inverse manner.
</P>
<P>Only some pair potentials support the use of the <I>inner</I> and <I>middle</I>
and <I>outer</I> keywords. If not, only the <I>pair</I> keyword can be used
with that pair style, meaning all pairwise forces are computed at the
same rRESPA level. See the doc pages for individual pair styles for
details.
</P>
<P>When using rRESPA (or for any MD simulation) care must be taken to
choose a timestep size(s) that insures the Hamiltonian for the chosen
ensemble is conserved. For the constant NVE ensemble, total energy
must be conserved. Unfortunately, it is difficult to know <I>a priori</I>
how well energy will be conserved, and a fairly long test simulation
(~10 ps) is usually necessary in order to verify that no long-term
drift in energy occurs with the trial set of parameters.
</P>
<P>With that caveat, a few rules-of-thumb may be useful in selecting
<I>respa</I> settings. The following applies mostly to biomolecular
simulations using the CHARMM or a similar all-atom force field, but
the concepts are adaptable to other problems. Without SHAKE, bonds
involving hydrogen atoms exhibit high-frequency vibrations and require
a timestep on the order of 0.5 fmsec in order to conserve energy. The
relatively inexpensive force computations for the bonds, angles,
impropers, and dihedrals can be computed on this innermost 0.5 fmsec
step. The outermost timestep cannot be greater than 4.0 fmsec without
risking energy drift. Smooth switching of forces between the levels
of the rRESPA hierarchy is also necessary to avoid drift, and a 1-2
angstrom "healing distance" (the distance between the outer and inner
cutoffs) works reasonably well. We thus recommend the following
settings for use of the <I>respa</I> style without SHAKE in biomolecular
simulations:
</P>
<PRE>timestep 4.0
run_style respa 4 2 2 2 inner 2 4.5 6.0 middle 3 8.0 10.0 outer 4
</PRE>
<P>With these settings, users can expect good energy conservation and
roughly a 2.5 fold speedup over the <I>verlet</I> style with a 0.5 fmsec
timestep.
</P>
<P>If SHAKE is used with the <I>respa</I> style, time reversibility is lost,
but substantially longer time steps can be achieved. For biomolecular
simulations using the CHARMM or similar all-atom force field, bonds
involving hydrogen atoms exhibit high frequency vibrations and require
a time step on the order of 0.5 fmsec in order to conserve energy.
These high frequency modes also limit the outer time step sizes since
the modes are coupled. It is therefore desirable to use SHAKE with
respa in order to freeze out these high frequency motions and increase
the size of the time steps in the respa hierarchy. The following
settings can be used for biomolecular simulations with SHAKE and
rRESPA:
</P>
<PRE>fix 2 all shake 0.000001 500 0 m 1.0 a 1
timestep 4.0
run_style respa 2 2 inner 1 4.0 5.0 outer 2
</PRE>
<P>With these settings, users can expect good energy conservation and
roughly a 1.5 fold speedup over the <I>verlet</I> style with SHAKE and a
2.0 fmsec timestep.
</P>
<P>For non-biomolecular simulations, the <I>respa</I> style can be
advantageous if there is a clear separation of time scales - fast and
slow modes in the simulation. Even a LJ system can benefit from
rRESPA if the interactions are divided by the inner, middle and outer
keywords. A 2-fold or more speedup can be obtained while maintaining
good energy conservation. In real units, for a pure LJ fluid at
liquid density, with a sigma of 3.0 angstroms, and epsilon of 0.1
Kcal/mol, the following settings seem to work well:
</P>
<PRE>timestep 36.0
run_style respa 3 3 4 inner 1 3.0 4.0 middle 2 6.0 7.0 outer 3
</PRE>
+<HR>
+
<P><B>Restrictions:</B>
</P>
+<P>The <I>verlet/split</I> style can only be used if LAMMPS was built with the
+REPLICA package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
+section for more info on packages.
+</P>
<P>Whenever using rRESPA, the user should experiment with trade-offs in
speed and accuracy for their system, and verify that they are
conserving energy to adequate precision.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "timestep.html">timestep</A>, <A HREF = "run.html">run</A>
</P>
<P><B>Default:</B>
</P>
<PRE>run_style verlet
</PRE>
<HR>
<A NAME = "Tuckerman"></A>
<P><B>(Tuckerman)</B> Tuckerman, Berne and Martyna, J Chem Phys, 97, p 1990
(1992).
</P>
</HTML>
diff --git a/doc/run_style.txt b/doc/run_style.txt
index 508f97564..2484fc4df 100644
--- a/doc/run_style.txt
+++ b/doc/run_style.txt
@@ -1,184 +1,255 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
run_style command :h3
[Syntax:]
run_style style args :pre
-style = {verlet} or {respa} :ulb,l
+style = {verlet} or {verlet/split} or {respa} :ulb,l
{verlet} args = none
+ {verlet/split} args = none
{respa} args = N n1 n2 ... keyword values ...
N = # of levels of rRESPA
n1, n2, ... = loop factor between rRESPA levels (N-1 values)
zero or more keyword/value pairings may be appended to the loop factors
keyword = {bond} or {angle} or {dihedral} or {improper} or
{pair} or {inner} or {middle} or {outer} or {kspace}
{bond} value = M
M = which level (1-N) to compute bond forces in
{angle} value = M
M = which level (1-N) to compute angle forces in
{dihedral} value = M
M = which level (1-N) to compute dihedral forces in
{improper} value = M
M = which level (1-N) to compute improper forces in
{pair} value = M
M = which level (1-N) to compute pair forces in
{inner} values = M cut1 cut2
M = which level (1-N) to compute pair inner forces in
cut1 = inner cutoff between pair inner and
pair middle or outer (distance units)
cut2 = outer cutoff between pair inner and
pair middle or outer (distance units)
{middle} values = M cut1 cut2
M = which level (1-N) to compute pair middle forces in
cut1 = inner cutoff between pair middle and pair outer (distance units)
cut2 = outer cutoff between pair middle and pair outer (distance units)
{outer} value = M
M = which level (1-N) to compute pair outer forces in
{kspace} value = M
M = which level (1-N) to compute kspace forces in :pre
:ule
[Examples:]
run_style verlet
run_style respa 4 2 2 2 bond 1 dihedral 2 pair 3 kspace 4
run_style respa 4 2 2 2 bond 1 dihedral 2 inner 3 5.0 6.0 outer 4 kspace 4 :pre
[Description:]
Choose the style of time integrator used for molecular dynamics
simulations performed by LAMMPS.
-The {verlet} style is a velocity-Verlet integrator.
+The {verlet} style is a standard velocity-Verlet integrator.
+
+:line
+
+The {verlet/split} style is also a velocity-Verlet integrator, but it
+splits the force calculation within each timestep over 2 partitions of
+processors. See "Section_start 6"_Section_start.html#start_6 for an
+explanation of the -partition command-line switch.
+
+Specifically, this style performs all computation except the
+"kspace_style"_kspace_style.html portion of the force field on the 1st
+partition. This include the "pair style"_pair_style.html, "bond
+style"_bond_style.html, "neighbor list building"_neighbor.html,
+"fixes"_fix.html including time intergration, and output. The
+"kspace_style"_kspace_style.html portion of the calculation is
+performed on the 2nd partition.
+
+This is most useful for the PPPM kspace_style when its performance on
+a large number of processors degrades due to the cost of communication
+in its 3d FFTs. In this scenario, splitting your P total processors
+into 2 subsets of processors, P1 in the 1st partition and P2 in the
+2nd partition, can enable your simulation to run faster. This is
+because the long-range forces in PPPM can be calculated at the same
+time as pair-wise and bonded forces are being calculated, and the FFTs
+can actually speed up when running on fewer processors.
+
+To use this style, you must define 2 partitions where P1 is a multiple
+of P2. Typically having P1 be 3x larger than P2 is a good choice.
+The 3d processor layouts in each partition must overlay in the
+following sense. If P1 is a Px1 by Py1 by Pz1 grid, and P2 = Px2 by
+Py2 by Pz2, then Px1 must be an integer multiple of Px2, and similarly
+for Py1 a multiple of Py2, and Pz1 a multiple of Pz2.
+
+Typically the best way to do this is to let the 1st partition choose
+its onn optimal layout, then require the 2nd partition's layout to
+match the integer multiple constraint. See the
+"processors"_processors.html command with its {part} keyword for a way
+to control this, e.g.
+
+procssors * * * part 1 2 multiple :pre
+
+You can also use the "partition"_partition.html command to explicitly
+specity the processor layout on each partition. E.g. for 2 partitions
+of 60 and 15 processors each:
+
+partition yes 1 processors 3 4 5
+partition yes 2 processors 3 1 5 :pre
+
+When you run in 2-partition mode with the {verlet/split} style, the
+thermodyanmic data for the entire simulation will be output to the log
+and screen file of the 1st partition, which are log.lammps.0 and
+screen.0 by default; see the "-plog and -pscreen command-line
+switches"Section_start.html#start_6 to change this. The log and
+screen file for the 2nd partition will not contain thermodynamic
+output beyone the 1st timestep of the run.
+
+See "Section_accelerate"_Section_accelerate.html of the manual for
+performance details of the speed-up offered by the {verlet/split}
+style. One important performance consideration is the assignemnt of
+logical processors in the 2 partitions to the physical cores of a
+parallel machine. The "processors"_processors.html command has
+options to support this, and strategies are discussed in
+"Section_accelerate"_Section_accelerate.html of the manual.
+
+:line
The {respa} style implements the rRESPA multi-timescale integrator
"(Tuckerman)"_#Tuckerman with N hierarchical levels, where level 1 is
the innermost loop (shortest timestep) and level N is the outermost
loop (largest timestep). The loop factor arguments specify what the
looping factor is between levels. N1 specifies the number of
iterations of level 1 for a single iteration of level 2, N2 is the
iterations of level 2 per iteration of level 3, etc. N-1 looping
parameters must be specified.
The "timestep"_timestep.html command sets the timestep for the
outermost rRESPA level. Thus if the example command above for a
4-level rRESPA had an outer timestep of 4.0 fmsec, the inner timestep
would be 8x smaller or 0.5 fmsec. All other LAMMPS commands that
specify number of timesteps (e.g. "neigh_modify"_neigh_modify.html
parameters, "dump"_dump.html every N timesteps, etc) refer to the
outermost timesteps.
The rRESPA keywords enable you to specify at what level of the
hierarchy various forces will be computed. If not specified, the
defaults are that bond forces are computed at level 1 (innermost
loop), angle forces are computed where bond forces are, dihedral
forces are computed where angle forces are, improper forces are
computed where dihedral forces are, pair forces are computed at the
outermost level, and kspace forces are computed where pair forces are.
The inner, middle, outer forces have no defaults.
The {inner} and {middle} keywords take additional arguments for
cutoffs that are used by the pairwise force computations. If the 2
cutoffs for {inner} are 5.0 and 6.0, this means that all pairs up to
6.0 apart are computed by the inner force. Those between 5.0 and 6.0
have their force go ramped to 0.0 so the overlap with the next regime
(middle or outer) is smooth. The next regime (middle or outer) will
compute forces for all pairs from 5.0 outward, with those from 5.0 to
6.0 having their value ramped in an inverse manner.
Only some pair potentials support the use of the {inner} and {middle}
and {outer} keywords. If not, only the {pair} keyword can be used
with that pair style, meaning all pairwise forces are computed at the
same rRESPA level. See the doc pages for individual pair styles for
details.
When using rRESPA (or for any MD simulation) care must be taken to
choose a timestep size(s) that insures the Hamiltonian for the chosen
ensemble is conserved. For the constant NVE ensemble, total energy
must be conserved. Unfortunately, it is difficult to know {a priori}
how well energy will be conserved, and a fairly long test simulation
(~10 ps) is usually necessary in order to verify that no long-term
drift in energy occurs with the trial set of parameters.
With that caveat, a few rules-of-thumb may be useful in selecting
{respa} settings. The following applies mostly to biomolecular
simulations using the CHARMM or a similar all-atom force field, but
the concepts are adaptable to other problems. Without SHAKE, bonds
involving hydrogen atoms exhibit high-frequency vibrations and require
a timestep on the order of 0.5 fmsec in order to conserve energy. The
relatively inexpensive force computations for the bonds, angles,
impropers, and dihedrals can be computed on this innermost 0.5 fmsec
step. The outermost timestep cannot be greater than 4.0 fmsec without
risking energy drift. Smooth switching of forces between the levels
of the rRESPA hierarchy is also necessary to avoid drift, and a 1-2
angstrom "healing distance" (the distance between the outer and inner
cutoffs) works reasonably well. We thus recommend the following
settings for use of the {respa} style without SHAKE in biomolecular
simulations:
timestep 4.0
run_style respa 4 2 2 2 inner 2 4.5 6.0 middle 3 8.0 10.0 outer 4 :pre
With these settings, users can expect good energy conservation and
roughly a 2.5 fold speedup over the {verlet} style with a 0.5 fmsec
timestep.
If SHAKE is used with the {respa} style, time reversibility is lost,
but substantially longer time steps can be achieved. For biomolecular
simulations using the CHARMM or similar all-atom force field, bonds
involving hydrogen atoms exhibit high frequency vibrations and require
a time step on the order of 0.5 fmsec in order to conserve energy.
These high frequency modes also limit the outer time step sizes since
the modes are coupled. It is therefore desirable to use SHAKE with
respa in order to freeze out these high frequency motions and increase
the size of the time steps in the respa hierarchy. The following
settings can be used for biomolecular simulations with SHAKE and
rRESPA:
fix 2 all shake 0.000001 500 0 m 1.0 a 1
timestep 4.0
run_style respa 2 2 inner 1 4.0 5.0 outer 2 :pre
With these settings, users can expect good energy conservation and
roughly a 1.5 fold speedup over the {verlet} style with SHAKE and a
2.0 fmsec timestep.
For non-biomolecular simulations, the {respa} style can be
advantageous if there is a clear separation of time scales - fast and
slow modes in the simulation. Even a LJ system can benefit from
rRESPA if the interactions are divided by the inner, middle and outer
keywords. A 2-fold or more speedup can be obtained while maintaining
good energy conservation. In real units, for a pure LJ fluid at
liquid density, with a sigma of 3.0 angstroms, and epsilon of 0.1
Kcal/mol, the following settings seem to work well:
timestep 36.0
run_style respa 3 3 4 inner 1 3.0 4.0 middle 2 6.0 7.0 outer 3 :pre
+:line
+
[Restrictions:]
+The {verlet/split} style can only be used if LAMMPS was built with the
+REPLICA package. See the "Making LAMMPS"_Section_start.html#start_3
+section for more info on packages.
+
Whenever using rRESPA, the user should experiment with trade-offs in
speed and accuracy for their system, and verify that they are
conserving energy to adequate precision.
[Related commands:]
"timestep"_timestep.html, "run"_run.html
[Default:]
run_style verlet :pre
:line
:link(Tuckerman)
[(Tuckerman)] Tuckerman, Berne and Martyna, J Chem Phys, 97, p 1990
(1992).
diff --git a/doc/suffix.html b/doc/suffix.html
index e58c86bf8..4915dc4cf 100644
--- a/doc/suffix.html
+++ b/doc/suffix.html
@@ -1,76 +1,87 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>suffix command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>suffix style
</PRE>
<UL><LI>style = <I>off</I> or <I>on</I> or <I>opt</I> or <I>omp</I> or <I>gpu</I> or <I>cuda</I>
</UL>
<P><B>Examples:</B>
</P>
<PRE>suffix off
suffix on
suffix gpu
</PRE>
<P><B>Description:</B>
</P>
<P>This command allows you to use variants of various styles if they
exist. In that respect it operates the same as the <A HREF = "Section_start.html#start_6">-suffix
command-line switch</A>. It also has options
to turn off/on any suffix setting made via the command line.
</P>
<P>The specified style can be <I>opt</I>, <I>omp</I>, <I>gpu</I>, or <I>cuda</I>. These refer to
optional packages that LAMMPS can be built with, as described in <A HREF = "Section_start.html#start_3">this
section of the manual</A>. The "opt" style
corrsponds to the OPT package, the "omp" style to the USER-OMP package,
the "gpu" style to the GPU package, and the "cuda" style to the
USER-CUDA package.
</P>
<P>These are the variants these packages provide:
</P>
-<UL><LI>OPT = a handful of pair styles, cache-optimized for faster CPU performance
-<LI>USER-OMP = a collection of pair, dihedral and fix styles with support for OpenMP multi-threading
-<LI>GPU = a handful of pair styles and the PPPM kspace_style, optimized to run on one or more GPUs or multicore CPU/GPU nodes
-<LI>USER-CUDA = a collection of atom, pair, fix, compute, and intergrate styles, optimized to run on one or more NVIDIA GPUs
+<UL><LI>OPT = a handful of pair styles, cache-optimized for faster CPU
+performance
+
+<LI>USER-OMP = a collection of pair, bond, angle, dihedral, improper,
+kspace, compute, and fix styles with support for OpenMP
+multi-threading
+
+<LI>GPU = a handful of pair styles and the PPPM kspace_style, optimized to
+run on one or more GPUs or multicore CPU/GPU nodes
+
+<LI>USER-CUDA = a collection of atom, pair, fix, compute, and intergrate
+styles, optimized to run on one or more NVIDIA GPUs
</UL>
<P>As an example, all of the packages provide a <A HREF = "pair_lj.html">pair_style
lj/cut</A> variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
suffix command is used with the appropriate style, you do not need to
modify your input script. The specified suffix (opt,omp,gpu,cuda) is
automatically appended whenever your input script command creates a
-new <A HREF = "atom_style.html">atom</A>, <A HREF = "pair_style.html">pair</A>, <A HREF = "fix.html">fix</A>,
-<A HREF = "compute.html">compute</A>, or <A HREF = "run_style.html">run</A> style. If the variant
-version does not exist, the standard version is created.
+new <A HREF = "atom_style.html">atom</A>, <A HREF = "pair_style.html">pair</A>,
+<A HREF = "bond_style.html">bond</A>, <A HREF = "angle_style.html">angle</A>,
+<A HREF = "dihedral_style.html">dihedral</A>, <A HREF = "improper_style.html">improper</A>,
+<A HREF = "kspace_style.html">kspace</A>, <A HREF = "fix.html">fix</A>, <A HREF = "compute.html">compute</A>, or
+<A HREF = "run_style.html">run</A> style. If the variant version does not exist,
+the standard version is created.
</P>
<P>If the specified style is <I>off</I>, then any previously specified suffix
is temporarily disabled, whether it was specified by a command-line
switch or a previous suffix command. If the specified style is <I>on</I>,
a disabled suffix is turned back on. The use of these 2 commands lets
your input script use a standard LAMMPS style (i.e. a non-accelerated
variant), which can be useful for testing or benchmarking purposes.
Of course this is also possible by not using any suffix commands, and
explictly appending or not appending the suffix to the relevant
commands in your input script.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "Section_start.html#start_6">Command-line switch -suffix</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/suffix.txt b/doc/suffix.txt
index ec773f0eb..d417d2008 100644
--- a/doc/suffix.txt
+++ b/doc/suffix.txt
@@ -1,71 +1,82 @@
"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
suffix command :h3
[Syntax:]
suffix style :pre
style = {off} or {on} or {opt} or {omp} or {gpu} or {cuda} :ul
[Examples:]
suffix off
suffix on
suffix gpu :pre
[Description:]
This command allows you to use variants of various styles if they
exist. In that respect it operates the same as the "-suffix
command-line switch"_Section_start.html#start_6. It also has options
to turn off/on any suffix setting made via the command line.
The specified style can be {opt}, {omp}, {gpu}, or {cuda}. These refer to
optional packages that LAMMPS can be built with, as described in "this
section of the manual"_Section_start.html#start_3. The "opt" style
corrsponds to the OPT package, the "omp" style to the USER-OMP package,
the "gpu" style to the GPU package, and the "cuda" style to the
USER-CUDA package.
These are the variants these packages provide:
-OPT = a handful of pair styles, cache-optimized for faster CPU performance
-USER-OMP = a collection of pair, dihedral and fix styles with support for OpenMP multi-threading
-GPU = a handful of pair styles and the PPPM kspace_style, optimized to run on one or more GPUs or multicore CPU/GPU nodes
-USER-CUDA = a collection of atom, pair, fix, compute, and intergrate styles, optimized to run on one or more NVIDIA GPUs :ul
+OPT = a handful of pair styles, cache-optimized for faster CPU
+performance :ulb,l
+
+USER-OMP = a collection of pair, bond, angle, dihedral, improper,
+kspace, compute, and fix styles with support for OpenMP
+multi-threading :l
+
+GPU = a handful of pair styles and the PPPM kspace_style, optimized to
+run on one or more GPUs or multicore CPU/GPU nodes :l
+
+USER-CUDA = a collection of atom, pair, fix, compute, and intergrate
+styles, optimized to run on one or more NVIDIA GPUs :l,ule
As an example, all of the packages provide a "pair_style
lj/cut"_pair_lj.html variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
suffix command is used with the appropriate style, you do not need to
modify your input script. The specified suffix (opt,omp,gpu,cuda) is
automatically appended whenever your input script command creates a
-new "atom"_atom_style.html, "pair"_pair_style.html, "fix"_fix.html,
-"compute"_compute.html, or "run"_run_style.html style. If the variant
-version does not exist, the standard version is created.
+new "atom"_atom_style.html, "pair"_pair_style.html,
+"bond"_bond_style.html, "angle"_angle_style.html,
+"dihedral"_dihedral_style.html, "improper"_improper_style.html,
+"kspace"_kspace_style.html, "fix"_fix.html, "compute"_compute.html, or
+"run"_run_style.html style. If the variant version does not exist,
+the standard version is created.
If the specified style is {off}, then any previously specified suffix
is temporarily disabled, whether it was specified by a command-line
switch or a previous suffix command. If the specified style is {on},
a disabled suffix is turned back on. The use of these 2 commands lets
your input script use a standard LAMMPS style (i.e. a non-accelerated
variant), which can be useful for testing or benchmarking purposes.
Of course this is also possible by not using any suffix commands, and
explictly appending or not appending the suffix to the relevant
commands in your input script.
[Restrictions:] none
[Related commands:]
"Command-line switch -suffix"_Section_start.html#start_6
[Default:] none
diff --git a/doc/tad.html b/doc/tad.html
index 08a87fc8b..459bdb1c1 100644
--- a/doc/tad.html
+++ b/doc/tad.html
@@ -1,317 +1,318 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>tad command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>tad N t_event T_lo T_hi delta tmax compute-ID keyword value ...
</PRE>
<UL><LI>N = # of timesteps to run (not including dephasing/quenching)
<LI>t_event = timestep interval between event checks
<LI>T_lo = temperature at which event times are desired
<LI>T_hi = temperature at which MD simulation is performed
<LI>delta = desired confidence level for stopping criterion
<LI>tmax = reciprocal of lowest expected preexponential factor (time units)
<LI>compute-ID = ID of the compute used for event detection
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>min</I> or <I>neb</I> or <I>min_style</I> or <I>neb_style</I> or <I>neb_log</I>
<PRE> <I>min</I> values = etol ftol maxiter maxeval
etol = stopping tolerance for energy (energy units)
ftol = stopping tolerance for force (force units)
maxiter = max iterations of minimize
maxeval = max number of force/energy evaluations
<I>neb</I> values = ftol N1 N2 Nevery
etol = stopping tolerance for energy (energy units)
ftol = stopping tolerance for force (force units)
N1 = max # of iterations (timesteps) to run initial NEB
N2 = max # of iterations (timesteps) to run barrier-climbing NEB
Nevery = print NEB statistics every this many timesteps
<I>min_style</I> value = <I>cg</I> or <I>hftn</I> or <I>sd</I> or <I>quickmin</I> or <I>fire</I>
<I>neb_style</I> value = <I>quickmin</I> or <I>fire</I>
<I>neb_log</I> value = file where NEB statistics are printed
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>tad 2000 50 1800 2300 0.01 0.01 event
tad 2000 50 1800 2300 0.01 0.01 event &
min 1e-05 1e-05 100 100 &
neb 0.0 0.01 200 200 20 &
min_style cg &
neb_style fire &
neb_log log.neb
</PRE>
<P><B>Description:</B>
</P>
<P>Run a temperature accelerated dynamics (TAD) simulation. This method
requires two or more partitions to perform NEB transition state
searches.
</P>
<P>TAD is described in <A HREF = "#Voter">this paper</A> by Art Voter. It is a method
that uses accelerated dynamics at an elevated temperature to generate
results at a specified lower temperature. A good overview of
accelerated dynamics methods for such systems is given in <A HREF = "#Voter2">this review
paper</A> from the same group. In general, these methods assume
that the long-time dynamics is dominated by infrequent events i.e. the
system is is confined to low energy basins for long periods,
punctuated by brief, randomly-occurring transitions to adjacent
basins. TAD is suitable for infrequent-event systems, where in
addition, the transition kinetics are well-approximated by harmonic
transition state theory (hTST). In hTST, the temperature dependence of
transition rates follows the Arrhenius relation. As a consequence a
set of event times generated in a high-temperature simulation can be
mapped to a set of much longer estimated times in the low-temperature
system. However, because this mapping involves the energy barrier of
the transition event, which is different for each event, the first
event at the high temperature may not be the earliest event at the low
temperature. TAD handles this by first generating a set of possible
events from the current basin. After each event, the simulation is
reflected backwards into the current basin. This is repeated until
the stopping criterion is satisfied, at which point the event with the
earliest low-temperature occurrence time is selected. The stopping
criterion is that the confidence measure be greater than
1-<I>delta</I>. The confidence measure is the probability that no earlier
low-temperature event will occur at some later time in the
high-temperature simulation. hTST provides an lower bound for this
probability, based on the user-specified minimum pre-exponential
factor (reciprocal of <I>tmax</I>).
</P>
<P>In order to estimate the energy barrier for each event, the TAD method
invokes the <A HREF = "neb.html">NEB</A> method. Each NEB replica runs on a
partition of processors. The current NEB implementation in LAMMPS
restricts you to having exactly one processor per replica. For more
information, see the documentation for the <A HREF = "neb.html">neb</A> command. In
the current LAMMPS implementation of TAD, all the non-NEB TAD
operations are performed on the first partition, while the other
-partitions remain idle. See <A HREF = "Section_howto.html#howto_5">this section</A>
-of the manual for further discussion of multi-replica simulations.
+partitions remain idle. See <A HREF = "Section_howto.html#howto_5">Section_howto
+5</A> of the manual for further discussion of
+multi-replica simulations.
</P>
<P>A TAD run has several stages, which are repeated each time an event is
performed. The logic for a TAD run is as follows:
</P>
<PRE>while (time remains):
while (time < tstop):
until (event occurs):
run dynamics for t_event steps
quench
run neb calculation using all replicas
compute tlo from energy barrier
update earliest event
update tstop
reflect back into current basin
execute earliest event
</PRE>
<P>Before this outer loop begins, the initial potential energy basin is
identified by quenching (an energy minimization, see below) the
initial state and storing the resulting coordinates for reference.
</P>
<P>Inside the inner loop, dynamics is run continuously according to
whatever integrator has been specified by the user, stopping every
<I>t_event</I> steps to check if a transition event has occurred. This
check is performed by quenching the system and comparing the resulting
atom coordinates to the coordinates from the previous basin.
</P>
<P>A quench is an energy minimization and is performed by whichever
algorithm has been defined by the <I>min</I> and <I>min_style</I> keywords or
their default values. Note that typically, you do not need to perform
a highly-converged minimization to detect a transition event.
</P>
<P>The event check is performed by a compute with the specified
<I>compute-ID</I>. Currently there is only one compute that works with the
TAD commmand, which is the <A HREF = "compute_event_displace.html">compute
event/displace</A> command. Other
event-checking computes may be added. <A HREF = "compute_event_displace.html">Compute
event/displace</A> checks whether any atom in
the compute group has moved further than a specified threshold
distance. If so, an "event" has occurred.
</P>
<P>The neb calculation is similar to that invoked by the <A HREF = "neb.html">neb</A>
command, except that the final state is generated internally, instead
of being read in from a file. The TAD implementation provides default
values for the NEB settings, which can be overridden using the <I>neb</I>
and <I>neb_style</I> keywords.
</P>
<HR>
<P>A key aspect of the TAD method is setting the stopping criterion
appropriately. If this criterion is too conservative, then many
events must be generated before one is finally executed. Conversely,
if this criterion is too aggressive, high-entropy high-barrier events
will be over-sampled, while low-entropy low-barrier events will be
under-sampled. If the lowest pre-exponential factor is known fairly
accurately, then it can be used to estimate <I>tmax</I>, and the value of
<I>delta</I> can be set to the desired confidence level e.g. <I>delta</I> = 0.05
corresponds to 95% confidence. However, for systems where the dynamics
are not well characterized (the most common case), it will be
necessary to experiment with the values of <I>delta</I> and <I>tmax</I> to get a
good trade-off between accuracy and performance.
</P>
<P>A second key aspect is the choice of <I>t_hi</I>. A larger value greatly
increases the rate at which new events are generated. However, too
large a value introduces errors due to anharmonicity (not accounted
for within hTST). Once again, for any given system, experimentation is
necessary to determine the best value of <I>t_hi</I>.
</P>
<HR>
<P>Five kinds of output can be generated during a TAD run: event
statistics, NEB statistics, thermodynamic output by each replica, dump
files, and restart files.
</P>
<P>Event statistics are printed to the screen and master log.lammps file
each time an event is executed. The quantities are the timestep, CPU
time, global event number <I>N</I>, local event number <I>M</I>, event status,
energy barrier, time margin, <I>t_lo</I> and <I>delt_lo</I>. The timestep is
the usual LAMMPS timestep, which corresponds to the high-temperature
time at which the event was detected, in units of timestep. The CPU
time is the total processor time since the start of the TAD run. The
global event number <I>N</I> is a counter that increments with each
executed event. The local event number <I>M</I> is a counter that resets to
zero upon entering each new basin. The event status is <I>E</I> when an
event is executed, and is <I>D</I> for an event that is detected, while
<I>DF</I> is for a detected event that is also the earliest (first) event
at the low temperature.
</P>
<P>The time margin is the ratio of the high temperature time in the
current basin to the stopping time. This last number can be used to
judge whether the stopping time is too short or too long (see above).
</P>
<P><I>t_lo</I> is the low-temperature event time when the current basin was
entered, in units of timestep. del<I>t_lo</I> is the time of each detected
event, measured relative to <I>t_lo</I>. <I>delt_lo</I> is equal to the
high-temperature time since entering the current basin, scaled by an
exponential factor that depends on the hi/lo temperature ratio and the
energy barrier for that event.
</P>
<P>On lines for executed events, with status <I>E</I>, the global event number
is incremented by one,
the local event number and time margin are reset to zero,
while the global event number, energy barrier, and
<I>delt_lo</I> match the last event with status <I>DF</I>
in the immediately preceding block of detected events.
The low-temperature event time <I>t_lo</I> is incremented by <I>delt_lo</I>.
</P>
<P>The NEB statistics are written to the file specified by the <I>neb_log</I>
keyword. If the keyword value is "none", then no NEB statistics are
printed out. The statistics are written every <I>Nevery</I> timesteps. See
the <A HREF = "neb.html">neb</A> command for a full description of the NEB
statistics. When invoked from TAD, NEB statistics are never printed to
the screen.
</P>
<P>Because the NEB calculation must run on multiple partitions, LAMMPS
produces additional screen and log files for each partition,
e.g. log.lammps.0, log.lammps.1, etc. For the TAD command, these
contain the thermodynamic output of each NEB replica. In addition, the
log file for the first partition, log.lammps.0, will contain
thermodynamic output from short runs and minimizations corresponding
to the dynamics and quench operations, as well as a line for each new
detected event, as described above.
</P>
<P>After the TAD command completes, timing statistics for the TAD run are
printed in each replica's log file, giving a breakdown of how much CPU
time was spent in each stage (NEB, dynamics, quenching, etc).
</P>
<P>Any <A HREF = "dump.html">dump files</A> defined in the input script will be written
to during a TAD run at timesteps when an event is executed. This
means the the requested dump frequency in the <A HREF = "dump.html">dump</A> command
is ignored. There will be one dump file (per dump command) created
for all partitions. The atom coordinates of the dump snapshot are
those of the minimum energy configuration resulting from quenching
following the executed event. The timesteps written into the dump
files correspond to the timestep at which the event occurred and NOT
the clock. A dump snapshot corresponding to the initial minimum state
used for event detection is written to the dump file at the beginning
of each TAD run.
</P>
<P>If the <A HREF = "restart.html">restart</A> command is used, a single restart file
for all the partitions is generated, which allows a TAD run to be
continued by a new input script in the usual manner. The restart file
is generated after an event is executed. The restart file contains a
snapshot of the system in the new quenched state, including the event
number and the low-temperature time. The restart frequency specified
in the <A HREF = "restart.html">restart</A> command is interpreted differently when
performing a TAD run. It does not mean the timestep interval between
restart files. Instead it means an event interval for executed
events. Thus a frequency of 1 means write a restart file every time
an event is executed. A frequency of 10 means write a restart file
every 10th executed event. When an input script reads a restart file
from a previous TAD run, the new script can be run on a different
number of replicas or processors.
</P>
<P>Note that within a single state, the dynamics will typically
temporarily continue beyond the event that is ultimately chosen, until
the stopping criterionis satisfied. When the event is eventually
executed, the timestep counter is reset to the value when the event
was detected. Similarly, after each quench and NEB minimization, the
timestep counter is reset to the value at the start of the
minimization. This means that the timesteps listed in the replica log
files do not always increase monotonically. However, the timestep
values printed to the master log file, dump files, and restart files
are always monotonically increasing.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><I>N</I> setting must be integer multiple of <I>t_event</I>.
</P>
<P>Runs restarted from restart files written during a TAD run will only
produce identical results if the user-specified integrator supports
exact restarts. So <A HREF = "fix_nh.html">fix nvt</A> will produce an exact
restart, but <A HREF = "fix_langevin.html">fix langevin</A> will not.
</P>
<P>This command cannot be used when any fixes are defined that keep track
of elapsed time to perform time-dependent operations. Examples
include the "ave" fixes such as <A HREF = "fix_ave_spatial.html">fix
ave/spatial</A>. Also <A HREF = "fix_dt_reset.html">fix
dt/reset</A> and <A HREF = "fix_deposit.html">fix deposit</A>.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "compute_event_displace.html">compute event/displace</A>,
<A HREF = "min_modify.html">min_modify</A>, <A HREF = "min_style.html">min_style</A>,
<A HREF = "run_style.html">run_style</A>, <A HREF = "minimize.html">minimize</A>,
<A HREF = "temper.html">temper</A>, <A HREF = "neb.html">neb</A>,
<A HREF = "prd.html">prd</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are <I>min</I> = 0.1 0.1 40 50, <I>neb</I> = 0.01 100 100
10, <I>min_style</I> = <I>cg</I>, <I>neb_style</I> = <I>quickmin</I>, and <I>neb_log</I> =
"none"
</P>
<HR>
<A NAME = "Voter"></A>
<P><B>(Voter)</B> Sørensen and Voter, J Chem Phys, 112, 9599 (2000)
</P>
<A NAME = "Voter2"></A>
<P><B>(Voter2)</B> Voter, Montalenti, Germann, Annual Review of Materials
Research 32, 321 (2002).
</P>
</HTML>
diff --git a/doc/tad.txt b/doc/tad.txt
index adb10fcc3..e62e92a66 100644
--- a/doc/tad.txt
+++ b/doc/tad.txt
@@ -1,304 +1,305 @@
"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
tad command :h3
[Syntax:]
tad N t_event T_lo T_hi delta tmax compute-ID \
keyword value ... :pre
N = # of timesteps to run (not including dephasing/quenching) :ulb,l
t_event = timestep interval between event checks :l
T_lo = temperature at which event times are desired :l
T_hi = temperature at which MD simulation is performed :l
delta = desired confidence level for stopping criterion :l
tmax = reciprocal of lowest expected preexponential factor (time units) :l
compute-ID = ID of the compute used for event detection :l
zero or more keyword/value pairs may be appended :l
keyword = {min} or {neb} or {min_style} or {neb_style} or {neb_log} :l
{min} values = etol ftol maxiter maxeval
etol = stopping tolerance for energy (energy units)
ftol = stopping tolerance for force (force units)
maxiter = max iterations of minimize
maxeval = max number of force/energy evaluations
{neb} values = ftol N1 N2 Nevery
etol = stopping tolerance for energy (energy units)
ftol = stopping tolerance for force (force units)
N1 = max # of iterations (timesteps) to run initial NEB
N2 = max # of iterations (timesteps) to run barrier-climbing NEB
Nevery = print NEB statistics every this many timesteps
{min_style} value = {cg} or {hftn} or {sd} or {quickmin} or {fire}
{neb_style} value = {quickmin} or {fire}
{neb_log} value = file where NEB statistics are printed :pre
:ule
[Examples:]
tad 2000 50 1800 2300 0.01 0.01 event
tad 2000 50 1800 2300 0.01 0.01 event &
min 1e-05 1e-05 100 100 &
neb 0.0 0.01 200 200 20 &
min_style cg &
neb_style fire &
neb_log log.neb :pre
[Description:]
Run a temperature accelerated dynamics (TAD) simulation. This method
requires two or more partitions to perform NEB transition state
searches.
TAD is described in "this paper"_#Voter by Art Voter. It is a method
that uses accelerated dynamics at an elevated temperature to generate
results at a specified lower temperature. A good overview of
accelerated dynamics methods for such systems is given in "this review
paper"_#Voter2 from the same group. In general, these methods assume
that the long-time dynamics is dominated by infrequent events i.e. the
system is is confined to low energy basins for long periods,
punctuated by brief, randomly-occurring transitions to adjacent
basins. TAD is suitable for infrequent-event systems, where in
addition, the transition kinetics are well-approximated by harmonic
transition state theory (hTST). In hTST, the temperature dependence of
transition rates follows the Arrhenius relation. As a consequence a
set of event times generated in a high-temperature simulation can be
mapped to a set of much longer estimated times in the low-temperature
system. However, because this mapping involves the energy barrier of
the transition event, which is different for each event, the first
event at the high temperature may not be the earliest event at the low
temperature. TAD handles this by first generating a set of possible
events from the current basin. After each event, the simulation is
reflected backwards into the current basin. This is repeated until
the stopping criterion is satisfied, at which point the event with the
earliest low-temperature occurrence time is selected. The stopping
criterion is that the confidence measure be greater than
1-{delta}. The confidence measure is the probability that no earlier
low-temperature event will occur at some later time in the
high-temperature simulation. hTST provides an lower bound for this
probability, based on the user-specified minimum pre-exponential
factor (reciprocal of {tmax}).
In order to estimate the energy barrier for each event, the TAD method
invokes the "NEB"_neb.html method. Each NEB replica runs on a
partition of processors. The current NEB implementation in LAMMPS
restricts you to having exactly one processor per replica. For more
information, see the documentation for the "neb"_neb.html command. In
the current LAMMPS implementation of TAD, all the non-NEB TAD
operations are performed on the first partition, while the other
-partitions remain idle. See "this section"_Section_howto.html#howto_5
-of the manual for further discussion of multi-replica simulations.
+partitions remain idle. See "Section_howto
+5"_Section_howto.html#howto_5 of the manual for further discussion of
+multi-replica simulations.
A TAD run has several stages, which are repeated each time an event is
performed. The logic for a TAD run is as follows:
while (time remains):
while (time < tstop):
until (event occurs):
run dynamics for t_event steps
quench
run neb calculation using all replicas
compute tlo from energy barrier
update earliest event
update tstop
reflect back into current basin
execute earliest event :pre
Before this outer loop begins, the initial potential energy basin is
identified by quenching (an energy minimization, see below) the
initial state and storing the resulting coordinates for reference.
Inside the inner loop, dynamics is run continuously according to
whatever integrator has been specified by the user, stopping every
{t_event} steps to check if a transition event has occurred. This
check is performed by quenching the system and comparing the resulting
atom coordinates to the coordinates from the previous basin.
A quench is an energy minimization and is performed by whichever
algorithm has been defined by the {min} and {min_style} keywords or
their default values. Note that typically, you do not need to perform
a highly-converged minimization to detect a transition event.
The event check is performed by a compute with the specified
{compute-ID}. Currently there is only one compute that works with the
TAD commmand, which is the "compute
event/displace"_compute_event_displace.html command. Other
event-checking computes may be added. "Compute
event/displace"_compute_event_displace.html checks whether any atom in
the compute group has moved further than a specified threshold
distance. If so, an "event" has occurred.
The neb calculation is similar to that invoked by the "neb"_neb.html
command, except that the final state is generated internally, instead
of being read in from a file. The TAD implementation provides default
values for the NEB settings, which can be overridden using the {neb}
and {neb_style} keywords.
:line
A key aspect of the TAD method is setting the stopping criterion
appropriately. If this criterion is too conservative, then many
events must be generated before one is finally executed. Conversely,
if this criterion is too aggressive, high-entropy high-barrier events
will be over-sampled, while low-entropy low-barrier events will be
under-sampled. If the lowest pre-exponential factor is known fairly
accurately, then it can be used to estimate {tmax}, and the value of
{delta} can be set to the desired confidence level e.g. {delta} = 0.05
corresponds to 95% confidence. However, for systems where the dynamics
are not well characterized (the most common case), it will be
necessary to experiment with the values of {delta} and {tmax} to get a
good trade-off between accuracy and performance.
A second key aspect is the choice of {t_hi}. A larger value greatly
increases the rate at which new events are generated. However, too
large a value introduces errors due to anharmonicity (not accounted
for within hTST). Once again, for any given system, experimentation is
necessary to determine the best value of {t_hi}.
:line
Five kinds of output can be generated during a TAD run: event
statistics, NEB statistics, thermodynamic output by each replica, dump
files, and restart files.
Event statistics are printed to the screen and master log.lammps file
each time an event is executed. The quantities are the timestep, CPU
time, global event number {N}, local event number {M}, event status,
energy barrier, time margin, {t_lo} and {delt_lo}. The timestep is
the usual LAMMPS timestep, which corresponds to the high-temperature
time at which the event was detected, in units of timestep. The CPU
time is the total processor time since the start of the TAD run. The
global event number {N} is a counter that increments with each
executed event. The local event number {M} is a counter that resets to
zero upon entering each new basin. The event status is {E} when an
event is executed, and is {D} for an event that is detected, while
{DF} is for a detected event that is also the earliest (first) event
at the low temperature.
The time margin is the ratio of the high temperature time in the
current basin to the stopping time. This last number can be used to
judge whether the stopping time is too short or too long (see above).
{t_lo} is the low-temperature event time when the current basin was
entered, in units of timestep. del{t_lo} is the time of each detected
event, measured relative to {t_lo}. {delt_lo} is equal to the
high-temperature time since entering the current basin, scaled by an
exponential factor that depends on the hi/lo temperature ratio and the
energy barrier for that event.
On lines for executed events, with status {E}, the global event number
is incremented by one,
the local event number and time margin are reset to zero,
while the global event number, energy barrier, and
{delt_lo} match the last event with status {DF}
in the immediately preceding block of detected events.
The low-temperature event time {t_lo} is incremented by {delt_lo}.
The NEB statistics are written to the file specified by the {neb_log}
keyword. If the keyword value is "none", then no NEB statistics are
printed out. The statistics are written every {Nevery} timesteps. See
the "neb"_neb.html command for a full description of the NEB
statistics. When invoked from TAD, NEB statistics are never printed to
the screen.
Because the NEB calculation must run on multiple partitions, LAMMPS
produces additional screen and log files for each partition,
e.g. log.lammps.0, log.lammps.1, etc. For the TAD command, these
contain the thermodynamic output of each NEB replica. In addition, the
log file for the first partition, log.lammps.0, will contain
thermodynamic output from short runs and minimizations corresponding
to the dynamics and quench operations, as well as a line for each new
detected event, as described above.
After the TAD command completes, timing statistics for the TAD run are
printed in each replica's log file, giving a breakdown of how much CPU
time was spent in each stage (NEB, dynamics, quenching, etc).
Any "dump files"_dump.html defined in the input script will be written
to during a TAD run at timesteps when an event is executed. This
means the the requested dump frequency in the "dump"_dump.html command
is ignored. There will be one dump file (per dump command) created
for all partitions. The atom coordinates of the dump snapshot are
those of the minimum energy configuration resulting from quenching
following the executed event. The timesteps written into the dump
files correspond to the timestep at which the event occurred and NOT
the clock. A dump snapshot corresponding to the initial minimum state
used for event detection is written to the dump file at the beginning
of each TAD run.
If the "restart"_restart.html command is used, a single restart file
for all the partitions is generated, which allows a TAD run to be
continued by a new input script in the usual manner. The restart file
is generated after an event is executed. The restart file contains a
snapshot of the system in the new quenched state, including the event
number and the low-temperature time. The restart frequency specified
in the "restart"_restart.html command is interpreted differently when
performing a TAD run. It does not mean the timestep interval between
restart files. Instead it means an event interval for executed
events. Thus a frequency of 1 means write a restart file every time
an event is executed. A frequency of 10 means write a restart file
every 10th executed event. When an input script reads a restart file
from a previous TAD run, the new script can be run on a different
number of replicas or processors.
Note that within a single state, the dynamics will typically
temporarily continue beyond the event that is ultimately chosen, until
the stopping criterionis satisfied. When the event is eventually
executed, the timestep counter is reset to the value when the event
was detected. Similarly, after each quench and NEB minimization, the
timestep counter is reset to the value at the start of the
minimization. This means that the timesteps listed in the replica log
files do not always increase monotonically. However, the timestep
values printed to the master log file, dump files, and restart files
are always monotonically increasing.
:line
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
{N} setting must be integer multiple of {t_event}.
Runs restarted from restart files written during a TAD run will only
produce identical results if the user-specified integrator supports
exact restarts. So "fix nvt"_fix_nh.html will produce an exact
restart, but "fix langevin"_fix_langevin.html will not.
This command cannot be used when any fixes are defined that keep track
of elapsed time to perform time-dependent operations. Examples
include the "ave" fixes such as "fix
ave/spatial"_fix_ave_spatial.html. Also "fix
dt/reset"_fix_dt_reset.html and "fix deposit"_fix_deposit.html.
[Related commands:]
"compute event/displace"_compute_event_displace.html,
"min_modify"_min_modify.html, "min_style"_min_style.html,
"run_style"_run_style.html, "minimize"_minimize.html,
"temper"_temper.html, "neb"_neb.html,
"prd"_prd.html
[Default:]
The option defaults are {min} = 0.1 0.1 40 50, {neb} = 0.01 100 100
10, {min_style} = {cg}, {neb_style} = {quickmin}, and {neb_log} =
"none"
:line
:link(Voter)
[(Voter)] Sørensen and Voter, J Chem Phys, 112, 9599 (2000)
:link(Voter2)
[(Voter2)] Voter, Montalenti, Germann, Annual Review of Materials
Research 32, 321 (2002).
diff --git a/doc/temper.html b/doc/temper.html
index 514db7886..01157902a 100644
--- a/doc/temper.html
+++ b/doc/temper.html
@@ -1,137 +1,137 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>temper command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>temper N M temp fix-ID seed1 seed2 index
</PRE>
<UL><LI>N = total # of timesteps to run
<LI>M = attempt a tempering swap every this many steps
<LI>temp = initial temperature for this ensemble
<LI>fix-ID = ID of the fix that will control temperature during the run
<LI>seed1 = random # seed used to decide on adjacent temperature to partner with
<LI>seed2 = random # seed for Boltzmann factor in Metropolis swap
<LI>index = which temperature (0 to N-1) I am simulating (optional)
</UL>
<P><B>Examples:</B>
</P>
<PRE>temper 100000 100 $t tempfix 0 58728
temper 40000 100 $t tempfix 0 32285 $w
</PRE>
<P><B>Description:</B>
</P>
<P>Run a parallel tempering or replica exchange simulation using multiple
replicas (ensembles) of a system. Two or more replicas must be used.
</P>
<P>Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see <A HREF = "Section_start.html#start_6">this section</A> of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. You will simply not get the performance speed-up you
+switch; see <A HREF = "Section_start.html#start_6">Section_start 6</A> of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. You will simply not get the performance speed-up you
would see with one or more physical processors per replica. See <A HREF = "Section_howto.html#howto_5">this
section</A> of the manual for further
discussion.
</P>
<P>Each replica's temperature is controlled at a different value by a fix
with <I>fix-ID</I> that controls temperature. Possible fix styles are
<A HREF = "fix_nh.html">nvt</A>, <A HREF = "fix_nh.html">temp/berendsen</A>,
<A HREF = "fix_langevin.html">langevin</A> and <A HREF = "fix_temp_rescale.html">temp/rescale</A>.
The desired temperature is specified by <I>temp</I>, which is typically a
variable previously set in the input script, so that each partition is
assigned a different temperature. See the <A HREF = "variable.html">variable</A>
command for more details. For example:
</P>
<PRE>variable t world 300.0 310.0 320.0 330.0
fix myfix all nvt $t $t 100.0
temper 100000 100 $t myfix 3847 58382
</PRE>
<P>would define 4 temperatures, and assign one of them to the thermostat
used by each replica, and to the temper command.
</P>
<P>As the tempering simulation runs for <I>N</I> timesteps, a temperature swap
between adjacent ensembles will be attempted every <I>M</I> timesteps. If
<I>seed1</I> is 0, then the swap attempts will alternate between odd and
even pairings. If <I>seed1</I> is non-zero then it is used as a seed in a
random number generator to randomly choose an odd or even pairing each
time. Each attempted swap of temperatures is either accepted or
rejected based on a Boltzmann-weighted Metropolis criterion which uses
<I>seed2</I> in the random number generator.
</P>
<P>As a tempering run proceeds, multiple log files and screen output
files are created, one per replica. By default these files are named
log.lammps.M and screen.M where M is the replica number from 0 to N-1,
with N = # of replicas. See the <A HREF = "Section_start.html#start_6">section on command-line
switches</A> for info on how to change these
names.
</P>
<P>The main screen and log file (log.lammps) will list information about
which temperature is assigned to each replica at each thermodynamic
output timestep. E.g. for a simulation with 16 replicas:
</P>
<PRE>Running on 16 partitions of processors
Step T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
500 1 0 3 2 5 4 6 7 8 9 10 11 12 13 14 15
1000 2 0 4 1 5 3 6 7 8 9 10 11 12 14 13 15
1500 2 1 4 0 5 3 6 7 9 8 10 11 12 14 13 15
2000 2 1 3 0 6 4 5 7 10 8 9 11 12 14 13 15
2500 2 1 3 0 6 4 5 7 11 8 9 10 12 14 13 15
...
</PRE>
<P>The column headings T0 to TN-1 mean which temperature is currently
assigned to the replica 0 to N-1. Thus the columns represent replicas
and the value in each column is its temperature (also numbered 0 to
N-1). For example, a 0 in the 4th column (column T3, step 2500) means
that the 4th replica is assigned temperature 0, i.e. the lowest
temperature. You can verify this time sequence of temperature
assignments for the Nth replica by comparing the Nth column of screen
output to the thermodynamic data in the corresponding log.lammps.N or
screen.N files as time proceeds.
</P>
<P>The last argument <I>index</I> in the temper command is optional and is
used when restarting a tempering run from a set of restart files (one
for each replica) which had previously swapped to new temperatures.
The <I>index</I> value (from 0 to N-1, where N is the # of replicas)
identifies which temperature the replica was simulating on the
timestep the restart files were written. Obviously, this argument
must be a variable so that each partition has the correct value. Set
the variable to the <I>N</I> values listed in the log file for the previous
run for the replica temperatures at that timestep. For example if the
log file listed the following for a simulation with 5 replicas:
</P>
<PRE>500000 2 4 0 1 3
</PRE>
<P>then a setting of
</P>
<PRE>variable w world 2 4 0 1 3
</PRE>
<P>would be used to restart the run with a tempering command like the
example above with $w as the last argument.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command can only be used if LAMMPS was built with the REPLICA
package. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info on packages.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "variable.html">variable</A>, <A HREF = "prd.html">prd</A>, <A HREF = "neb.html">neb</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/temper.txt b/doc/temper.txt
index 70f1e2f0d..803c505cd 100644
--- a/doc/temper.txt
+++ b/doc/temper.txt
@@ -1,132 +1,132 @@
"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
temper command :h3
[Syntax:]
temper N M temp fix-ID seed1 seed2 index :pre
N = total # of timesteps to run
M = attempt a tempering swap every this many steps
temp = initial temperature for this ensemble
fix-ID = ID of the fix that will control temperature during the run
seed1 = random # seed used to decide on adjacent temperature to partner with
seed2 = random # seed for Boltzmann factor in Metropolis swap
index = which temperature (0 to N-1) I am simulating (optional) :ul
[Examples:]
temper 100000 100 $t tempfix 0 58728
temper 40000 100 $t tempfix 0 32285 $w :pre
[Description:]
Run a parallel tempering or replica exchange simulation using multiple
replicas (ensembles) of a system. Two or more replicas must be used.
Each replica runs on a partition of one or more processors. Processor
partitions are defined at run-time using the -partition command-line
-switch; see "this section"_Section_start.html#start_6 of the manual.
-Note that if you have MPI installed, you can run a multi-replica
-simulation with more replicas (partitions) than you have physical
-processors, e.g you can run a 10-replica simulation on one or two
-processors. You will simply not get the performance speed-up you
+switch; see "Section_start 6"_Section_start.html#start_6 of the
+manual. Note that if you have MPI installed, you can run a
+multi-replica simulation with more replicas (partitions) than you have
+physical processors, e.g you can run a 10-replica simulation on one or
+two processors. You will simply not get the performance speed-up you
would see with one or more physical processors per replica. See "this
section"_Section_howto.html#howto_5 of the manual for further
discussion.
Each replica's temperature is controlled at a different value by a fix
with {fix-ID} that controls temperature. Possible fix styles are
"nvt"_fix_nh.html, "temp/berendsen"_fix_nh.html,
"langevin"_fix_langevin.html and "temp/rescale"_fix_temp_rescale.html.
The desired temperature is specified by {temp}, which is typically a
variable previously set in the input script, so that each partition is
assigned a different temperature. See the "variable"_variable.html
command for more details. For example:
variable t world 300.0 310.0 320.0 330.0
fix myfix all nvt $t $t 100.0
temper 100000 100 $t myfix 3847 58382 :pre
would define 4 temperatures, and assign one of them to the thermostat
used by each replica, and to the temper command.
As the tempering simulation runs for {N} timesteps, a temperature swap
between adjacent ensembles will be attempted every {M} timesteps. If
{seed1} is 0, then the swap attempts will alternate between odd and
even pairings. If {seed1} is non-zero then it is used as a seed in a
random number generator to randomly choose an odd or even pairing each
time. Each attempted swap of temperatures is either accepted or
rejected based on a Boltzmann-weighted Metropolis criterion which uses
{seed2} in the random number generator.
As a tempering run proceeds, multiple log files and screen output
files are created, one per replica. By default these files are named
log.lammps.M and screen.M where M is the replica number from 0 to N-1,
with N = # of replicas. See the "section on command-line
switches"_Section_start.html#start_6 for info on how to change these
names.
The main screen and log file (log.lammps) will list information about
which temperature is assigned to each replica at each thermodynamic
output timestep. E.g. for a simulation with 16 replicas:
Running on 16 partitions of processors
Step T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
500 1 0 3 2 5 4 6 7 8 9 10 11 12 13 14 15
1000 2 0 4 1 5 3 6 7 8 9 10 11 12 14 13 15
1500 2 1 4 0 5 3 6 7 9 8 10 11 12 14 13 15
2000 2 1 3 0 6 4 5 7 10 8 9 11 12 14 13 15
2500 2 1 3 0 6 4 5 7 11 8 9 10 12 14 13 15
... :pre
The column headings T0 to TN-1 mean which temperature is currently
assigned to the replica 0 to N-1. Thus the columns represent replicas
and the value in each column is its temperature (also numbered 0 to
N-1). For example, a 0 in the 4th column (column T3, step 2500) means
that the 4th replica is assigned temperature 0, i.e. the lowest
temperature. You can verify this time sequence of temperature
assignments for the Nth replica by comparing the Nth column of screen
output to the thermodynamic data in the corresponding log.lammps.N or
screen.N files as time proceeds.
The last argument {index} in the temper command is optional and is
used when restarting a tempering run from a set of restart files (one
for each replica) which had previously swapped to new temperatures.
The {index} value (from 0 to N-1, where N is the # of replicas)
identifies which temperature the replica was simulating on the
timestep the restart files were written. Obviously, this argument
must be a variable so that each partition has the correct value. Set
the variable to the {N} values listed in the log file for the previous
run for the replica temperatures at that timestep. For example if the
log file listed the following for a simulation with 5 replicas:
500000 2 4 0 1 3 :pre
then a setting of
variable w world 2 4 0 1 3 :pre
would be used to restart the run with a tempering command like the
example above with $w as the last argument.
:line
[Restrictions:]
This command can only be used if LAMMPS was built with the REPLICA
package. See the "Making LAMMPS"_Section_start.html#start_3 section
for more info on packages.
[Related commands:]
"variable"_variable.html, "prd"_prd.html, "neb"_neb.html
[Default:] none
diff --git a/doc/thermo_style.html b/doc/thermo_style.html
index 3c5844354..8641eb138 100644
--- a/doc/thermo_style.html
+++ b/doc/thermo_style.html
@@ -1,324 +1,324 @@
<HTML>
<CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A>
</CENTER>
<HR>
<H3>thermo_style command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>thermo_style style args
</PRE>
<UL><LI>style = <I>one</I> or <I>multi</I> or <I>custom</I>
<LI>args = list of arguments for a particular style
<PRE> <I>one</I> args = none
<I>multi</I> args = none
<I>custom</I> args = list of attributes
possible attributes = step, elapsed, elaplong, dt, cpu, tpcpu, spcpu,
atoms, temp, press, pe, ke, etotal, enthalpy,
evdwl, ecoul, epair, ebond, eangle, edihed, eimp,
emol, elong, etail,
vol, lx, ly, lz, xlo, xhi, ylo, yhi, zlo, zhi,
xy, xz, yz, xlat, ylat, zlat,
pxx, pyy, pzz, pxy, pxz, pyz,
fmax, fnorm,
cella, cellb, cellc, cellalpha, cellbeta, cellgamma,
c_ID, c_ID[I], c_ID[I][J],
f_ID, f_ID[I], f_ID[I][J],
v_name
step = timestep
elapsed = timesteps since start of this run
elaplong = timesteps since start of initial run in a series of runs
dt = timestep size
cpu = elapsed CPU time in seconds
tpcpu = time per CPU second
spcpu = timesteps per CPU second
atoms = # of atoms
temp = temperature
press = pressure
pe = total potential energy
ke = kinetic energy
etotal = total energy (pe + ke)
enthalpy = enthalpy (etotal + press*vol)
evdwl = VanderWaal pairwise energy
ecoul = Coulombic pairwise energy
epair = pairwise energy (evdwl + ecoul + elong + etail)
ebond = bond energy
eangle = angle energy
edihed = dihedral energy
eimp = improper energy
emol = molecular energy (ebond + eangle + edihed + eimp)
elong = long-range kspace energy
etail = VanderWaal energy long-range tail correction
vol = volume
lx,ly,lz = box lengths in x,y,z
xlo,xhi,ylo,yhi,zlo,zhi = box boundaries
xy,xz,yz = box tilt for triclinic (non-orthogonal) simulation boxes
xlat,ylat,zlat = lattice spacings as calculated by <A HREF = "lattice.html">lattice</A> command
pxx,pyy,pzz,pxy,pxz,pyz = 6 components of pressure tensor
fmax = max component of force on any atom in any dimension
fnorm = length of force vector for all atoms
cella,cellb,cellc = periodic cell lattice constants a,b,c
cellalpha, cellbeta, cellgamma = periodic cell angles alpha,beta,gamma
c_ID = global scalar value calculated by a compute with ID
c_ID[I] = Ith component of global vector calculated by a compute with ID
c_ID[I][J] = I,J component of global array calculated by a compute with ID
f_ID = global scalar value calculated by a fix with ID
f_ID[I] = Ith component of global vector calculated by a fix with ID
f_ID[I][J] = I,J component of global array calculated by a fix with ID
v_name = scalar value calculated by an equal-style variable with name
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>thermo_style multi
thermo_style custom step temp pe etotal press vol
thermo_style custom step temp etotal c_myTemp v_abc
</PRE>
<P><B>Description:</B>
</P>
<P>Set the style and content for printing thermodynamic data to the
screen and log file.
</P>
<P>Style <I>one</I> prints a one-line summary of thermodynamic info that is
the equivalent of "thermo_style custom step temp epair emol etotal
press". The line contains only numeric values.
</P>
<P>Style <I>multi</I> prints a multiple-line listing of thermodynamic info
that is the equivalent of "thermo_style custom etotal ke temp pe ebond
eangle edihed eimp evdwl ecoul elong press". The listing contains
numeric values and a string ID for each quantity.
</P>
<P>Style <I>custom</I> is the most general setting and allows you to specify
which of the keywords listed above you want printed on each
thermodynamic timestep. Note that the keywords c_ID, f_ID, v_name are
references to <A HREF = "compute.html">computes</A>, <A HREF = "fix.html">fixes</A>, and
equal-style <A HREF = "variable.html"">variables</A> that have been defined
elsewhere in the input script or can even be new styles which users
have added to LAMMPS (see the <A HREF = "Section_modify.html">Section_modify</A>
section of the documentation). Thus the <I>custom</I> style provides a
flexible means of outputting essentially any desired quantity as a
simulation proceeds.
</P>
<P>All styles except <I>custom</I> have <I>vol</I> appended to their list of
outputs if the simulation box volume changes during the simulation.
</P>
<P>The values printed by the various keywords are instantaneous values,
calculated on the current timestep. Time-averaged quantities, which
include values from previous timesteps, can be output by using the
f_ID keyword and accessing a fix that does time-averaging such as the
<A HREF = "fix_ave_time.html">fix ave/time</A> command.
</P>
<P>Options invoked by the <A HREF = "thermo_modify.html">thermo_modify</A> command can
be used to set the one- or multi-line format of the print-out, the
normalization of thermodynamic output (total values versus per-atom
values for extensive quantities (ones which scale with the number of
atoms in the system), and the numeric precision of each printed value.
</P>
<P>IMPORTANT NOTE: When you use a "thermo_style" command, all
thermodynamic settings are restored to their default values, including
those previously set by a <A HREF = "thermo_modify.html">thermo_modify</A> command.
Thus if your input script specifies a thermo_style command, you should
use the thermo_modify command after it.
</P>
<HR>
<P>Several of the thermodynamic quantities require a temperature to be
computed: "temp", "press", "ke", "etotal", "enthalpy", "pxx", etc. By
default this is done by using a <I>temperature</I> compute which is created
when LAMMPS starts up, as if this command had been issued:
</P>
<PRE>compute thermo_temp all temp
</PRE>
<P>See the <A HREF = "compute_temp.html">compute temp</A> command for details. Note
that the ID of this compute is <I>thermo_temp</I> and the group is <I>all</I>.
You can change the attributes of this temperature (e.g. its
degrees-of-freedom) via the <A HREF = "compute_modify.html">compute_modify</A>
command. Alternatively, you can directly assign a new compute (that
calculates temperature) which you have defined, to be used for
calculating any thermodynamic quantity that requires a temperature.
This is done via the <A HREF = "thermo_modify.html">thermo_modify</A> command.
</P>
<P>Several of the thermodynamic quantities require a pressure to be
computed: "press", "enthalpy", "pxx", etc. By default this is done by
using a <I>pressure</I> compute which is created when LAMMPS starts up, as
if this command had been issued:
</P>
<PRE>compute thermo_press all pressure thermo_temp
</PRE>
<P>See the <A HREF = "compute_pressure.html">compute pressure</A> command for details.
Note that the ID of this compute is <I>thermo_press</I> and the group is
<I>all</I>. You can change the attributes of this pressure via the
<A HREF = "compute_modify.html">compute_modify</A> command. Alternatively, you can
directly assign a new compute (that calculates pressure) which you
have defined, to be used for calculating any thermodynamic quantity
that requires a pressure. This is done via the
<A HREF = "thermo_modify.html">thermo_modify</A> command.
</P>
<P>Several of the thermodynamic quantities require a potential energy to
be computed: "pe", "etotal", "ebond", etc. This is done by using a
<I>pe</I> compute which is created when LAMMPS starts up, as if this
command had been issued:
</P>
<PRE>compute thermo_pe all pe
</PRE>
<P>See the <A HREF = "compute_pe.html">compute pe</A> command for details. Note that
the ID of this compute is <I>thermo_pe</I> and the group is <I>all</I>. You can
change the attributes of this potential energy via the
<A HREF = "compute_modify.html">compute_modify</A> command.
</P>
<HR>
<P>The kinetic energy of the system <I>ke</I> is inferred from the temperature
of the system with 1/2 Kb T of energy for each degree of freedom.
Thus, using different <A HREF = "compute.html">compute commands</A> for calculating
temperature, via the <A HREF = "thermo_modify.html">thermo_modify temp</A> command,
may yield different kinetic energies, since different computes that
calculate temperature can subtract out different non-thermal
components of velocity and/or include different degrees of freedom
(translational, rotational, etc).
</P>
<P>The potential energy of the system <I>pe</I> will include contributions
from fixes if the <A HREF = "fix_modify.html">fix_modify thermo</A> option is set
for a fix that calculates such a contribution. For example, the <A HREF = "fix_wall.html">fix
wall/lj93</A> fix calculates the energy of atoms
interacting with the wall. See the doc pages for "individual fixes"
to see which ones contribute.
</P>
<P>A long-range tail correction <I>etail</I> for the VanderWaal pairwise
energy will be non-zero only if the <A HREF = "pair_modify.html">pair_modify
tail</A> option is turned on. The <I>etail</I> contribution
is included in <I>evdwl</I>, <I>pe</I>, and <I>etotal</I>, and the corresponding tail
correction to the pressure is included in <I>press</I> and <I>pxx</I>, <I>pyy</I>,
etc.
</P>
<HR>
<P>The <I>step</I>, <I>elapsed</I>, and <I>elaplong</I> keywords refer to timestep
count. <I>Step</I> is the current timestep, or iteration count when a
<A HREF = "minimize.html">minimization</A> is being performed. <I>Elapsed</I> is the
number of timesteps elapsed since the beginning of this run.
<I>Elaplong</I> is the number of timesteps elapsed since the beginning of
an initial run in a series of runs. See the <I>start</I> and <I>stop</I>
keywords for the <A HREF = "run.html">run</A> for info on how to invoke a series of
runs that keep track of an initial starting time. If these keywords
are not used, then <I>elapsed</I> and <I>elaplong</I> are the same value.
</P>
<P>The <I>cpu</I> keyword is elapsed CPU seconds since the beginning of this
run. The <I>tpcpu</I> and <I>spcpu</I> keywords are measures of how fast your
simulation is currently running. The <I>tpcpu</I> keyword is simulation
time per CPU second, where simulation time is in time
<A HREF = "units.html">units</A>. E.g. for metal units, the <I>tpcpu</I> value would be
picoseconds per CPU second. The <I>spcpu</I> keyword is the number of
timesteps per CPU second. Both quantities are on-the-fly metrics,
measured relative to the last time they were invoked. Thus if you are
printing out thermodyamic output every 100 timesteps, the two keywords
will continually output the time and timestep rate for the last 100
steps. The <I>tpcpu</I> keyword does not attempt to track any changes in
timestep size, e.g. due to using the <A HREF = "fix_dt_reset.html">fix dt/reset</A>
command.
</P>
<P>The <I>fmax</I> and <I>fnorm</I> keywords are useful for monitoring the progress
of an <A HREF = "minimize.html">energy minimization</A>. The <I>fmax</I> keyword
calculates the maximum force in any dimension on any atom in the
system, or the infinity-norm of the force vector for the system. The
<I>fnorm</I> keyword calculates the 2-norm or length of the force vector.
</P>
<P>The keywords <I>cella</I>, <I>cellb</I>, <I>cellc</I>, <I>cellalpha</I>, <I>cellbeta</I>,
<I>cellgamma</I>, correspond to the usual crystallographic quantities that
define the periodic unit cell of a crystal. See <A HREF = "Section_howto.html#howto_12">this
section</A> of the doc pages for a geometric
description of triclinic periodic cells, including a precise defintion
of these quantities in terms of the internal LAMMPS cell dimensions
<I>lx</I>, <I>ly</I>, <I>lz</I>, <I>yz</I>, <I>xz</I>, <I>xy</I>,
</P>
<HR>
<P>The <I>c_ID</I> and <I>c_ID[I]</I> and <I>c_ID[I][J]</I> keywords allow global
values calculated by a compute to be output. As discussed on the
<A HREF = "compute.html">compute</A> doc page, computes can calculate global,
per-atom, or local values. Only global values can be referenced by
this command. However, per-atom compute values can be referenced in a
<A HREF = "variable.html">variable</A> and the variable referenced by thermo_style
custom, as discussed below.
</P>
<P>The ID in the keyword should be replaced by the actual ID of a compute
that has been defined elsewhere in the input script. See the
<A HREF = "compute.html">compute</A> command for details. If the compute calculates
a global scalar, vector, or array, then the keyword formats with 0, 1,
or 2 brackets will reference a scalar value from the compute.
</P>
<P>Note that some computes calculate "intensive" global quantities like
temperature; others calculate "extensive" global quantities like
kinetic energy that are summed over all atoms in the compute group.
Intensive quantities are printed directly without normalization by
thermo_style custom. Extensive quantities may be normalized by the
total number of atoms in the simulation (NOT the number of atoms in
the compute group) when output, depending on the <A HREF = "thermo_modify.html">thermo_modify
norm</A> option being used.
</P>
<P>The <I>f_ID</I> and <I>f_ID[I]</I> and <I>f_ID[I][J]</I> keywords allow global
values calculated by a fix to be output. As discussed on the
<A HREF = "fix.html">fix</A> doc page, fixes can calculate global, per-atom, or
local values. Only global values can be referenced by this command.
However, per-atom fix values can be referenced in a
<A HREF = "variable.html">variable</A> and the variable referenced by thermo_style
custom, as discussed below.
</P>
<P>The ID in the keyword should be replaced by the actual ID of a fix
that has been defined elsewhere in the input script. See the
<A HREF = "fix.html">fix</A> command for details. If the fix calculates a global
scalar, vector, or array, then the keyword formats with 0, 1, or 2
brackets will reference a scalar value from the fix.
</P>
<P>Note that some fixes calculate "intensive" global quantities like
timestep size; others calculate "extensive" global quantities like
energy that are summed over all atoms in the fix group. Intensive
quantities are printed directly without normalization by thermo_style
custom. Extensive quantities may be normalized by the total number of
atoms in the simulation (NOT the number of atoms in the fix group)
when output, depending on the <A HREF = "thermo_modify.html">thermo_modify norm</A>
option being used.
</P>
<P>The <I>v_name</I> keyword allow the current value of a variable to be
output. The name in the keyword should be replaced by the variable
name that has been defined elsewhere in the input script. Only
equal-style variables can be referenced. See the
<A HREF = "variable.html">variable</A> command for details. Variables of style
<I>equal</I> can reference per-atom properties or thermodynamic keywords,
or they can invoke other computes, fixes, or variables when evaluated,
so this is a very general means of creating thermodynamic output.
</P>
-<P>See <A HREF = "Section_modify.html">this section</A> for information on how to add
+<P>See <A HREF = "Section_modify.html">Section_modify</A> for information on how to add
new compute and fix styles to LAMMPS to calculate quantities that can
then be referenced with these keywords to generate thermodynamic
output.
</P>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command must come after the simulation box is defined by a
<A HREF = "read_data.html">read_data</A>, <A HREF = "read_restart.html">read_restart</A>, or
<A HREF = "create_box.html">create_box</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "thermo.html">thermo</A>, <A HREF = "thermo_modify.html">thermo_modify</A>,
<A HREF = "fix_modify.html">fix_modify</A>, <A HREF = "compute_temp.html">compute temp</A>,
<A HREF = "compute_pressure.html">compute pressure</A>
</P>
<P><B>Default:</B>
</P>
<PRE>thermo_style one
</PRE>
</HTML>
diff --git a/doc/thermo_style.txt b/doc/thermo_style.txt
index 8f4a64148..0e77cb728 100644
--- a/doc/thermo_style.txt
+++ b/doc/thermo_style.txt
@@ -1,316 +1,316 @@
"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
thermo_style command :h3
[Syntax:]
thermo_style style args :pre
style = {one} or {multi} or {custom} :ulb,l
args = list of arguments for a particular style :l
{one} args = none
{multi} args = none
{custom} args = list of attributes
possible attributes = step, elapsed, elaplong, dt, cpu, tpcpu, spcpu,
atoms, temp, press, pe, ke, etotal, enthalpy,
evdwl, ecoul, epair, ebond, eangle, edihed, eimp,
emol, elong, etail,
vol, lx, ly, lz, xlo, xhi, ylo, yhi, zlo, zhi,
xy, xz, yz, xlat, ylat, zlat,
pxx, pyy, pzz, pxy, pxz, pyz,
fmax, fnorm,
cella, cellb, cellc, cellalpha, cellbeta, cellgamma,
c_ID, c_ID\[I\], c_ID\[I\]\[J\],
f_ID, f_ID\[I\], f_ID\[I\]\[J\],
v_name
step = timestep
elapsed = timesteps since start of this run
elaplong = timesteps since start of initial run in a series of runs
dt = timestep size
cpu = elapsed CPU time in seconds
tpcpu = time per CPU second
spcpu = timesteps per CPU second
atoms = # of atoms
temp = temperature
press = pressure
pe = total potential energy
ke = kinetic energy
etotal = total energy (pe + ke)
enthalpy = enthalpy (etotal + press*vol)
evdwl = VanderWaal pairwise energy
ecoul = Coulombic pairwise energy
epair = pairwise energy (evdwl + ecoul + elong + etail)
ebond = bond energy
eangle = angle energy
edihed = dihedral energy
eimp = improper energy
emol = molecular energy (ebond + eangle + edihed + eimp)
elong = long-range kspace energy
etail = VanderWaal energy long-range tail correction
vol = volume
lx,ly,lz = box lengths in x,y,z
xlo,xhi,ylo,yhi,zlo,zhi = box boundaries
xy,xz,yz = box tilt for triclinic (non-orthogonal) simulation boxes
xlat,ylat,zlat = lattice spacings as calculated by "lattice"_lattice.html command
pxx,pyy,pzz,pxy,pxz,pyz = 6 components of pressure tensor
fmax = max component of force on any atom in any dimension
fnorm = length of force vector for all atoms
cella,cellb,cellc = periodic cell lattice constants a,b,c
cellalpha, cellbeta, cellgamma = periodic cell angles alpha,beta,gamma
c_ID = global scalar value calculated by a compute with ID
c_ID\[I\] = Ith component of global vector calculated by a compute with ID
c_ID\[I\]\[J\] = I,J component of global array calculated by a compute with ID
f_ID = global scalar value calculated by a fix with ID
f_ID\[I\] = Ith component of global vector calculated by a fix with ID
f_ID\[I\]\[J\] = I,J component of global array calculated by a fix with ID
v_name = scalar value calculated by an equal-style variable with name :pre
:ule
[Examples:]
thermo_style multi
thermo_style custom step temp pe etotal press vol
thermo_style custom step temp etotal c_myTemp v_abc :pre
[Description:]
Set the style and content for printing thermodynamic data to the
screen and log file.
Style {one} prints a one-line summary of thermodynamic info that is
the equivalent of "thermo_style custom step temp epair emol etotal
press". The line contains only numeric values.
Style {multi} prints a multiple-line listing of thermodynamic info
that is the equivalent of "thermo_style custom etotal ke temp pe ebond
eangle edihed eimp evdwl ecoul elong press". The listing contains
numeric values and a string ID for each quantity.
Style {custom} is the most general setting and allows you to specify
which of the keywords listed above you want printed on each
thermodynamic timestep. Note that the keywords c_ID, f_ID, v_name are
references to "computes"_compute.html, "fixes"_fix.html, and
equal-style "variables"_variable.html" that have been defined
elsewhere in the input script or can even be new styles which users
have added to LAMMPS (see the "Section_modify"_Section_modify.html
section of the documentation). Thus the {custom} style provides a
flexible means of outputting essentially any desired quantity as a
simulation proceeds.
All styles except {custom} have {vol} appended to their list of
outputs if the simulation box volume changes during the simulation.
The values printed by the various keywords are instantaneous values,
calculated on the current timestep. Time-averaged quantities, which
include values from previous timesteps, can be output by using the
f_ID keyword and accessing a fix that does time-averaging such as the
"fix ave/time"_fix_ave_time.html command.
Options invoked by the "thermo_modify"_thermo_modify.html command can
be used to set the one- or multi-line format of the print-out, the
normalization of thermodynamic output (total values versus per-atom
values for extensive quantities (ones which scale with the number of
atoms in the system), and the numeric precision of each printed value.
IMPORTANT NOTE: When you use a "thermo_style" command, all
thermodynamic settings are restored to their default values, including
those previously set by a "thermo_modify"_thermo_modify.html command.
Thus if your input script specifies a thermo_style command, you should
use the thermo_modify command after it.
:line
Several of the thermodynamic quantities require a temperature to be
computed: "temp", "press", "ke", "etotal", "enthalpy", "pxx", etc. By
default this is done by using a {temperature} compute which is created
when LAMMPS starts up, as if this command had been issued:
compute thermo_temp all temp :pre
See the "compute temp"_compute_temp.html command for details. Note
that the ID of this compute is {thermo_temp} and the group is {all}.
You can change the attributes of this temperature (e.g. its
degrees-of-freedom) via the "compute_modify"_compute_modify.html
command. Alternatively, you can directly assign a new compute (that
calculates temperature) which you have defined, to be used for
calculating any thermodynamic quantity that requires a temperature.
This is done via the "thermo_modify"_thermo_modify.html command.
Several of the thermodynamic quantities require a pressure to be
computed: "press", "enthalpy", "pxx", etc. By default this is done by
using a {pressure} compute which is created when LAMMPS starts up, as
if this command had been issued:
compute thermo_press all pressure thermo_temp :pre
See the "compute pressure"_compute_pressure.html command for details.
Note that the ID of this compute is {thermo_press} and the group is
{all}. You can change the attributes of this pressure via the
"compute_modify"_compute_modify.html command. Alternatively, you can
directly assign a new compute (that calculates pressure) which you
have defined, to be used for calculating any thermodynamic quantity
that requires a pressure. This is done via the
"thermo_modify"_thermo_modify.html command.
Several of the thermodynamic quantities require a potential energy to
be computed: "pe", "etotal", "ebond", etc. This is done by using a
{pe} compute which is created when LAMMPS starts up, as if this
command had been issued:
compute thermo_pe all pe :pre
See the "compute pe"_compute_pe.html command for details. Note that
the ID of this compute is {thermo_pe} and the group is {all}. You can
change the attributes of this potential energy via the
"compute_modify"_compute_modify.html command.
:line
The kinetic energy of the system {ke} is inferred from the temperature
of the system with 1/2 Kb T of energy for each degree of freedom.
Thus, using different "compute commands"_compute.html for calculating
temperature, via the "thermo_modify temp"_thermo_modify.html command,
may yield different kinetic energies, since different computes that
calculate temperature can subtract out different non-thermal
components of velocity and/or include different degrees of freedom
(translational, rotational, etc).
The potential energy of the system {pe} will include contributions
from fixes if the "fix_modify thermo"_fix_modify.html option is set
for a fix that calculates such a contribution. For example, the "fix
wall/lj93"_fix_wall.html fix calculates the energy of atoms
interacting with the wall. See the doc pages for "individual fixes"
to see which ones contribute.
A long-range tail correction {etail} for the VanderWaal pairwise
energy will be non-zero only if the "pair_modify
tail"_pair_modify.html option is turned on. The {etail} contribution
is included in {evdwl}, {pe}, and {etotal}, and the corresponding tail
correction to the pressure is included in {press} and {pxx}, {pyy},
etc.
:line
The {step}, {elapsed}, and {elaplong} keywords refer to timestep
count. {Step} is the current timestep, or iteration count when a
"minimization"_minimize.html is being performed. {Elapsed} is the
number of timesteps elapsed since the beginning of this run.
{Elaplong} is the number of timesteps elapsed since the beginning of
an initial run in a series of runs. See the {start} and {stop}
keywords for the "run"_run.html for info on how to invoke a series of
runs that keep track of an initial starting time. If these keywords
are not used, then {elapsed} and {elaplong} are the same value.
The {cpu} keyword is elapsed CPU seconds since the beginning of this
run. The {tpcpu} and {spcpu} keywords are measures of how fast your
simulation is currently running. The {tpcpu} keyword is simulation
time per CPU second, where simulation time is in time
"units"_units.html. E.g. for metal units, the {tpcpu} value would be
picoseconds per CPU second. The {spcpu} keyword is the number of
timesteps per CPU second. Both quantities are on-the-fly metrics,
measured relative to the last time they were invoked. Thus if you are
printing out thermodyamic output every 100 timesteps, the two keywords
will continually output the time and timestep rate for the last 100
steps. The {tpcpu} keyword does not attempt to track any changes in
timestep size, e.g. due to using the "fix dt/reset"_fix_dt_reset.html
command.
The {fmax} and {fnorm} keywords are useful for monitoring the progress
of an "energy minimization"_minimize.html. The {fmax} keyword
calculates the maximum force in any dimension on any atom in the
system, or the infinity-norm of the force vector for the system. The
{fnorm} keyword calculates the 2-norm or length of the force vector.
The keywords {cella}, {cellb}, {cellc}, {cellalpha}, {cellbeta},
{cellgamma}, correspond to the usual crystallographic quantities that
define the periodic unit cell of a crystal. See "this
section"_Section_howto.html#howto_12 of the doc pages for a geometric
description of triclinic periodic cells, including a precise defintion
of these quantities in terms of the internal LAMMPS cell dimensions
{lx}, {ly}, {lz}, {yz}, {xz}, {xy},
:line
The {c_ID} and {c_ID\[I\]} and {c_ID\[I\]\[J\]} keywords allow global
values calculated by a compute to be output. As discussed on the
"compute"_compute.html doc page, computes can calculate global,
per-atom, or local values. Only global values can be referenced by
this command. However, per-atom compute values can be referenced in a
"variable"_variable.html and the variable referenced by thermo_style
custom, as discussed below.
The ID in the keyword should be replaced by the actual ID of a compute
that has been defined elsewhere in the input script. See the
"compute"_compute.html command for details. If the compute calculates
a global scalar, vector, or array, then the keyword formats with 0, 1,
or 2 brackets will reference a scalar value from the compute.
Note that some computes calculate "intensive" global quantities like
temperature; others calculate "extensive" global quantities like
kinetic energy that are summed over all atoms in the compute group.
Intensive quantities are printed directly without normalization by
thermo_style custom. Extensive quantities may be normalized by the
total number of atoms in the simulation (NOT the number of atoms in
the compute group) when output, depending on the "thermo_modify
norm"_thermo_modify.html option being used.
The {f_ID} and {f_ID\[I\]} and {f_ID\[I\]\[J\]} keywords allow global
values calculated by a fix to be output. As discussed on the
"fix"_fix.html doc page, fixes can calculate global, per-atom, or
local values. Only global values can be referenced by this command.
However, per-atom fix values can be referenced in a
"variable"_variable.html and the variable referenced by thermo_style
custom, as discussed below.
The ID in the keyword should be replaced by the actual ID of a fix
that has been defined elsewhere in the input script. See the
"fix"_fix.html command for details. If the fix calculates a global
scalar, vector, or array, then the keyword formats with 0, 1, or 2
brackets will reference a scalar value from the fix.
Note that some fixes calculate "intensive" global quantities like
timestep size; others calculate "extensive" global quantities like
energy that are summed over all atoms in the fix group. Intensive
quantities are printed directly without normalization by thermo_style
custom. Extensive quantities may be normalized by the total number of
atoms in the simulation (NOT the number of atoms in the fix group)
when output, depending on the "thermo_modify norm"_thermo_modify.html
option being used.
The {v_name} keyword allow the current value of a variable to be
output. The name in the keyword should be replaced by the variable
name that has been defined elsewhere in the input script. Only
equal-style variables can be referenced. See the
"variable"_variable.html command for details. Variables of style
{equal} can reference per-atom properties or thermodynamic keywords,
or they can invoke other computes, fixes, or variables when evaluated,
so this is a very general means of creating thermodynamic output.
-See "this section"_Section_modify.html for information on how to add
+See "Section_modify"_Section_modify.html for information on how to add
new compute and fix styles to LAMMPS to calculate quantities that can
then be referenced with these keywords to generate thermodynamic
output.
:line
[Restrictions:]
This command must come after the simulation box is defined by a
"read_data"_read_data.html, "read_restart"_read_restart.html, or
"create_box"_create_box.html command.
[Related commands:]
"thermo"_thermo.html, "thermo_modify"_thermo_modify.html,
"fix_modify"_fix_modify.html, "compute temp"_compute_temp.html,
"compute pressure"_compute_pressure.html
[Default:]
thermo_style one :pre
diff --git a/examples/USER/gauss-diel/data.gauss-diel b/examples/USER/gauss-diel/data.gauss-diel
new file mode 100644
index 000000000..a30685bc0
--- /dev/null
+++ b/examples/USER/gauss-diel/data.gauss-diel
@@ -0,0 +1,14134 @@
+LAMMPS description
+
+4200 atoms
+3600 bonds
+3300 angles
+3000 dihedrals
+
+4 atom types
+12 bond types
+11 angle types
+10 dihedral types
+
+-35.0 35.0 xlo xhi
+-35.0 35.0 ylo yhi
+-35.0 35.0 zlo zhi
+
+Masses
+
+1 4.1350 # HG
+2 0.6101 # CM
+3 0.6540 # CT
+4 1.0000 # CI
+
+Atoms
+
+1 1 1 -1.0000 8.5190 -20.7750 18.1210 # HG
+2 1 2 0.0000 7.9450 -20.3870 17.8340 # CM
+3 1 2 0.0000 8.0320 -19.8950 17.8200 # CM
+4 1 2 0.0000 7.6570 -19.6100 17.6530 # CM
+5 1 2 0.0000 7.7880 -19.1280 17.6270 # CM
+6 1 2 0.0000 7.3690 -18.8690 17.5420 # CM
+7 1 2 0.0000 7.4550 -18.3770 17.5650 # CM
+8 1 2 0.0000 7.0340 -18.1170 17.5010 # CM
+9 1 2 0.0000 7.1420 -17.6490 17.3610 # CM
+10 1 2 0.0000 6.7300 -17.3680 17.3220 # CM
+11 1 2 0.0000 6.8490 -16.9150 17.1500 # CM
+12 1 2 0.0000 6.4650 -16.6830 16.9290 # CM
+13 1 3 0.0000 6.5600 -16.1930 16.9110 # CT
+14 2 1 -1.0000 -9.4680 5.2210 14.8150 # HG
+15 2 2 0.0000 -8.7410 5.2730 14.6380 # CM
+16 2 2 0.0000 -8.5250 4.8270 14.5720 # CM
+17 2 2 0.0000 -8.0350 4.8310 14.4750 # CM
+18 2 2 0.0000 -7.8590 4.3710 14.3890 # CM
+19 2 2 0.0000 -7.3610 4.4060 14.3820 # CM
+20 2 2 0.0000 -7.1500 3.9530 14.3540 # CM
+21 2 2 0.0000 -6.6520 3.9850 14.3680 # CM
+22 2 2 0.0000 -6.4490 3.5700 14.1770 # CM
+23 2 2 0.0000 -5.9500 3.5750 14.2130 # CM
+24 2 2 0.0000 -5.7600 3.1710 13.9890 # CM
+25 2 2 0.0000 -5.2860 3.2340 13.8450 # CM
+26 2 3 0.0000 -5.0770 2.7850 13.7730 # CT
+27 3 1 -1.0000 -13.5180 3.5030 -2.9670 # HG
+28 3 2 0.0000 -13.7410 3.1060 -2.3720 # CM
+29 3 2 0.0000 -14.0460 3.3640 -2.0710 # CM
+30 3 2 0.0000 -14.1920 3.1300 -1.6540 # CM
+31 3 2 0.0000 -14.5170 3.4060 -1.3910 # CM
+32 3 2 0.0000 -14.5720 3.1810 -0.9480 # CM
+33 3 2 0.0000 -14.8470 3.4610 -0.6390 # CM
+34 3 2 0.0000 -14.8860 3.2480 -0.1890 # CM
+35 3 2 0.0000 -15.2820 3.4330 0.0540 # CM
+36 3 2 0.0000 -15.3150 3.2510 0.5190 # CM
+37 3 2 0.0000 -15.7320 3.4180 0.7370 # CM
+38 3 2 0.0000 -15.8880 3.1230 1.1090 # CM
+39 3 3 0.0000 -16.1980 3.3830 1.4030 # CT
+40 4 1 -1.0000 -0.1290 -30.9680 26.4790 # HG
+41 4 2 0.0000 -0.5600 -31.4860 26.1490 # CM
+42 4 2 0.0000 -0.7390 -31.3350 25.7070 # CM
+43 4 2 0.0000 -1.0490 -31.6520 25.4760 # CM
+44 4 2 0.0000 -1.1860 -31.4810 25.0260 # CM
+45 4 2 0.0000 -1.5550 -31.7780 24.8670 # CM
+46 4 2 0.0000 -1.7560 -31.6020 24.4440 # CM
+47 4 2 0.0000 -2.1380 -31.8850 24.2930 # CM
+48 4 2 0.0000 -2.2230 -31.8120 23.8060 # CM
+49 4 2 0.0000 -2.6240 -32.0670 23.6490 # CM
+50 4 2 0.0000 -2.6770 -32.0110 23.1550 # CM
+51 4 2 0.0000 -2.9370 -32.3820 22.9440 # CM
+52 4 3 0.0000 -3.1080 -32.2300 22.5000 # CT
+53 5 1 -1.0000 11.4610 33.8840 24.5110 # HG
+54 5 2 0.0000 11.9630 33.4980 24.9130 # CM
+55 5 2 0.0000 12.4350 33.5990 24.7820 # CM
+56 5 2 0.0000 12.7900 33.3380 25.0180 # CM
+57 5 2 0.0000 13.2490 33.4840 24.8820 # CM
+58 5 2 0.0000 13.5680 33.1490 25.0700 # CM
+59 5 2 0.0000 14.0320 33.2330 24.9050 # CM
+60 5 2 0.0000 14.3500 32.8870 25.0750 # CM
+61 5 2 0.0000 14.8180 33.0600 25.0530 # CM
+62 5 2 0.0000 15.1500 32.7120 25.1910 # CM
+63 5 2 0.0000 15.6100 32.9070 25.1970 # CM
+64 5 2 0.0000 15.9230 32.6590 25.4960 # CM
+65 5 3 0.0000 16.3930 32.7700 25.3660 # CT
+66 6 1 -1.0000 -4.5200 -30.0620 28.1240 # HG
+67 6 2 0.0000 -5.2470 -30.2270 28.0430 # CM
+68 6 2 0.0000 -5.4120 -30.5490 28.3880 # CM
+69 6 2 0.0000 -5.8880 -30.6950 28.3440 # CM
+70 6 2 0.0000 -6.0260 -30.9950 28.7200 # CM
+71 6 2 0.0000 -6.4710 -31.1840 28.5960 # CM
+72 6 2 0.0000 -6.6140 -31.5330 28.9260 # CM
+73 6 2 0.0000 -7.0490 -31.7390 28.7930 # CM
+74 6 2 0.0000 -7.2640 -31.9530 29.1910 # CM
+75 6 2 0.0000 -7.6870 -32.1900 29.0660 # CM
+76 6 2 0.0000 -7.9080 -32.3700 29.4760 # CM
+77 6 2 0.0000 -8.3980 -32.4420 29.4170 # CM
+78 6 3 0.0000 -8.5600 -32.7580 29.7690 # CT
+79 7 1 -1.0000 19.4590 25.3990 -17.9710 # HG
+80 7 2 0.0000 19.1430 25.8320 -17.4480 # CM
+81 7 2 0.0000 18.9690 25.5700 -17.0590 # CM
+82 7 2 0.0000 18.7330 25.8320 -16.7050 # CM
+83 7 2 0.0000 18.5970 25.5430 -16.3200 # CM
+84 7 2 0.0000 18.2940 25.8180 -16.0330 # CM
+85 7 2 0.0000 18.0950 25.5400 -15.6680 # CM
+86 7 2 0.0000 17.7750 25.8080 -15.3920 # CM
+87 7 2 0.0000 17.7110 25.5900 -14.9470 # CM
+88 7 2 0.0000 17.3690 25.8310 -14.6720 # CM
+89 7 2 0.0000 17.3390 25.6230 -14.2180 # CM
+90 7 2 0.0000 17.1590 25.9360 -13.8730 # CM
+91 7 3 0.0000 16.9940 25.6700 -13.4840 # CT
+92 8 1 -1.0000 -10.9050 -34.3740 -25.5530 # HG
+93 8 2 0.0000 -11.0100 -33.6870 -25.8340 # CM
+94 8 2 0.0000 -10.5810 -33.4610 -25.9560 # CM
+95 8 2 0.0000 -10.6210 -32.9920 -26.1250 # CM
+96 8 2 0.0000 -10.1760 -32.8070 -26.2630 # CM
+97 8 2 0.0000 -10.2430 -32.3180 -26.3420 # CM
+98 8 2 0.0000 -9.8050 -32.0910 -26.4280 # CM
+99 8 2 0.0000 -9.8660 -31.5990 -26.4870 # CM
+100 8 2 0.0000 -9.4740 -31.4070 -26.7300 # CM
+101 8 2 0.0000 -9.5070 -30.9090 -26.7690 # CM
+102 8 2 0.0000 -9.1270 -30.7340 -27.0420 # CM
+103 8 2 0.0000 -9.2250 -30.2910 -27.2510 # CM
+104 8 3 0.0000 -8.7950 -30.0730 -27.3780 # CT
+105 9 1 -1.0000 13.1740 -32.8000 33.2740 # HG
+106 9 2 0.0000 12.4340 -32.8820 33.1800 # CM
+107 9 2 0.0000 12.2240 -32.4890 32.9530 # CM
+108 9 2 0.0000 11.7270 -32.5070 32.8980 # CM
+109 9 2 0.0000 11.5550 -32.1120 32.6440 # CM
+110 9 2 0.0000 11.0570 -32.1220 32.6840 # CM
+111 9 2 0.0000 10.8540 -31.7090 32.4880 # CM
+112 9 2 0.0000 10.3580 -31.7060 32.5460 # CM
+113 9 2 0.0000 10.1500 -31.3930 32.2150 # CM
+114 9 2 0.0000 9.6550 -31.3570 32.2830 # CM
+115 9 2 0.0000 9.4570 -31.0690 31.9260 # CM
+116 9 2 0.0000 8.9710 -31.1600 31.8510 # CM
+117 9 3 0.0000 8.7670 -30.7680 31.6170 # CT
+118 10 1 -1.0000 8.6280 33.1820 -10.7210 # HG
+119 10 2 0.0000 9.2240 32.7890 -10.4920 # CM
+120 10 2 0.0000 9.4230 32.5090 -10.8560 # CM
+121 10 2 0.0000 9.8090 32.2190 -10.7250 # CM
+122 10 2 0.0000 9.9980 31.9750 -11.1190 # CM
+123 10 2 0.0000 10.3190 31.6380 -10.9370 # CM
+124 10 2 0.0000 10.4860 31.3370 -11.3000 # CM
+125 10 2 0.0000 10.7900 30.9850 -11.1180 # CM
+126 10 2 0.0000 11.0760 30.8020 -11.4840 # CM
+127 10 2 0.0000 11.3650 30.4260 -11.3220 # CM
+128 10 2 0.0000 11.6690 30.2750 -11.6880 # CM
+129 10 2 0.0000 12.0790 30.0460 -11.5190 # CM
+130 10 3 0.0000 12.2780 29.7740 -11.8880 # CT
+131 11 1 -1.0000 -26.3600 -23.8490 27.3190 # HG
+132 11 2 0.0000 -26.0320 -24.5210 27.2670 # CM
+133 11 2 0.0000 -26.3220 -24.8600 27.0400 # CM
+134 11 2 0.0000 -26.1370 -25.3240 27.0120 # CM
+135 11 2 0.0000 -26.4400 -25.6290 26.7550 # CM
+136 11 2 0.0000 -26.2670 -26.0930 26.8220 # CM
+137 11 2 0.0000 -26.5800 -26.4290 26.6250 # CM
+138 11 2 0.0000 -26.4200 -26.8950 26.7080 # CM
+139 11 2 0.0000 -26.6300 -27.2090 26.3810 # CM
+140 11 2 0.0000 -26.5020 -27.6840 26.4730 # CM
+141 11 2 0.0000 -26.6910 -27.9820 26.1190 # CM
+142 11 2 0.0000 -26.4410 -28.4110 26.0720 # CM
+143 11 3 0.0000 -26.7310 -28.7440 25.8380 # CT
+144 12 1 -1.0000 9.7960 13.1570 21.1370 # HG
+145 12 2 0.0000 9.9010 12.4230 21.0250 # CM
+146 12 2 0.0000 10.3450 12.2640 21.1940 # CM
+147 12 2 0.0000 10.4510 11.7830 21.1120 # CM
+148 12 2 0.0000 10.8890 11.6530 21.3170 # CM
+149 12 2 0.0000 10.9990 11.1970 21.1430 # CM
+150 12 2 0.0000 11.4580 11.0590 21.2840 # CM
+151 12 2 0.0000 11.5790 10.6140 21.0950 # CM
+152 12 2 0.0000 11.9490 10.4090 21.3620 # CM
+153 12 2 0.0000 12.1020 9.9750 21.1640 # CM
+154 12 2 0.0000 12.4470 9.7670 21.4580 # CM
+155 12 2 0.0000 12.4820 9.2720 21.3970 # CM
+156 12 3 0.0000 12.9230 9.1170 21.5740 # CT
+157 13 1 -1.0000 31.7720 25.7400 5.8580 # HG
+158 13 2 0.0000 31.2900 26.2440 5.5840 # CM
+159 13 2 0.0000 31.5140 26.6670 5.4390 # CM
+160 13 2 0.0000 31.2120 27.0300 5.2730 # CM
+161 13 2 0.0000 31.4710 27.4260 5.1110 # CM
+162 13 2 0.0000 31.1400 27.7930 5.0360 # CM
+163 13 2 0.0000 31.3720 28.2230 4.9270 # CM
+164 13 2 0.0000 31.0450 28.5950 4.8720 # CM
+165 13 2 0.0000 31.2520 28.9670 4.6090 # CM
+166 13 2 0.0000 30.9450 29.3600 4.5720 # CM
+167 13 2 0.0000 31.1510 29.7090 4.2790 # CM
+168 13 2 0.0000 30.8130 30.0150 4.0760 # CM
+169 13 3 0.0000 31.0420 30.4330 3.9260 # CT
+170 14 1 -1.0000 -8.0340 -0.2300 1.1720 # HG
+171 14 2 0.0000 -7.7380 -0.5830 1.7630 # CM
+172 14 2 0.0000 -7.6240 -1.0610 1.6650 # CM
+173 14 2 0.0000 -7.4450 -1.3270 2.0490 # CM
+174 14 2 0.0000 -7.3170 -1.7900 1.9090 # CM
+175 14 2 0.0000 -7.2260 -2.0470 2.3280 # CM
+176 14 2 0.0000 -7.1500 -2.5310 2.2270 # CM
+177 14 2 0.0000 -7.0800 -2.7930 2.6460 # CM
+178 14 2 0.0000 -6.8450 -3.2220 2.5410 # CM
+179 14 2 0.0000 -6.7960 -3.5090 2.9480 # CM
+180 14 2 0.0000 -6.5310 -3.9180 2.8360 # CM
+181 14 2 0.0000 -6.3110 -4.1220 3.2350 # CM
+182 14 3 0.0000 -6.1920 -4.5960 3.1300 # CT
+183 15 1 -1.0000 18.7940 33.1570 -25.3840 # HG
+184 15 2 0.0000 19.1390 32.4980 -25.2940 # CM
+185 15 2 0.0000 18.8180 32.1180 -25.2420 # CM
+186 15 2 0.0000 19.0210 31.6690 -25.1570 # CM
+187 15 2 0.0000 18.6730 31.3090 -25.1370 # CM
+188 15 2 0.0000 18.9010 30.8980 -24.9680 # CM
+189 15 2 0.0000 18.5700 30.5330 -24.8830 # CM
+190 15 2 0.0000 18.7920 30.1280 -24.6940 # CM
+191 15 2 0.0000 18.5040 29.7260 -24.7660 # CM
+192 15 2 0.0000 18.7010 29.3170 -24.5550 # CM
+193 15 2 0.0000 18.4200 28.9180 -24.6630 # CM
+194 15 2 0.0000 18.6740 28.4890 -24.6320 # CM
+195 15 3 0.0000 18.3490 28.1120 -24.5880 # CT
+196 16 1 -1.0000 -15.1000 30.3850 2.2020 # HG
+197 16 2 0.0000 -14.3910 30.4230 1.9600 # CM
+198 16 2 0.0000 -14.2440 30.0040 1.7300 # CM
+199 16 2 0.0000 -13.7670 29.9920 1.5780 # CM
+200 16 2 0.0000 -13.6620 29.5710 1.3290 # CM
+201 16 2 0.0000 -13.1660 29.5590 1.2710 # CM
+202 16 2 0.0000 -13.0210 29.1220 1.0750 # CM
+203 16 2 0.0000 -12.5240 29.0990 1.0350 # CM
+204 16 2 0.0000 -12.3950 28.7530 0.6980 # CM
+205 16 2 0.0000 -11.8990 28.6970 0.6700 # CM
+206 16 2 0.0000 -11.7840 28.3730 0.3080 # CM
+207 16 2 0.0000 -11.3210 28.4340 0.1320 # CM
+208 16 3 0.0000 -11.1800 28.0160 -0.1030 # CT
+209 17 1 -1.0000 -30.4840 -25.1510 25.9280 # HG
+210 17 2 0.0000 -30.4950 -25.3340 26.6550 # CM
+211 17 2 0.0000 -30.0490 -25.4830 26.8240 # CM
+212 17 2 0.0000 -30.0330 -25.6320 27.3010 # CM
+213 17 2 0.0000 -29.5670 -25.7480 27.4430 # CM
+214 17 2 0.0000 -29.6040 -25.9700 27.8890 # CM
+215 17 2 0.0000 -29.1600 -26.1500 28.0360 # CM
+216 17 2 0.0000 -29.1990 -26.3910 28.4710 # CM
+217 17 2 0.0000 -28.7500 -26.4190 28.6900 # CM
+218 17 2 0.0000 -28.7680 -26.6860 29.1130 # CM
+219 17 2 0.0000 -28.3220 -26.6780 29.3380 # CM
+220 17 2 0.0000 -28.3500 -26.7670 29.8290 # CM
+221 17 3 0.0000 -27.9000 -26.9070 29.9940 # CT
+222 18 1 -1.0000 -27.3350 -7.5350 -34.2720 # HG
+223 18 2 0.0000 -27.5580 -8.2210 -34.4780 # CM
+224 18 2 0.0000 -27.2310 -8.5770 -34.3480 # CM
+225 18 2 0.0000 -27.3440 -9.0420 -34.4930 # CM
+226 18 2 0.0000 -27.0110 -9.3740 -34.3230 # CM
+227 18 2 0.0000 -27.1070 -9.8060 -34.5560 # CM
+228 18 2 0.0000 -26.7560 -10.1470 -34.4520 # CM
+229 18 2 0.0000 -26.8390 -10.5720 -34.7000 # CM
+230 18 2 0.0000 -26.5990 -10.9500 -34.4750 # CM
+231 18 2 0.0000 -26.6480 -11.3770 -34.7310 # CM
+232 18 2 0.0000 -26.4330 -11.7510 -34.4790 # CM
+233 18 2 0.0000 -26.6170 -12.1990 -34.6020 # CM
+234 18 3 0.0000 -26.2910 -12.5510 -34.4630 # CT
+235 19 1 -1.0000 -0.4070 17.6680 -5.9150 # HG
+236 19 2 0.0000 0.0520 18.2510 -5.8110 # CM
+237 19 2 0.0000 0.5120 18.1690 -5.9890 # CM
+238 19 2 0.0000 0.8460 18.5340 -5.9130 # CM
+239 19 2 0.0000 1.2860 18.4300 -6.1280 # CM
+240 19 2 0.0000 1.6110 18.7690 -5.9600 # CM
+241 19 2 0.0000 2.0760 18.6610 -6.1110 # CM
+242 19 2 0.0000 2.4060 18.9870 -5.9270 # CM
+243 19 2 0.0000 2.8230 18.9810 -6.2030 # CM
+244 19 2 0.0000 3.1750 19.2810 -6.0110 # CM
+245 19 2 0.0000 3.5730 19.2910 -6.3140 # CM
+246 19 2 0.0000 3.8500 19.7030 -6.2570 # CM
+247 19 3 0.0000 4.3050 19.6190 -6.4440 # CT
+248 20 1 -1.0000 18.0940 3.2440 7.7860 # HG
+249 20 2 0.0000 18.6660 2.7730 7.8980 # CM
+250 20 2 0.0000 19.0960 2.9430 7.7080 # CM
+251 20 2 0.0000 19.4900 2.6380 7.7490 # CM
+252 20 2 0.0000 19.9080 2.8500 7.5720 # CM
+253 20 2 0.0000 20.2540 2.4900 7.5510 # CM
+254 20 2 0.0000 20.6690 2.6560 7.3260 # CM
+255 20 2 0.0000 21.0090 2.2920 7.2850 # CM
+256 20 2 0.0000 21.4630 2.4900 7.2190 # CM
+257 20 2 0.0000 21.8100 2.1370 7.1460 # CM
+258 20 2 0.0000 22.2620 2.3460 7.1150 # CM
+259 20 2 0.0000 22.6310 2.0290 7.2270 # CM
+260 20 3 0.0000 23.0600 2.2060 7.0420 # CT
+261 21 1 -1.0000 14.2400 25.0380 32.2930 # HG
+262 21 2 0.0000 14.3570 25.6040 31.8140 # CM
+263 21 2 0.0000 13.9370 25.7560 31.5890 # CM
+264 21 2 0.0000 13.9890 26.1170 31.2470 # CM
+265 21 2 0.0000 13.5470 26.2630 31.0630 # CM
+266 21 2 0.0000 13.6450 26.5570 30.6710 # CM
+267 21 2 0.0000 13.2240 26.6750 30.4280 # CM
+268 21 2 0.0000 13.3210 26.9520 30.0240 # CM
+269 21 2 0.0000 12.9100 27.2010 29.8860 # CM
+270 21 2 0.0000 12.9840 27.4590 29.4630 # CM
+271 21 2 0.0000 12.5780 27.7290 29.3550 # CM
+272 21 2 0.0000 12.6770 28.1220 29.0640 # CM
+273 21 3 0.0000 12.2540 28.2750 28.8470 # CT
+274 22 1 -1.0000 -0.3720 -22.5100 10.7880 # HG
+275 22 2 0.0000 0.2670 -22.7140 11.1220 # CM
+276 22 2 0.0000 0.5490 -22.3220 11.2550 # CM
+277 22 2 0.0000 0.9920 -22.4290 11.4600 # CM
+278 22 2 0.0000 1.2330 -22.0150 11.6050 # CM
+279 22 2 0.0000 1.6990 -22.1550 11.7230 # CM
+280 22 2 0.0000 1.9850 -21.7560 11.8190 # CM
+281 22 2 0.0000 2.4560 -21.8910 11.9160 # CM
+282 22 2 0.0000 2.6890 -21.5280 12.1680 # CM
+283 22 2 0.0000 3.1710 -21.6370 12.2450 # CM
+284 22 2 0.0000 3.3830 -21.2820 12.5250 # CM
+285 22 2 0.0000 3.7880 -21.4420 12.7690 # CM
+286 22 3 0.0000 4.0620 -21.0480 12.9070 # CT
+287 23 1 -1.0000 28.7790 18.7360 17.2860 # HG
+288 23 2 0.0000 29.2940 19.1580 17.6310 # CM
+289 23 2 0.0000 29.4930 18.9320 18.0310 # CM
+290 23 2 0.0000 29.8230 19.2000 18.2930 # CM
+291 23 2 0.0000 30.0210 18.9340 18.6680 # CM
+292 23 2 0.0000 30.2750 19.2560 18.9540 # CM
+293 23 2 0.0000 30.4400 19.0320 19.3700 # CM
+294 23 2 0.0000 30.6760 19.3560 19.6670 # CM
+295 23 2 0.0000 30.9750 19.1100 19.9840 # CM
+296 23 2 0.0000 31.1950 19.4210 20.3090 # CM
+297 23 2 0.0000 31.5140 19.1670 20.5970 # CM
+298 23 2 0.0000 31.8720 19.4560 20.7920 # CM
+299 23 3 0.0000 32.0730 19.2230 21.1850 # CT
+300 24 1 -1.0000 -30.9720 11.3670 31.0680 # HG
+301 24 2 0.0000 -31.2450 11.9220 30.6430 # CM
+302 24 2 0.0000 -31.0080 12.3560 30.7170 # CM
+303 24 2 0.0000 -31.1840 12.7490 30.4630 # CM
+304 24 2 0.0000 -30.9070 13.1580 30.5400 # CM
+305 24 2 0.0000 -31.1590 13.5410 30.3420 # CM
+306 24 2 0.0000 -30.9370 13.9760 30.4510 # CM
+307 24 2 0.0000 -31.1980 14.3620 30.2730 # CM
+308 24 2 0.0000 -30.9040 14.7640 30.2340 # CM
+309 24 2 0.0000 -31.1610 15.1670 30.0860 # CM
+310 24 2 0.0000 -30.8490 15.5520 30.0190 # CM
+311 24 2 0.0000 -31.0300 15.8970 29.7060 # CM
+312 24 3 0.0000 -30.7850 16.3260 29.7780 # CT
+313 25 1 -1.0000 12.7510 -20.4140 -12.4460 # HG
+314 25 2 0.0000 12.6780 -20.5810 -13.1730 # CM
+315 25 2 0.0000 12.6240 -21.0720 -13.2540 # CM
+316 25 2 0.0000 12.5960 -21.2140 -13.7330 # CM
+317 25 2 0.0000 12.5150 -21.7060 -13.7750 # CM
+318 25 2 0.0000 12.5780 -21.8200 -14.2580 # CM
+319 25 2 0.0000 12.5590 -22.3150 -14.3270 # CM
+320 25 2 0.0000 12.6430 -22.4340 -14.8040 # CM
+321 25 2 0.0000 12.4640 -22.8910 -14.9010 # CM
+322 25 2 0.0000 12.5690 -23.0350 -15.3680 # CM
+323 25 2 0.0000 12.3550 -23.4770 -15.4610 # CM
+324 25 2 0.0000 12.2810 -23.5590 -15.9480 # CM
+325 25 3 0.0000 12.2200 -24.0490 -16.0230 # CT
+326 26 1 -1.0000 29.1690 3.3770 -0.8320 # HG
+327 26 2 0.0000 29.8140 3.0710 -1.0610 # CM
+328 26 2 0.0000 29.7920 2.5720 -1.0870 # CM
+329 26 2 0.0000 30.2160 2.3390 -1.2150 # CM
+330 26 2 0.0000 30.1500 1.8450 -1.2570 # CM
+331 26 2 0.0000 30.6060 1.6430 -1.3000 # CM
+332 26 2 0.0000 30.5810 1.1440 -1.2880 # CM
+333 26 2 0.0000 31.0360 0.9400 -1.3100 # CM
+334 26 2 0.0000 31.0030 0.4650 -1.4630 # CM
+335 26 2 0.0000 31.4490 0.2390 -1.4600 # CM
+336 26 2 0.0000 31.4070 -0.2230 -1.6470 # CM
+337 26 2 0.0000 31.8380 -0.3990 -1.8270 # CM
+338 26 3 0.0000 31.8090 -0.8970 -1.8580 # CT
+339 27 1 -1.0000 31.2220 19.3390 -21.3530 # HG
+340 27 2 0.0000 30.9210 18.6550 -21.3050 # CM
+341 27 2 0.0000 31.2310 18.2950 -21.4620 # CM
+342 27 2 0.0000 31.0480 17.8300 -21.4630 # CM
+343 27 2 0.0000 31.3930 17.4950 -21.5980 # CM
+344 27 2 0.0000 31.1530 17.0620 -21.6690 # CM
+345 27 2 0.0000 31.4610 16.7170 -21.8610 # CM
+346 27 2 0.0000 31.2190 16.2910 -21.9520 # CM
+347 27 2 0.0000 31.5450 15.9120 -21.9800 # CM
+348 27 2 0.0000 31.3190 15.4830 -22.1020 # CM
+349 27 2 0.0000 31.6500 15.1090 -22.0940 # CM
+350 27 2 0.0000 31.4360 14.6620 -22.0270 # CM
+351 27 3 0.0000 31.7530 14.3060 -22.1770 # CT
+352 28 1 -1.0000 -7.8460 29.3350 -4.9140 # HG
+353 28 2 0.0000 -7.2360 29.7580 -5.0180 # CM
+354 28 2 0.0000 -6.8540 29.6210 -4.7260 # CM
+355 28 2 0.0000 -6.4410 29.9000 -4.7580 # CM
+356 28 2 0.0000 -6.0710 29.7190 -4.4730 # CM
+357 28 2 0.0000 -5.7120 30.0660 -4.4650 # CM
+358 28 2 0.0000 -5.3510 29.9410 -4.1430 # CM
+359 28 2 0.0000 -5.0010 30.2960 -4.1180 # CM
+360 28 2 0.0000 -4.5760 30.1050 -3.9360 # CM
+361 28 2 0.0000 -4.2260 30.4570 -3.8760 # CM
+362 28 2 0.0000 -3.7980 30.2470 -3.7260 # CM
+363 28 2 0.0000 -3.3970 30.5250 -3.8340 # CM
+364 28 3 0.0000 -3.0160 30.3790 -3.5450 # CT
+365 29 1 -1.0000 -9.4900 -9.1250 -16.2900 # HG
+366 29 2 0.0000 -8.9220 -9.2470 -16.7640 # CM
+367 29 2 0.0000 -9.0400 -9.5670 -17.1300 # CM
+368 29 2 0.0000 -8.6720 -9.6840 -17.4470 # CM
+369 29 2 0.0000 -8.8330 -9.9840 -17.8140 # CM
+370 29 2 0.0000 -8.4270 -10.1450 -18.0560 # CM
+371 29 2 0.0000 -8.5480 -10.4930 -18.3950 # CM
+372 29 2 0.0000 -8.1410 -10.6710 -18.6240 # CM
+373 29 2 0.0000 -8.2690 -10.8820 -19.0590 # CM
+374 29 2 0.0000 -7.8750 -11.0910 -19.2850 # CM
+375 29 2 0.0000 -8.0100 -11.2680 -19.7320 # CM
+376 29 2 0.0000 -7.6260 -11.3100 -20.0490 # CM
+377 29 3 0.0000 -7.7520 -11.6250 -20.4160 # CT
+378 30 1 -1.0000 21.8090 20.0230 31.1610 # HG
+379 30 2 0.0000 21.4830 20.2140 31.8090 # CM
+380 30 2 0.0000 21.3670 20.7000 31.8300 # CM
+381 30 2 0.0000 21.1690 20.8590 32.2610 # CM
+382 30 2 0.0000 21.0400 21.3420 32.2380 # CM
+383 30 2 0.0000 20.9290 21.4840 32.7040 # CM
+384 30 2 0.0000 20.8490 21.9770 32.7260 # CM
+385 30 2 0.0000 20.7580 22.1250 33.1940 # CM
+386 30 2 0.0000 20.5220 22.5650 33.1920 # CM
+387 30 2 0.0000 20.4520 22.7400 33.6550 # CM
+388 30 2 0.0000 20.1860 23.1620 33.6400 # CM
+389 30 2 0.0000 19.9470 23.2570 34.0670 # CM
+390 30 3 0.0000 19.8250 23.7420 34.0810 # CT
+391 31 1 -1.0000 -19.5940 -20.9190 3.0420 # HG
+392 31 2 0.0000 -20.1100 -20.3750 3.0180 # CM
+393 31 2 0.0000 -20.5550 -20.5380 2.8570 # CM
+394 31 2 0.0000 -20.9110 -20.1910 2.8090 # CM
+395 31 2 0.0000 -21.3490 -20.3920 2.6720 # CM
+396 31 2 0.0000 -21.6510 -20.0130 2.5530 # CM
+397 31 2 0.0000 -22.0800 -20.1810 2.3580 # CM
+398 31 2 0.0000 -22.3750 -19.8030 2.2190 # CM
+399 31 2 0.0000 -22.8480 -19.9600 2.1840 # CM
+400 31 2 0.0000 -23.1510 -19.5990 2.0160 # CM
+401 31 2 0.0000 -23.6240 -19.7590 2.0180 # CM
+402 31 2 0.0000 -23.9550 -19.3860 2.0380 # CM
+403 31 3 0.0000 -24.3990 -19.5550 1.8830 # CT
+404 32 1 -1.0000 8.9790 10.0570 7.9020 # HG
+405 32 2 0.0000 9.5790 9.7410 7.5820 # CM
+406 32 2 0.0000 9.6970 9.3000 7.7860 # CM
+407 32 2 0.0000 10.1070 9.0780 7.6070 # CM
+408 32 2 0.0000 10.1790 8.6280 7.8150 # CM
+409 32 2 0.0000 10.6360 8.4780 7.6770 # CM
+410 32 2 0.0000 10.7630 8.0560 7.9130 # CM
+411 32 2 0.0000 11.2270 7.9150 7.7940 # CM
+412 32 2 0.0000 11.2880 7.4280 7.8900 # CM
+413 32 2 0.0000 11.7580 7.2810 7.8040 # CM
+414 32 2 0.0000 11.7960 6.7870 7.8720 # CM
+415 32 2 0.0000 12.1800 6.5860 7.6240 # CM
+416 32 3 0.0000 12.2900 6.1420 7.8270 # CT
+417 33 1 -1.0000 17.6460 -1.2550 -20.2560 # HG
+418 33 2 0.0000 17.7700 -1.5490 -20.9350 # CM
+419 33 2 0.0000 17.8180 -1.2000 -21.2900 # CM
+420 33 2 0.0000 17.8790 -1.3680 -21.7570 # CM
+421 33 2 0.0000 17.9510 -0.9940 -22.0810 # CM
+422 33 2 0.0000 17.9220 -1.1920 -22.5380 # CM
+423 33 2 0.0000 17.9330 -0.8350 -22.8880 # CM
+424 33 2 0.0000 17.8830 -1.0290 -23.3460 # CM
+425 33 2 0.0000 18.0580 -0.7080 -23.6870 # CM
+426 33 2 0.0000 17.9860 -0.8770 -24.1530 # CM
+427 33 2 0.0000 18.1940 -0.5640 -24.4810 # CM
+428 33 2 0.0000 18.3040 -0.7830 -24.9160 # CM
+429 33 3 0.0000 18.3580 -0.4300 -25.2660 # CT
+430 34 1 -1.0000 22.4520 -27.9790 -19.8930 # HG
+431 34 2 0.0000 23.1550 -27.8000 -19.7020 # CM
+432 34 2 0.0000 23.4590 -27.7650 -20.0980 # CM
+433 34 2 0.0000 23.9400 -27.6690 -19.9980 # CM
+434 34 2 0.0000 24.2080 -27.6140 -20.4170 # CM
+435 34 2 0.0000 24.6880 -27.6060 -20.2790 # CM
+436 34 2 0.0000 24.9880 -27.6080 -20.6790 # CM
+437 34 2 0.0000 25.4690 -27.6210 -20.5450 # CM
+438 34 2 0.0000 25.7560 -27.4580 -20.9200 # CM
+439 34 2 0.0000 26.2430 -27.4940 -20.8100 # CM
+440 34 2 0.0000 26.5160 -27.2980 -21.1790 # CM
+441 34 2 0.0000 26.9690 -27.1510 -21.0290 # CM
+442 34 3 0.0000 27.2670 -27.1100 -21.4280 # CT
+443 35 1 -1.0000 -21.7320 -7.7100 -28.0790 # HG
+444 35 2 0.0000 -21.5610 -6.9800 -28.1070 # CM
+445 35 2 0.0000 -21.0690 -6.8960 -28.0710 # CM
+446 35 2 0.0000 -20.9290 -6.4160 -28.0640 # CM
+447 35 2 0.0000 -20.4300 -6.3700 -28.0540 # CM
+448 35 2 0.0000 -20.3330 -5.8880 -27.9620 # CM
+449 35 2 0.0000 -19.8430 -5.8160 -27.8900 # CM
+450 35 2 0.0000 -19.7450 -5.3400 -27.7770 # CM
+451 35 2 0.0000 -19.2650 -5.2380 -27.8690 # CM
+452 35 2 0.0000 -19.1460 -4.7720 -27.7310 # CM
+453 35 2 0.0000 -18.6730 -4.6730 -27.8600 # CM
+454 35 2 0.0000 -18.5830 -4.1840 -27.9090 # CM
+455 35 3 0.0000 -18.0910 -4.1050 -27.8790 # CT
+456 36 1 -1.0000 9.4810 -29.0890 -32.6680 # HG
+457 36 2 0.0000 9.0550 -28.9030 -32.0790 # CM
+458 36 2 0.0000 9.1530 -28.4440 -31.9070 # CM
+459 36 2 0.0000 8.8990 -28.3030 -31.5000 # CM
+460 36 2 0.0000 9.0020 -27.8300 -31.3720 # CM
+461 36 2 0.0000 8.8000 -27.7560 -30.9210 # CM
+462 36 2 0.0000 8.9320 -27.3100 -30.7380 # CM
+463 36 2 0.0000 8.7480 -27.2420 -30.2780 # CM
+464 36 2 0.0000 8.7370 -26.7540 -30.1700 # CM
+465 36 2 0.0000 8.5830 -26.6740 -29.7000 # CM
+466 36 2 0.0000 8.5450 -26.1830 -29.6170 # CM
+467 36 2 0.0000 8.2300 -26.0730 -29.2450 # CM
+468 36 3 0.0000 8.3270 -25.6110 -29.0810 # CT
+469 37 1 -1.0000 15.5970 22.5170 -30.4500 # HG
+470 37 2 0.0000 15.1520 23.0740 -30.2180 # CM
+471 37 2 0.0000 15.4030 23.4960 -30.1260 # CM
+472 37 2 0.0000 15.1340 23.8780 -29.9480 # CM
+473 37 2 0.0000 15.4110 24.2900 -29.8930 # CM
+474 37 2 0.0000 15.1330 24.6170 -29.6370 # CM
+475 37 2 0.0000 15.4010 25.0220 -29.5150 # CM
+476 37 2 0.0000 15.1320 25.3410 -29.2420 # CM
+477 37 2 0.0000 15.3330 25.7980 -29.2650 # CM
+478 37 2 0.0000 15.0910 26.1220 -28.9700 # CM
+479 37 2 0.0000 15.2810 26.5800 -29.0280 # CM
+480 37 2 0.0000 14.9600 26.9410 -28.9030 # CM
+481 37 3 0.0000 15.2150 27.3630 -28.8180 # CT
+482 38 1 -1.0000 33.6820 -10.8500 -8.3900 # HG
+483 38 2 0.0000 33.1490 -11.1760 -8.8050 # CM
+484 38 2 0.0000 33.0730 -11.6540 -8.6790 # CM
+485 38 2 0.0000 32.7380 -11.9030 -8.9550 # CM
+486 38 2 0.0000 32.6680 -12.3680 -8.7850 # CM
+487 38 2 0.0000 32.3980 -12.6080 -9.1300 # CM
+488 38 2 0.0000 32.3560 -13.0940 -9.0180 # CM
+489 38 2 0.0000 32.1050 -13.3400 -9.3720 # CM
+490 38 2 0.0000 31.9240 -13.7680 -9.1870 # CM
+491 38 2 0.0000 31.6960 -14.0390 -9.5400 # CM
+492 38 2 0.0000 31.4910 -14.4470 -9.3350 # CM
+493 38 2 0.0000 31.1140 -14.6320 -9.6060 # CM
+494 38 3 0.0000 31.0360 -15.1070 -9.4710 # CT
+495 39 1 -1.0000 6.8690 -9.3550 -17.5090 # HG
+496 39 2 0.0000 7.0150 -9.5150 -18.2270 # CM
+497 39 2 0.0000 7.1800 -9.9830 -18.2910 # CM
+498 39 2 0.0000 7.3070 -10.1090 -18.7570 # CM
+499 39 2 0.0000 7.4410 -10.5900 -18.7890 # CM
+500 39 2 0.0000 7.6400 -10.6540 -19.2430 # CM
+501 39 2 0.0000 7.8360 -11.1120 -19.2880 # CM
+502 39 2 0.0000 8.0540 -11.1720 -19.7340 # CM
+503 39 2 0.0000 8.0960 -11.6590 -19.8390 # CM
+504 39 2 0.0000 8.3410 -11.7340 -20.2690 # CM
+505 39 2 0.0000 8.3460 -12.2220 -20.3780 # CM
+506 39 2 0.0000 8.4090 -12.3110 -20.8650 # CM
+507 39 3 0.0000 8.5670 -12.7820 -20.9250 # CT
+508 40 1 -1.0000 -21.1810 4.2870 17.5290 # HG
+509 40 2 0.0000 -20.8610 4.4620 18.1840 # CM
+510 40 2 0.0000 -20.6860 4.9300 18.1950 # CM
+511 40 2 0.0000 -20.4470 5.0670 18.6120 # CM
+512 40 2 0.0000 -20.3100 5.5480 18.5980 # CM
+513 40 2 0.0000 -20.0060 5.6210 18.9870 # CM
+514 40 2 0.0000 -19.8050 6.0790 18.9720 # CM
+515 40 2 0.0000 -19.4840 6.1480 19.3480 # CM
+516 40 2 0.0000 -19.4170 6.6370 19.4280 # CM
+517 40 2 0.0000 -19.0740 6.7210 19.7820 # CM
+518 40 2 0.0000 -19.0420 7.2110 19.8750 # CM
+519 40 2 0.0000 -18.8600 7.3110 20.3290 # CM
+520 40 3 0.0000 -18.6930 7.7820 20.3370 # CT
+521 41 1 -1.0000 -18.2790 -16.1240 30.8390 # HG
+522 41 2 0.0000 -18.6040 -15.7620 31.4100 # CM
+523 41 2 0.0000 -19.0860 -15.6610 31.3250 # CM
+524 41 2 0.0000 -19.3220 -15.4000 31.6800 # CM
+525 41 2 0.0000 -19.8080 -15.3410 31.5750 # CM
+526 41 2 0.0000 -19.9860 -15.0090 31.9020 # CM
+527 41 2 0.0000 -20.4580 -14.8840 31.7900 # CM
+528 41 2 0.0000 -20.6310 -14.5360 32.1030 # CM
+529 41 2 0.0000 -21.1310 -14.5370 32.0980 # CM
+530 41 2 0.0000 -21.3190 -14.1720 32.3850 # CM
+531 41 2 0.0000 -21.8180 -14.2050 32.3970 # CM
+532 41 2 0.0000 -22.0170 -13.9900 32.8010 # CM
+533 41 3 0.0000 -22.5000 -13.8980 32.7140 # CT
+534 42 1 -1.0000 1.3230 13.6250 -5.1740 # HG
+535 42 2 0.0000 2.0180 13.5660 -4.8970 # CM
+536 42 2 0.0000 2.2140 14.0090 -4.7730 # CM
+537 42 2 0.0000 2.6860 14.0010 -4.6060 # CM
+538 42 2 0.0000 2.8400 14.4560 -4.4660 # CM
+539 42 2 0.0000 3.3330 14.4230 -4.3890 # CM
+540 42 2 0.0000 3.5290 14.8750 -4.3020 # CM
+541 42 2 0.0000 4.0250 14.8480 -4.2460 # CM
+542 42 2 0.0000 4.1910 15.2510 -4.0010 # CM
+543 42 2 0.0000 4.6900 15.2520 -3.9640 # CM
+544 42 2 0.0000 4.8390 15.6420 -3.6890 # CM
+545 42 2 0.0000 5.2890 15.5730 -3.4830 # CM
+546 42 3 0.0000 5.4780 16.0170 -3.3530 # CT
+547 43 1 -1.0000 3.2190 11.4660 -5.7300 # HG
+548 43 2 0.0000 2.8470 11.2350 -6.3390 # CM
+549 43 2 0.0000 2.5450 11.5880 -6.5250 # CM
+550 43 2 0.0000 2.2670 11.4530 -6.9180 # CM
+551 43 2 0.0000 1.9980 11.8370 -7.0950 # CM
+552 43 2 0.0000 1.6760 11.6460 -7.4250 # CM
+553 43 2 0.0000 1.3530 11.9950 -7.5810 # CM
+554 43 2 0.0000 1.0160 11.8020 -7.8950 # CM
+555 43 2 0.0000 0.8100 12.1660 -8.1690 # CM
+556 43 2 0.0000 0.4490 11.9910 -8.4670 # CM
+557 43 2 0.0000 0.2750 12.3580 -8.7580 # CM
+558 43 2 0.0000 0.0620 12.1900 -9.1770 # CM
+559 43 3 0.0000 -0.2330 12.5480 -9.3630 # CT
+560 44 1 -1.0000 20.2710 16.5490 -21.3160 # HG
+561 44 2 0.0000 19.9240 17.2090 -21.3920 # CM
+562 44 2 0.0000 19.4680 17.1650 -21.5940 # CM
+563 44 2 0.0000 19.2220 17.5920 -21.6770 # CM
+564 44 2 0.0000 18.7610 17.5090 -21.8530 # CM
+565 44 2 0.0000 18.5830 17.9520 -22.0020 # CM
+566 44 2 0.0000 18.1440 17.8970 -22.2360 # CM
+567 44 2 0.0000 17.9730 18.3350 -22.4050 # CM
+568 44 2 0.0000 17.4800 18.3080 -22.4820 # CM
+569 44 2 0.0000 17.3010 18.7310 -22.6810 # CM
+570 44 2 0.0000 16.8040 18.7020 -22.7210 # CM
+571 44 2 0.0000 16.5840 19.1500 -22.7360 # CM
+572 44 3 0.0000 16.1260 19.1000 -22.9300 # CT
+573 45 1 -1.0000 -2.3430 -17.3740 -23.0650 # HG
+574 45 2 0.0000 -2.6620 -18.0140 -22.8390 # CM
+575 45 2 0.0000 -2.3330 -18.3870 -22.7900 # CM
+576 45 2 0.0000 -2.5230 -18.8320 -22.6630 # CM
+577 45 2 0.0000 -2.1640 -19.1740 -22.5960 # CM
+578 45 2 0.0000 -2.3930 -19.6160 -22.5560 # CM
+579 45 2 0.0000 -2.0590 -19.9890 -22.5440 # CM
+580 45 2 0.0000 -2.2860 -20.4330 -22.5250 # CM
+581 45 2 0.0000 -1.9700 -20.7790 -22.3490 # CM
+582 45 2 0.0000 -2.1740 -21.2350 -22.3540 # CM
+583 45 2 0.0000 -1.8610 -21.5640 -22.1450 # CM
+584 45 2 0.0000 -2.0930 -21.9690 -21.9680 # CM
+585 45 3 0.0000 -1.7600 -22.3370 -21.9140 # CT
+586 46 1 -1.0000 24.4550 5.3630 -9.1820 # HG
+587 46 2 0.0000 23.7530 5.2820 -8.9300 # CM
+588 46 2 0.0000 23.4510 5.0700 -9.2680 # CM
+589 46 2 0.0000 22.9710 5.0250 -9.1350 # CM
+590 46 2 0.0000 22.7040 4.7850 -9.4840 # CM
+591 46 2 0.0000 22.2240 4.8350 -9.3560 # CM
+592 46 2 0.0000 21.9250 4.6540 -9.7140 # CM
+593 46 2 0.0000 21.4440 4.7220 -9.5990 # CM
+594 46 2 0.0000 21.1600 4.4050 -9.8610 # CM
+595 46 2 0.0000 20.6720 4.4830 -9.7780 # CM
+596 46 2 0.0000 20.4020 4.1390 -10.0200 # CM
+597 46 2 0.0000 19.9500 4.0700 -9.8190 # CM
+598 46 3 0.0000 19.6530 3.8520 -10.1570 # CT
+599 47 1 -1.0000 -33.6610 -24.3180 -18.5060 # HG
+600 47 2 0.0000 -33.9420 -23.6280 -18.5950 # CM
+601 47 2 0.0000 -33.7350 -23.3840 -18.9790 # CM
+602 47 2 0.0000 -33.8880 -22.9130 -19.0480 # CM
+603 47 2 0.0000 -33.6810 -22.7090 -19.4560 # CM
+604 47 2 0.0000 -33.7880 -22.2210 -19.4420 # CM
+605 47 2 0.0000 -33.5480 -21.9760 -19.8060 # CM
+606 47 2 0.0000 -33.6370 -21.4850 -19.7820 # CM
+607 47 2 0.0000 -33.5420 -21.2730 -20.2250 # CM
+608 47 2 0.0000 -33.5970 -20.7750 -20.2060 # CM
+609 47 2 0.0000 -33.5320 -20.5800 -20.6620 # CM
+610 47 2 0.0000 -33.7550 -20.1370 -20.7170 # CM
+611 47 3 0.0000 -33.5500 -19.9000 -21.1060 # CT
+612 48 1 -1.0000 23.4460 -8.6790 22.9010 # HG
+613 48 2 0.0000 23.8580 -8.3940 22.3430 # CM
+614 48 2 0.0000 23.9210 -8.7160 21.9650 # CM
+615 48 2 0.0000 24.2110 -8.5600 21.5890 # CM
+616 48 2 0.0000 24.2310 -8.8960 21.2190 # CM
+617 48 2 0.0000 24.5910 -8.7450 20.9070 # CM
+618 48 2 0.0000 24.6760 -9.0880 20.5530 # CM
+619 48 2 0.0000 25.0500 -8.9490 20.2530 # CM
+620 48 2 0.0000 25.0220 -9.1970 19.8200 # CM
+621 48 2 0.0000 25.4080 -9.0900 19.5210 # CM
+622 48 2 0.0000 25.3500 -9.3190 19.0800 # CM
+623 48 2 0.0000 25.6030 -9.0960 18.7110 # CM
+624 48 3 0.0000 25.6570 -9.4190 18.3340 # CT
+625 49 1 -1.0000 34.6230 2.6960 -21.7750 # HG
+626 49 2 0.0000 34.1220 2.7040 -21.2170 # CM
+627 49 2 0.0000 33.6550 2.6260 -21.3760 # CM
+628 49 2 0.0000 33.2970 2.6490 -21.0280 # CM
+629 49 2 0.0000 32.8470 2.5400 -21.2180 # CM
+630 49 2 0.0000 32.5110 2.6560 -20.8660 # CM
+631 49 2 0.0000 32.0450 2.6110 -21.0430 # CM
+632 49 2 0.0000 31.7080 2.7470 -20.7010 # CM
+633 49 2 0.0000 31.2630 2.5490 -20.8130 # CM
+634 49 2 0.0000 30.9080 2.7020 -20.4940 # CM
+635 49 2 0.0000 30.4770 2.4720 -20.5970 # CM
+636 49 2 0.0000 30.1670 2.4540 -20.2050 # CM
+637 49 3 0.0000 29.7030 2.3690 -20.3690 # CT
+638 50 1 -1.0000 -8.5780 -1.1320 8.1340 # HG
+639 50 2 0.0000 -7.9630 -1.4600 8.4090 # CM
+640 50 2 0.0000 -7.5750 -1.4380 8.0940 # CM
+641 50 2 0.0000 -7.1570 -1.6700 8.2430 # CM
+642 50 2 0.0000 -6.7830 -1.6050 7.9170 # CM
+643 50 2 0.0000 -6.4170 -1.9160 8.0550 # CM
+644 50 2 0.0000 -6.0490 -1.9180 7.7170 # CM
+645 50 2 0.0000 -5.6910 -2.2430 7.8410 # CM
+646 50 2 0.0000 -5.2650 -2.1260 7.6070 # CM
+647 50 2 0.0000 -4.9060 -2.4630 7.6990 # CM
+648 50 2 0.0000 -4.4780 -2.3170 7.4860 # CM
+649 50 2 0.0000 -4.0750 -2.5160 7.7040 # CM
+650 50 3 0.0000 -3.6890 -2.4860 7.3880 # CT
+651 51 1 -1.0000 -16.3520 11.0720 -10.2110 # HG
+652 51 2 0.0000 -16.8840 10.5760 -10.3910 # CM
+653 51 2 0.0000 -17.3320 10.7890 -10.4570 # CM
+654 51 2 0.0000 -17.7110 10.4780 -10.5550 # CM
+655 51 2 0.0000 -18.1370 10.7260 -10.6420 # CM
+656 51 2 0.0000 -18.5020 10.3860 -10.6510 # CM
+657 51 2 0.0000 -18.9500 10.6060 -10.6790 # CM
+658 51 2 0.0000 -19.3190 10.2690 -10.6670 # CM
+659 51 2 0.0000 -19.7360 10.4660 -10.8590 # CM
+660 51 2 0.0000 -20.1220 10.1490 -10.8250 # CM
+661 51 2 0.0000 -20.5230 10.3450 -11.0490 # CM
+662 51 2 0.0000 -20.8520 9.9990 -11.1950 # CM
+663 51 3 0.0000 -21.2960 10.2170 -11.2670 # CT
+664 52 1 -1.0000 30.2530 -18.9470 25.1640 # HG
+665 52 2 0.0000 30.6880 -18.8400 25.7650 # CM
+666 52 2 0.0000 30.4730 -18.9970 26.1890 # CM
+667 52 2 0.0000 30.7320 -18.9170 26.6090 # CM
+668 52 2 0.0000 30.5010 -19.1100 27.0090 # CM
+669 52 2 0.0000 30.7420 -18.9370 27.4110 # CM
+670 52 2 0.0000 30.5020 -19.0660 27.8310 # CM
+671 52 2 0.0000 30.7290 -18.8780 28.2340 # CM
+672 52 2 0.0000 30.5960 -19.1350 28.6410 # CM
+673 52 2 0.0000 30.7920 -18.9370 29.0570 # CM
+674 52 2 0.0000 30.6790 -19.2230 29.4500 # CM
+675 52 2 0.0000 30.9980 -19.1670 29.8300 # CM
+676 52 3 0.0000 30.7830 -19.3310 30.2500 # CT
+677 53 1 -1.0000 -4.8950 -22.6450 -34.0140 # HG
+678 53 2 0.0000 -5.3620 -23.2120 -34.1680 # CM
+679 53 2 0.0000 -5.2920 -23.6060 -33.8690 # CM
+680 53 2 0.0000 -5.5750 -24.0070 -33.9640 # CM
+681 53 2 0.0000 -5.4970 -24.3720 -33.6300 # CM
+682 53 2 0.0000 -5.7290 -24.7790 -33.8050 # CM
+683 53 2 0.0000 -5.6250 -25.1780 -33.5230 # CM
+684 53 2 0.0000 -5.8380 -25.5900 -33.7070 # CM
+685 53 2 0.0000 -5.8740 -25.9380 -33.3500 # CM
+686 53 2 0.0000 -6.0580 -26.3680 -33.5300 # CM
+687 53 2 0.0000 -6.1200 -26.6940 -33.1570 # CM
+688 53 2 0.0000 -6.4610 -27.0450 -33.2600 # CM
+689 53 3 0.0000 -6.3910 -27.4340 -32.9540 # CT
+690 54 1 -1.0000 20.9440 19.6130 -9.8900 # HG
+691 54 2 0.0000 21.4990 20.0380 -10.1640 # CM
+692 54 2 0.0000 21.3340 20.4660 -10.3630 # CM
+693 54 2 0.0000 21.6810 20.7580 -10.5740 # CM
+694 54 2 0.0000 21.4850 21.1890 -10.7380 # CM
+695 54 2 0.0000 21.8370 21.4110 -11.0130 # CM
+696 54 2 0.0000 21.6560 21.8190 -11.2390 # CM
+697 54 2 0.0000 22.0000 22.0310 -11.5320 # CM
+698 54 2 0.0000 21.8800 22.5090 -11.6180 # CM
+699 54 2 0.0000 22.2000 22.7250 -11.9350 # CM
+700 54 2 0.0000 22.0880 23.2090 -11.9860 # CM
+701 54 2 0.0000 22.4770 23.4850 -12.1350 # CM
+702 54 3 0.0000 22.3070 23.9150 -12.3260 # CT
+703 55 1 -1.0000 -3.2460 0.9860 -13.1500 # HG
+704 55 2 0.0000 -3.0530 0.3830 -12.7490 # CM
+705 55 2 0.0000 -3.3150 0.3410 -12.3250 # CM
+706 55 2 0.0000 -3.1900 -0.0400 -12.0260 # CM
+707 55 2 0.0000 -3.4900 -0.0670 -11.6260 # CM
+708 55 2 0.0000 -3.2840 -0.4000 -11.3150 # CM
+709 55 2 0.0000 -3.5290 -0.4110 -10.8790 # CM
+710 55 2 0.0000 -3.3120 -0.7270 -10.5590 # CM
+711 55 2 0.0000 -3.6380 -0.8590 -10.2030 # CM
+712 55 2 0.0000 -3.4260 -1.1520 -9.8580 # CM
+713 55 2 0.0000 -3.7700 -1.3040 -9.5290 # CM
+714 55 2 0.0000 -3.6420 -1.7260 -9.2950 # CM
+715 55 3 0.0000 -3.9120 -1.7670 -8.8760 # CT
+716 56 1 -1.0000 -9.4470 -4.5190 -32.5540 # HG
+717 56 2 0.0000 -8.8630 -4.6230 -32.0950 # CM
+718 56 2 0.0000 -8.9700 -4.9270 -31.7130 # CM
+719 56 2 0.0000 -8.6060 -4.9960 -31.3780 # CM
+720 56 2 0.0000 -8.7380 -5.3270 -31.0260 # CM
+721 56 2 0.0000 -8.3880 -5.3040 -30.6690 # CM
+722 56 2 0.0000 -8.5190 -5.5810 -30.2740 # CM
+723 56 2 0.0000 -8.1820 -5.5440 -29.9080 # CM
+724 56 2 0.0000 -8.2220 -5.9340 -29.5980 # CM
+725 56 2 0.0000 -7.9100 -5.8930 -29.2090 # CM
+726 56 2 0.0000 -7.9370 -6.3050 -28.9260 # CM
+727 56 2 0.0000 -7.5270 -6.3790 -28.6520 # CM
+728 56 3 0.0000 -7.6360 -6.6900 -28.2760 # CT
+729 57 1 -1.0000 -29.1230 18.3160 26.7400 # HG
+730 57 2 0.0000 -29.3100 17.8360 27.2850 # CM
+731 57 2 0.0000 -28.9150 17.6870 27.5550 # CM
+732 57 2 0.0000 -29.0080 17.3490 27.9110 # CM
+733 57 2 0.0000 -28.5970 17.2440 28.1770 # CM
+734 57 2 0.0000 -28.7080 16.8480 28.4600 # CM
+735 57 2 0.0000 -28.3010 16.6810 28.6990 # CM
+736 57 2 0.0000 -28.4040 16.2720 28.9670 # CM
+737 57 2 0.0000 -28.0580 16.2090 29.3220 # CM
+738 57 2 0.0000 -28.1310 15.7850 29.5780 # CM
+739 57 2 0.0000 -27.7990 15.7520 29.9500 # CM
+740 57 2 0.0000 -27.9540 15.4560 30.3220 # CM
+741 57 3 0.0000 -27.5580 15.3170 30.5930 # CT
+742 58 1 -1.0000 5.8320 9.9880 0.3150 # HG
+743 58 2 0.0000 5.5850 10.6660 0.5180 # CM
+744 58 2 0.0000 5.2230 10.8380 0.2180 # CM
+745 58 2 0.0000 5.0550 11.2980 0.3160 # CM
+746 58 2 0.0000 4.6760 11.4260 0.0150 # CM
+747 58 2 0.0000 4.5950 11.9140 0.0850 # CM
+748 58 2 0.0000 4.2590 12.0870 -0.2420 # CM
+749 58 2 0.0000 4.1920 12.5790 -0.1880 # CM
+750 58 2 0.0000 3.7540 12.7140 -0.3890 # CM
+751 58 2 0.0000 3.6880 13.2100 -0.3690 # CM
+752 58 2 0.0000 3.2340 13.3270 -0.5410 # CM
+753 58 2 0.0000 3.0680 13.7650 -0.3690 # CM
+754 58 3 0.0000 2.7010 13.9290 -0.6670 # CT
+755 59 1 -1.0000 24.9110 12.1690 10.3220 # HG
+756 59 2 0.0000 25.4970 12.0460 9.8700 # CM
+757 59 2 0.0000 25.3640 12.0020 9.3890 # CM
+758 59 2 0.0000 25.7320 11.8970 9.0680 # CM
+759 59 2 0.0000 25.5680 11.8880 8.5950 # CM
+760 59 2 0.0000 25.9380 11.6980 8.3190 # CM
+761 59 2 0.0000 25.7870 11.6230 7.8470 # CM
+762 59 2 0.0000 26.1490 11.4130 7.5740 # CM
+763 59 2 0.0000 26.0620 11.4920 7.0880 # CM
+764 59 2 0.0000 26.4000 11.2610 6.8000 # CM
+765 59 2 0.0000 26.3210 11.3760 6.3200 # CM
+766 59 2 0.0000 26.7300 11.3220 6.0380 # CM
+767 59 3 0.0000 26.5930 11.2870 5.5590 # CT
+768 60 1 -1.0000 28.1520 -11.1160 6.7380 # HG
+769 60 2 0.0000 28.1780 -10.8250 6.0470 # CM
+770 60 2 0.0000 28.4710 -11.0880 5.7380 # CM
+771 60 2 0.0000 28.5240 -10.9030 5.2760 # CM
+772 60 2 0.0000 28.8010 -11.2050 4.9880 # CM
+773 60 2 0.0000 28.9020 -10.9500 4.5700 # CM
+774 60 2 0.0000 29.2240 -11.2020 4.2820 # CM
+775 60 2 0.0000 29.3440 -10.9400 3.8740 # CM
+776 60 2 0.0000 29.5210 -11.2470 3.5210 # CM
+777 60 2 0.0000 29.6740 -10.9940 3.1170 # CM
+778 60 2 0.0000 29.8170 -11.3140 2.7610 # CM
+779 60 2 0.0000 29.7960 -11.1160 2.3020 # CM
+780 60 3 0.0000 30.0840 -11.3860 1.9960 # CT
+781 61 1 -1.0000 23.2770 -10.3980 -9.2180 # HG
+782 61 2 0.0000 23.7370 -9.8100 -9.1510 # CM
+783 61 2 0.0000 24.0090 -9.8240 -8.7320 # CM
+784 61 2 0.0000 24.3080 -9.4320 -8.6500 # CM
+785 61 2 0.0000 24.5850 -9.4930 -8.2370 # CM
+786 61 2 0.0000 24.8020 -9.0530 -8.1440 # CM
+787 61 2 0.0000 25.0430 -9.0630 -7.7050 # CM
+788 61 2 0.0000 25.2430 -8.6180 -7.6000 # CM
+789 61 2 0.0000 25.6090 -8.6720 -7.2630 # CM
+790 61 2 0.0000 25.7990 -8.2300 -7.1250 # CM
+791 61 2 0.0000 26.1840 -8.3000 -6.8140 # CM
+792 61 2 0.0000 26.5000 -7.9130 -6.8070 # CM
+793 61 3 0.0000 26.7750 -7.9370 -6.3910 # CT
+794 62 1 -1.0000 -22.8400 3.8200 11.0360 # HG
+795 62 2 0.0000 -22.6130 4.4480 10.6960 # CM
+796 62 2 0.0000 -22.1240 4.4470 10.5940 # CM
+797 62 2 0.0000 -21.9410 4.8640 10.3870 # CM
+798 62 2 0.0000 -21.4560 4.8170 10.2740 # CM
+799 62 2 0.0000 -21.2930 5.2740 10.1520 # CM
+800 62 2 0.0000 -20.7970 5.2730 10.0870 # CM
+801 62 2 0.0000 -20.6280 5.7320 9.9850 # CM
+802 62 2 0.0000 -20.1810 5.7040 9.7630 # CM
+803 62 2 0.0000 -19.9860 6.1580 9.6830 # CM
+804 62 2 0.0000 -19.5570 6.1170 9.4310 # CM
+805 62 2 0.0000 -19.4370 6.5320 9.1810 # CM
+806 62 3 0.0000 -18.9490 6.5230 9.0740 # CT
+807 63 1 -1.0000 5.8050 9.0400 9.8490 # HG
+808 63 2 0.0000 5.9890 9.1790 9.1350 # CM
+809 63 2 0.0000 6.1940 8.7840 8.9080 # CM
+810 63 2 0.0000 6.3480 8.8560 8.4370 # CM
+811 63 2 0.0000 6.5220 8.4340 8.2330 # CM
+812 63 2 0.0000 6.7400 8.5620 7.8030 # CM
+813 63 2 0.0000 6.9750 8.1710 7.5980 # CM
+814 63 2 0.0000 7.2120 8.3020 7.1790 # CM
+815 63 2 0.0000 7.2980 7.8970 6.8980 # CM
+816 63 2 0.0000 7.5630 8.0090 6.4890 # CM
+817 63 2 0.0000 7.6130 7.6030 6.2020 # CM
+818 63 2 0.0000 7.7000 7.7130 5.7230 # CM
+819 63 3 0.0000 7.8980 7.3130 5.4980 # CT
+820 64 1 -1.0000 7.4660 -26.1890 34.8530 # HG
+821 64 2 0.0000 7.8940 -25.7120 34.4630 # CM
+822 64 2 0.0000 8.3640 -25.8740 34.4080 # CM
+823 64 2 0.0000 8.6770 -25.5650 34.1710 # CM
+824 64 2 0.0000 9.1290 -25.7710 34.1100 # CM
+825 64 2 0.0000 9.4320 -25.4070 33.9510 # CM
+826 64 2 0.0000 9.9060 -25.5660 33.9330 # CM
+827 64 2 0.0000 10.2140 -25.1980 33.7950 # CM
+828 64 2 0.0000 10.6410 -25.3900 33.6190 # CM
+829 64 2 0.0000 10.9720 -25.0320 33.5050 # CM
+830 64 2 0.0000 11.3790 -25.2350 33.3010 # CM
+831 64 2 0.0000 11.6350 -24.9150 33.0160 # CM
+832 64 3 0.0000 12.1010 -25.0850 32.9570 # CT
+833 65 1 -1.0000 -27.9910 -34.4270 -5.7340 # HG
+834 65 2 0.0000 -27.5340 -33.9050 -5.4500 # CM
+835 65 2 0.0000 -27.7020 -33.4400 -5.5250 # CM
+836 65 2 0.0000 -27.4050 -33.0710 -5.3660 # CM
+837 65 2 0.0000 -27.6170 -32.6220 -5.4320 # CM
+838 65 2 0.0000 -27.2620 -32.2810 -5.3430 # CM
+839 65 2 0.0000 -27.4240 -31.8220 -5.4550 # CM
+840 65 2 0.0000 -27.0650 -31.4820 -5.3870 # CM
+841 65 2 0.0000 -27.2670 -31.0270 -5.3360 # CM
+842 65 2 0.0000 -26.9160 -30.6730 -5.2980 # CM
+843 65 2 0.0000 -27.1320 -30.2300 -5.2140 # CM
+844 65 2 0.0000 -26.8250 -29.9030 -4.9930 # CM
+845 65 3 0.0000 -27.0010 -29.4410 -5.0630 # CT
+846 66 1 -1.0000 -6.8770 -20.8090 -16.6430 # HG
+847 66 2 0.0000 -6.7540 -21.1990 -16.0150 # CM
+848 66 2 0.0000 -7.1670 -21.2530 -15.7380 # CM
+849 66 2 0.0000 -7.1090 -21.4900 -15.3010 # CM
+850 66 2 0.0000 -7.5460 -21.5500 -15.0640 # CM
+851 66 2 0.0000 -7.4380 -21.7090 -14.6030 # CM
+852 66 2 0.0000 -7.8490 -21.7260 -14.3190 # CM
+853 66 2 0.0000 -7.7410 -21.8650 -13.8520 # CM
+854 66 2 0.0000 -8.1520 -22.0390 -13.6270 # CM
+855 66 2 0.0000 -8.0650 -22.1530 -13.1470 # CM
+856 66 2 0.0000 -8.4740 -22.3560 -12.9440 # CM
+857 66 2 0.0000 -8.3720 -22.6420 -12.5470 # CM
+858 66 3 0.0000 -8.7890 -22.7000 -12.2780 # CT
+859 67 1 -1.0000 30.2170 1.2570 -6.9870 # HG
+860 67 2 0.0000 30.5650 1.8500 -6.6870 # CM
+861 67 2 0.0000 30.3910 1.9670 -6.2330 # CM
+862 67 2 0.0000 30.5900 2.3730 -6.0200 # CM
+863 67 2 0.0000 30.4120 2.4440 -5.5570 # CM
+864 67 2 0.0000 30.5660 2.8970 -5.4130 # CM
+865 67 2 0.0000 30.3590 3.0240 -4.9750 # CM
+866 67 2 0.0000 30.4940 3.4850 -4.8390 # CM
+867 67 2 0.0000 30.4300 3.5430 -4.3470 # CM
+868 67 2 0.0000 30.5320 4.0110 -4.2010 # CM
+869 67 2 0.0000 30.4960 4.0460 -3.7040 # CM
+870 67 2 0.0000 30.7620 4.4240 -3.5160 # CM
+871 67 3 0.0000 30.5900 4.5330 -3.0600 # CT
+872 68 1 -1.0000 22.1670 3.8430 10.0030 # HG
+873 68 2 0.0000 21.6170 3.7270 10.4990 # CM
+874 68 2 0.0000 21.4630 4.1490 10.7180 # CM
+875 68 2 0.0000 21.1120 4.0990 11.0710 # CM
+876 68 2 0.0000 20.9630 4.5420 11.2480 # CM
+877 68 2 0.0000 20.6810 4.4480 11.6500 # CM
+878 68 2 0.0000 20.5610 4.8720 11.8870 # CM
+879 68 2 0.0000 20.2970 4.7800 12.3000 # CM
+880 68 2 0.0000 20.0440 5.1890 12.4360 # CM
+881 68 2 0.0000 19.7990 5.1200 12.8670 # CM
+882 68 2 0.0000 19.5250 5.5240 12.9730 # CM
+883 68 2 0.0000 19.1410 5.4240 13.2760 # CM
+884 68 3 0.0000 18.9860 5.8500 13.4870 # CT
+885 69 1 -1.0000 6.0820 -22.8670 -9.2050 # HG
+886 69 2 0.0000 5.9800 -22.1260 -9.1490 # CM
+887 69 2 0.0000 5.4970 -21.9970 -9.1480 # CM
+888 69 2 0.0000 5.4000 -21.5070 -9.1340 # CM
+889 69 2 0.0000 4.9090 -21.4160 -9.1070 # CM
+890 69 2 0.0000 4.8500 -20.9250 -9.1820 # CM
+891 69 2 0.0000 4.3640 -20.8080 -9.2170 # CM
+892 69 2 0.0000 4.3030 -20.3220 -9.3120 # CM
+893 69 2 0.0000 3.8410 -20.1800 -9.1830 # CM
+894 69 2 0.0000 3.7550 -19.7010 -9.3020 # CM
+895 69 2 0.0000 3.3040 -19.5640 -9.1380 # CM
+896 69 2 0.0000 3.2630 -19.0710 -9.0720 # CM
+897 69 3 0.0000 2.7780 -18.9480 -9.0640 # CT
+898 70 1 -1.0000 -15.2240 4.5810 -34.9860 # HG
+899 70 2 0.0000 -15.4540 5.0550 -34.4520 # CM
+900 70 2 0.0000 -15.5560 4.8240 -34.0200 # CM
+901 70 2 0.0000 -15.7340 5.1140 -33.6530 # CM
+902 70 2 0.0000 -15.7980 4.8560 -33.2290 # CM
+903 70 2 0.0000 -16.0530 5.1530 -32.9180 # CM
+904 70 2 0.0000 -16.1830 4.9060 -32.5030 # CM
+905 70 2 0.0000 -16.4560 5.1940 -32.2000 # CM
+906 70 2 0.0000 -16.4410 5.0130 -31.7340 # CM
+907 70 2 0.0000 -16.7360 5.2740 -31.4250 # CM
+908 70 2 0.0000 -16.6860 5.1040 -30.9580 # CM
+909 70 2 0.0000 -16.8100 5.4430 -30.6130 # CM
+910 70 3 0.0000 -16.9030 5.2090 -30.1820 # CT
+911 71 1 -1.0000 9.8100 -4.6590 11.9230 # HG
+912 71 2 0.0000 9.1430 -4.9400 12.1220 # CM
+913 71 2 0.0000 9.1830 -5.3550 12.3970 # CM
+914 71 2 0.0000 8.7530 -5.5760 12.5240 # CM
+915 71 2 0.0000 8.8290 -5.9720 12.8210 # CM
+916 71 2 0.0000 8.3920 -6.2120 12.8550 # CM
+917 71 2 0.0000 8.4460 -6.6450 13.1000 # CM
+918 71 2 0.0000 8.0150 -6.8980 13.1160 # CM
+919 71 2 0.0000 8.0270 -7.2310 13.4890 # CM
+920 71 2 0.0000 7.6130 -7.5120 13.4980 # CM
+921 71 2 0.0000 7.6240 -7.8160 13.8940 # CM
+922 71 2 0.0000 7.1690 -7.9670 14.0360 # CM
+923 71 3 0.0000 7.2140 -8.3770 14.3170 # CT
+924 72 1 -1.0000 31.0240 -5.7150 4.8870 # HG
+925 72 2 0.0000 30.9440 -6.0900 4.2420 # CM
+926 72 2 0.0000 30.5150 -6.3450 4.2200 # CM
+927 72 2 0.0000 30.4450 -6.6230 3.8100 # CM
+928 72 2 0.0000 29.9950 -6.8410 3.8090 # CM
+929 72 2 0.0000 29.9970 -7.1720 3.4340 # CM
+930 72 2 0.0000 29.5810 -7.4490 3.4390 # CM
+931 72 2 0.0000 29.5900 -7.7940 3.0780 # CM
+932 72 2 0.0000 29.1250 -7.9500 2.9790 # CM
+933 72 2 0.0000 29.1220 -8.3180 2.6410 # CM
+934 72 2 0.0000 28.6510 -8.4410 2.5270 # CM
+935 72 2 0.0000 28.6090 -8.6580 2.0790 # CM
+936 72 3 0.0000 28.1760 -8.9050 2.0590 # CT
+937 73 1 -1.0000 -12.0680 -31.8420 31.6140 # HG
+938 73 2 0.0000 -11.3660 -31.7720 31.8680 # CM
+939 73 2 0.0000 -11.1920 -31.3040 31.8310 # CM
+940 73 2 0.0000 -10.7180 -31.2340 31.9720 # CM
+941 73 2 0.0000 -10.5880 -30.7510 31.9470 # CM
+942 73 2 0.0000 -10.0920 -30.7330 32.0110 # CM
+943 73 2 0.0000 -9.9200 -30.2690 31.9370 # CM
+944 73 2 0.0000 -9.4230 -30.2520 31.9790 # CM
+945 73 2 0.0000 -9.2760 -29.7830 32.0700 # CM
+946 73 2 0.0000 -8.7770 -29.7460 32.0840 # CM
+947 73 2 0.0000 -8.6440 -29.2810 32.2090 # CM
+948 73 2 0.0000 -8.1870 -29.2560 32.4090 # CM
+949 73 3 0.0000 -8.0220 -28.7850 32.3770 # CT
+950 74 1 -1.0000 -31.7970 20.7880 7.1730 # HG
+951 74 2 0.0000 -31.1200 20.7740 7.4960 # CM
+952 74 2 0.0000 -30.9640 21.2290 7.6360 # CM
+953 74 2 0.0000 -30.5060 21.2520 7.8340 # CM
+954 74 2 0.0000 -30.3940 21.7160 7.9870 # CM
+955 74 2 0.0000 -29.9070 21.7170 8.0970 # CM
+956 74 2 0.0000 -29.7480 22.1800 8.2000 # CM
+957 74 2 0.0000 -29.2570 22.1870 8.2900 # CM
+958 74 2 0.0000 -29.1370 22.5980 8.5470 # CM
+959 74 2 0.0000 -28.6430 22.6340 8.6180 # CM
+960 74 2 0.0000 -28.5400 23.0300 8.9040 # CM
+961 74 2 0.0000 -28.1020 22.9910 9.1410 # CM
+962 74 3 0.0000 -27.9540 23.4460 9.2850 # CT
+963 75 1 -1.0000 7.1710 22.7840 -1.9740 # HG
+964 75 2 0.0000 7.2450 23.4460 -2.3190 # CM
+965 75 2 0.0000 6.8630 23.5470 -2.6260 # CM
+966 75 2 0.0000 6.8970 23.9720 -2.8870 # CM
+967 75 2 0.0000 6.4870 24.0550 -3.1610 # CM
+968 75 2 0.0000 6.5930 24.4360 -3.4670 # CM
+969 75 2 0.0000 6.2230 24.5080 -3.7960 # CM
+970 75 2 0.0000 6.3360 24.8750 -4.1160 # CM
+971 75 2 0.0000 5.9180 25.0530 -4.3240 # CM
+972 75 2 0.0000 6.0180 25.4010 -4.6700 # CM
+973 75 2 0.0000 5.5920 25.5940 -4.8450 # CM
+974 75 2 0.0000 5.6510 26.0500 -5.0410 # CM
+975 75 3 0.0000 5.2640 26.1500 -5.3400 # CT
+976 76 1 -1.0000 -27.1790 1.5340 -6.4720 # HG
+977 76 2 0.0000 -26.7600 2.1080 -6.2330 # CM
+978 76 2 0.0000 -26.8980 2.5450 -6.4350 # CM
+979 76 2 0.0000 -26.6210 2.9420 -6.3100 # CM
+980 76 2 0.0000 -26.8030 3.3640 -6.5080 # CM
+981 76 2 0.0000 -26.4570 3.7180 -6.4340 # CM
+982 76 2 0.0000 -26.5830 4.1410 -6.6690 # CM
+983 76 2 0.0000 -26.2300 4.4890 -6.6150 # CM
+984 76 2 0.0000 -26.4230 4.9430 -6.6990 # CM
+985 76 2 0.0000 -26.0720 5.2990 -6.6780 # CM
+986 76 2 0.0000 -26.2830 5.7490 -6.7310 # CM
+987 76 2 0.0000 -26.0080 6.1170 -6.5360 # CM
+988 76 3 0.0000 -26.1550 6.5520 -6.7340 # CT
+989 77 1 -1.0000 16.5480 25.3040 -19.7430 # HG
+990 77 2 0.0000 16.7010 24.9170 -19.1180 # CM
+991 77 2 0.0000 16.6480 24.4240 -19.1790 # CM
+992 77 2 0.0000 16.7220 24.1430 -18.7710 # CM
+993 77 2 0.0000 16.6870 23.6550 -18.8750 # CM
+994 77 2 0.0000 16.6810 23.4160 -18.4360 # CM
+995 77 2 0.0000 16.5910 22.9280 -18.5000 # CM
+996 77 2 0.0000 16.5630 22.6900 -18.0620 # CM
+997 77 2 0.0000 16.6410 22.2000 -18.1290 # CM
+998 77 2 0.0000 16.5850 21.9450 -17.7020 # CM
+999 77 2 0.0000 16.6980 21.4640 -17.7760 # CM
+1000 77 2 0.0000 16.8320 21.2290 -17.3560 # CM
+1001 77 3 0.0000 16.7850 20.7360 -17.4240 # CT
+1002 78 1 -1.0000 -1.2310 5.7730 15.3280 # HG
+1003 78 2 0.0000 -1.9070 6.0730 15.2040 # CM
+1004 78 2 0.0000 -1.9550 6.2540 14.7400 # CM
+1005 78 2 0.0000 -2.3880 6.4810 14.6360 # CM
+1006 78 2 0.0000 -2.4120 6.6250 14.1570 # CM
+1007 78 2 0.0000 -2.8150 6.9180 14.1160 # CM
+1008 78 2 0.0000 -2.8370 7.1250 13.6610 # CM
+1009 78 2 0.0000 -3.2270 7.4350 13.6230 # CM
+1010 78 2 0.0000 -3.3430 7.5050 13.1420 # CM
+1011 78 2 0.0000 -3.7130 7.8380 13.0880 # CM
+1012 78 2 0.0000 -3.8400 7.8740 12.6060 # CM
+1013 78 2 0.0000 -4.3060 8.0420 12.5400 # CM
+1014 78 3 0.0000 -4.3510 8.2150 12.0730 # CT
+1015 79 1 -1.0000 -2.9380 20.6540 4.9820 # HG
+1016 79 2 0.0000 -2.2410 20.4250 5.1350 # CM
+1017 79 2 0.0000 -1.9020 20.7890 5.0850 # CM
+1018 79 2 0.0000 -1.4250 20.6590 5.1590 # CM
+1019 79 2 0.0000 -1.1180 21.0530 5.1280 # CM
+1020 79 2 0.0000 -0.6530 20.8720 5.1210 # CM
+1021 79 2 0.0000 -0.3210 21.2360 5.0340 # CM
+1022 79 2 0.0000 0.1430 21.0540 5.0060 # CM
+1023 79 2 0.0000 0.4740 21.4210 5.0860 # CM
+1024 79 2 0.0000 0.9450 21.2590 5.0310 # CM
+1025 79 2 0.0000 1.2650 21.6250 5.1460 # CM
+1026 79 2 0.0000 1.7150 21.4550 5.2800 # CM
+1027 79 3 0.0000 2.0480 21.8250 5.2350 # CT
+1028 80 1 -1.0000 -17.8220 19.7820 11.0140 # HG
+1029 80 2 0.0000 -18.5490 19.6830 11.1710 # CM
+1030 80 2 0.0000 -18.6660 19.2030 11.2510 # CM
+1031 80 2 0.0000 -19.1490 19.1060 11.3350 # CM
+1032 80 2 0.0000 -19.2250 18.6220 11.4370 # CM
+1033 80 2 0.0000 -19.7190 18.5490 11.4300 # CM
+1034 80 2 0.0000 -19.8290 18.0630 11.4730 # CM
+1035 80 2 0.0000 -20.3210 17.9860 11.4460 # CM
+1036 80 2 0.0000 -20.4360 17.5440 11.6500 # CM
+1037 80 2 0.0000 -20.9230 17.4400 11.6020 # CM
+1038 80 2 0.0000 -21.0300 17.0140 11.8390 # CM
+1039 80 2 0.0000 -21.5110 16.9780 11.9680 # CM
+1040 80 3 0.0000 -21.6210 16.4980 12.0540 # CT
+1041 81 1 -1.0000 -2.4990 -26.4010 -17.2150 # HG
+1042 81 2 0.0000 -2.9680 -26.9310 -16.9660 # CM
+1043 81 2 0.0000 -3.3470 -27.0160 -17.2810 # CM
+1044 81 2 0.0000 -3.6880 -27.3490 -17.1290 # CM
+1045 81 2 0.0000 -4.0370 -27.4290 -17.4790 # CM
+1046 81 2 0.0000 -4.3990 -27.6950 -17.2620 # CM
+1047 81 2 0.0000 -4.7910 -27.7460 -17.5690 # CM
+1048 81 2 0.0000 -5.1630 -27.9940 -17.3460 # CM
+1049 81 2 0.0000 -5.4710 -28.1840 -17.6910 # CM
+1050 81 2 0.0000 -5.8660 -28.4090 -17.4820 # CM
+1051 81 2 0.0000 -6.1470 -28.6240 -17.8350 # CM
+1052 81 2 0.0000 -6.4280 -28.9980 -17.6600 # CM
+1053 81 3 0.0000 -6.8010 -29.0840 -17.9820 # CT
+1054 82 1 -1.0000 25.3930 -0.1350 12.3660 # HG
+1055 82 2 0.0000 26.0430 -0.0900 12.7380 # CM
+1056 82 2 0.0000 26.4130 0.0950 12.4580 # CM
+1057 82 2 0.0000 26.8640 0.1150 12.6740 # CM
+1058 82 2 0.0000 27.2030 0.3300 12.3760 # CM
+1059 82 2 0.0000 27.6490 0.2540 12.5880 # CM
+1060 82 2 0.0000 28.0180 0.4080 12.2870 # CM
+1061 82 2 0.0000 28.4650 0.3150 12.4870 # CM
+1062 82 2 0.0000 28.8110 0.6080 12.2770 # CM
+1063 82 2 0.0000 29.2700 0.5030 12.4470 # CM
+1064 82 2 0.0000 29.6000 0.8240 12.2540 # CM
+1065 82 2 0.0000 30.0130 0.8700 12.5310 # CM
+1066 82 3 0.0000 30.3780 1.0620 12.2500 # CT
+1067 83 1 -1.0000 -20.7300 11.2740 -31.3650 # HG
+1068 83 2 0.0000 -20.3350 10.6410 -31.4380 # CM
+1069 83 2 0.0000 -20.5770 10.2400 -31.2630 # CM
+1070 83 2 0.0000 -20.3280 9.8080 -31.2780 # CM
+1071 83 2 0.0000 -20.6100 9.4250 -31.1200 # CM
+1072 83 2 0.0000 -20.3040 9.0330 -31.0700 # CM
+1073 83 2 0.0000 -20.5430 8.6470 -30.8590 # CM
+1074 83 2 0.0000 -20.2350 8.2610 -30.7880 # CM
+1075 83 2 0.0000 -20.4990 7.8390 -30.7400 # CM
+1076 83 2 0.0000 -20.2040 7.4480 -30.6370 # CM
+1077 83 2 0.0000 -20.4750 7.0290 -30.6240 # CM
+1078 83 2 0.0000 -20.2040 6.6190 -30.7100 # CM
+1079 83 3 0.0000 -20.4540 6.2210 -30.5400 # CT
+1080 84 1 -1.0000 -23.5050 -28.7830 33.7190 # HG
+1081 84 2 0.0000 -23.6820 -29.5120 33.7270 # CM
+1082 84 2 0.0000 -24.0620 -29.6220 33.4210 # CM
+1083 84 2 0.0000 -24.2150 -30.0980 33.4230 # CM
+1084 84 2 0.0000 -24.5770 -30.1770 33.0860 # CM
+1085 84 2 0.0000 -24.7600 -30.6330 33.1770 # CM
+1086 84 2 0.0000 -25.1620 -30.7230 32.8940 # CM
+1087 84 2 0.0000 -25.3600 -31.1690 32.9980 # CM
+1088 84 2 0.0000 -25.6430 -31.3240 32.6160 # CM
+1089 84 2 0.0000 -25.8720 -31.7560 32.7190 # CM
+1090 84 2 0.0000 -26.1240 -31.9150 32.3180 # CM
+1091 84 2 0.0000 -26.2030 -32.4080 32.3200 # CM
+1092 84 3 0.0000 -26.5780 -32.5140 32.0070 # CT
+1093 85 1 -1.0000 -16.8550 -29.6230 9.3970 # HG
+1094 85 2 0.0000 -16.7670 -28.8850 9.4980 # CM
+1095 85 2 0.0000 -17.1970 -28.6520 9.6020 # CM
+1096 85 2 0.0000 -17.1720 -28.1550 9.6510 # CM
+1097 85 2 0.0000 -17.6140 -27.9590 9.7810 # CM
+1098 85 2 0.0000 -17.5700 -27.4640 9.7370 # CM
+1099 85 2 0.0000 -18.0110 -27.2390 9.8060 # CM
+1100 85 2 0.0000 -17.9740 -26.7450 9.7410 # CM
+1101 85 2 0.0000 -18.3560 -26.5140 9.9670 # CM
+1102 85 2 0.0000 -18.3490 -26.0210 9.8840 # CM
+1103 85 2 0.0000 -18.7150 -25.8000 10.1410 # CM
+1104 85 2 0.0000 -18.6260 -25.3170 10.2310 # CM
+1105 85 3 0.0000 -19.0580 -25.0900 10.3420 # CT
+1106 86 1 -1.0000 -30.4630 -1.7140 30.7230 # HG
+1107 86 2 0.0000 -31.1910 -1.6980 30.9010 # CM
+1108 86 2 0.0000 -31.3840 -2.1540 30.9660 # CM
+1109 86 2 0.0000 -31.8740 -2.1740 31.0630 # CM
+1110 86 2 0.0000 -32.0260 -2.6430 31.1490 # CM
+1111 86 2 0.0000 -32.5260 -2.6320 31.1570 # CM
+1112 86 2 0.0000 -32.7140 -3.0950 31.1850 # CM
+1113 86 2 0.0000 -33.2130 -3.0890 31.1710 # CM
+1114 86 2 0.0000 -33.3940 -3.5140 31.3620 # CM
+1115 86 2 0.0000 -33.8930 -3.5330 31.3270 # CM
+1116 86 2 0.0000 -34.0630 -3.9470 31.5510 # CM
+1117 86 2 0.0000 -34.5390 -3.9080 31.6950 # CM
+1118 86 3 0.0000 -34.7250 -4.3660 31.7660 # CT
+1119 87 1 -1.0000 9.1890 0.2020 -22.4450 # HG
+1120 87 2 0.0000 9.8890 0.4460 -22.3310 # CM
+1121 87 2 0.0000 10.0390 0.7710 -22.6810 # CM
+1122 87 2 0.0000 10.5110 0.9330 -22.6420 # CM
+1123 87 2 0.0000 10.6180 1.2760 -22.9910 # CM
+1124 87 2 0.0000 11.1120 1.3480 -22.9750 # CM
+1125 87 2 0.0000 11.2610 1.6440 -23.3490 # CM
+1126 87 2 0.0000 11.7570 1.7000 -23.3480 # CM
+1127 87 2 0.0000 11.8830 2.1120 -23.6030 # CM
+1128 87 2 0.0000 12.3790 2.1640 -23.6360 # CM
+1129 87 2 0.0000 12.4900 2.5950 -23.8630 # CM
+1130 87 2 0.0000 12.9470 2.7620 -23.7500 # CM
+1131 87 3 0.0000 13.0890 3.0920 -24.0980 # CT
+1132 88 1 -1.0000 -13.7950 -10.8650 2.3730 # HG
+1133 88 2 0.0000 -14.4540 -10.5080 2.3400 # CM
+1134 88 2 0.0000 -14.8390 -10.8010 2.4650 # CM
+1135 88 2 0.0000 -15.2930 -10.5950 2.4300 # CM
+1136 88 2 0.0000 -15.6510 -10.9070 2.5890 # CM
+1137 88 2 0.0000 -16.0880 -10.7020 2.4590 # CM
+1138 88 2 0.0000 -16.4660 -11.0150 2.5530 # CM
+1139 88 2 0.0000 -16.9020 -10.8210 2.4060 # CM
+1140 88 2 0.0000 -17.2790 -11.0480 2.6430 # CM
+1141 88 2 0.0000 -17.7230 -10.8840 2.4820 # CM
+1142 88 2 0.0000 -18.0890 -11.0940 2.7500 # CM
+1143 88 2 0.0000 -18.5110 -10.8270 2.7470 # CM
+1144 88 3 0.0000 -18.8910 -11.1220 2.8800 # CT
+1145 89 1 -1.0000 12.4620 13.5100 -14.4030 # HG
+1146 89 2 0.0000 13.1190 13.6950 -14.7140 # CM
+1147 89 2 0.0000 13.3950 13.2960 -14.8340 # CM
+1148 89 2 0.0000 13.8490 13.3900 -15.0220 # CM
+1149 89 2 0.0000 14.0850 12.9690 -15.1550 # CM
+1150 89 2 0.0000 14.5580 13.0960 -15.2560 # CM
+1151 89 2 0.0000 14.8370 12.6900 -15.3390 # CM
+1152 89 2 0.0000 15.3150 12.8130 -15.4190 # CM
+1153 89 2 0.0000 15.5480 12.4410 -15.6590 # CM
+1154 89 2 0.0000 16.0350 12.5380 -15.7190 # CM
+1155 89 2 0.0000 16.2490 12.1750 -15.9880 # CM
+1156 89 2 0.0000 16.6670 12.3240 -16.2180 # CM
+1157 89 3 0.0000 16.9350 11.9210 -16.3420 # CT
+1158 90 1 -1.0000 -10.9890 33.4330 -17.9640 # HG
+1159 90 2 0.0000 -11.0810 33.7020 -18.6580 # CM
+1160 90 2 0.0000 -10.7560 33.5080 -18.9850 # CM
+1161 90 2 0.0000 -10.7800 33.6870 -19.4510 # CM
+1162 90 2 0.0000 -10.4610 33.4510 -19.7560 # CM
+1163 90 2 0.0000 -10.4520 33.7110 -20.1830 # CM
+1164 90 2 0.0000 -10.1000 33.5340 -20.4910 # CM
+1165 90 2 0.0000 -10.0740 33.8050 -20.9100 # CM
+1166 90 2 0.0000 -9.8540 33.5400 -21.2720 # CM
+1167 90 2 0.0000 -9.7940 33.8100 -21.6880 # CM
+1168 90 2 0.0000 -9.6040 33.5240 -22.0510 # CM
+1169 90 2 0.0000 -9.7030 33.6980 -22.5080 # CM
+1170 90 3 0.0000 -9.3820 33.4950 -22.8320 # CT
+1171 91 1 -1.0000 -27.3220 29.0730 -11.7090 # HG
+1172 91 2 0.0000 -26.8820 29.2830 -12.2790 # CM
+1173 91 2 0.0000 -27.0300 29.7130 -12.4880 # CM
+1174 91 2 0.0000 -26.7670 29.8660 -12.8850 # CM
+1175 91 2 0.0000 -26.9250 30.3110 -13.0510 # CM
+1176 91 2 0.0000 -26.7010 30.3870 -13.4920 # CM
+1177 91 2 0.0000 -26.8800 30.7990 -13.7130 # CM
+1178 91 2 0.0000 -26.6730 30.8660 -14.1630 # CM
+1179 91 2 0.0000 -26.7210 31.3430 -14.3020 # CM
+1180 91 2 0.0000 -26.5450 31.4180 -14.7650 # CM
+1181 91 2 0.0000 -26.5680 31.9040 -14.8790 # CM
+1182 91 2 0.0000 -26.2450 32.0360 -15.2350 # CM
+1183 91 3 0.0000 -26.3920 32.4700 -15.4360 # CT
+1184 92 1 -1.0000 25.2650 7.6990 -28.0560 # HG
+1185 92 2 0.0000 24.6880 8.1310 -28.2650 # CM
+1186 92 2 0.0000 24.7600 8.6140 -28.1590 # CM
+1187 92 2 0.0000 24.3810 8.9220 -28.2660 # CM
+1188 92 2 0.0000 24.4980 9.4000 -28.1730 # CM
+1189 92 2 0.0000 24.0740 9.6610 -28.2100 # CM
+1190 92 2 0.0000 24.1440 10.1350 -28.0670 # CM
+1191 92 2 0.0000 23.7180 10.3940 -28.0830 # CM
+1192 92 2 0.0000 23.8160 10.8840 -28.1050 # CM
+1193 92 2 0.0000 23.3960 11.1560 -28.0910 # CM
+1194 92 2 0.0000 23.5070 11.6410 -28.1460 # CM
+1195 92 2 0.0000 23.1220 11.9090 -28.3190 # CM
+1196 92 3 0.0000 23.2030 12.3910 -28.2180 # CT
+1197 93 1 -1.0000 -32.5140 -6.1920 29.9220 # HG
+1198 93 2 0.0000 -32.0810 -6.7940 30.0290 # CM
+1199 93 2 0.0000 -31.5930 -6.6870 30.0070 # CM
+1200 93 2 0.0000 -31.2800 -7.0750 30.0530 # CM
+1201 93 2 0.0000 -30.8020 -6.9280 30.0540 # CM
+1202 93 2 0.0000 -30.5250 -7.3420 30.0150 # CM
+1203 93 2 0.0000 -30.0410 -7.2270 29.9560 # CM
+1204 93 2 0.0000 -29.7650 -7.6380 29.8960 # CM
+1205 93 2 0.0000 -29.2860 -7.5390 30.0030 # CM
+1206 93 2 0.0000 -28.9920 -7.9350 29.9170 # CM
+1207 93 2 0.0000 -28.5250 -7.8330 30.0610 # CM
+1208 93 2 0.0000 -28.2590 -8.2440 30.1630 # CM
+1209 93 3 0.0000 -27.7730 -8.1300 30.1470 # CT
+1210 94 1 -1.0000 6.8770 -20.7190 -2.2810 # HG
+1211 94 2 0.0000 6.8990 -20.6120 -3.0230 # CM
+1212 94 2 0.0000 7.3400 -20.7390 -3.2230 # CM
+1213 94 2 0.0000 7.3900 -20.6570 -3.7140 # CM
+1214 94 2 0.0000 7.8320 -20.8200 -3.8840 # CM
+1215 94 2 0.0000 7.8790 -20.6450 -4.3500 # CM
+1216 94 2 0.0000 8.3350 -20.7430 -4.5310 # CM
+1217 94 2 0.0000 8.3920 -20.5510 -4.9890 # CM
+1218 94 2 0.0000 8.7660 -20.7840 -5.2260 # CM
+1219 94 2 0.0000 8.8540 -20.5810 -5.6740 # CM
+1220 94 2 0.0000 9.2060 -20.8440 -5.9130 # CM
+1221 94 2 0.0000 9.1860 -20.7890 -6.4090 # CM
+1222 94 3 0.0000 9.6250 -20.9250 -6.6050 # CT
+1223 95 1 -1.0000 32.6780 16.4830 5.0020 # HG
+1224 95 2 0.0000 32.4320 17.0700 5.3980 # CM
+1225 95 2 0.0000 32.6380 17.0960 5.8530 # CM
+1226 95 2 0.0000 32.4740 17.4660 6.1480 # CM
+1227 95 2 0.0000 32.7200 17.4780 6.5840 # CM
+1228 95 2 0.0000 32.4750 17.7980 6.8780 # CM
+1229 95 2 0.0000 32.6610 17.7920 7.3420 # CM
+1230 95 2 0.0000 32.4050 18.0960 7.6440 # CM
+1231 95 2 0.0000 32.6820 18.2150 8.0420 # CM
+1232 95 2 0.0000 32.4250 18.4950 8.3690 # CM
+1233 95 2 0.0000 32.7240 18.6330 8.7450 # CM
+1234 95 2 0.0000 32.5650 19.0470 8.9760 # CM
+1235 95 3 0.0000 32.7790 19.0720 9.4270 # CT
+1236 96 1 -1.0000 15.5780 -14.9380 23.2080 # HG
+1237 96 2 0.0000 15.8020 -14.9990 23.9220 # CM
+1238 96 2 0.0000 15.4410 -15.1710 24.2230 # CM
+1239 96 2 0.0000 15.5560 -15.2000 24.7090 # CM
+1240 96 2 0.0000 15.1830 -15.4010 24.9750 # CM
+1241 96 2 0.0000 15.2990 -15.3340 25.4570 # CM
+1242 96 2 0.0000 14.9200 -15.4740 25.7520 # CM
+1243 96 2 0.0000 15.0250 -15.3890 26.2330 # CM
+1244 96 2 0.0000 14.7330 -15.6720 26.5240 # CM
+1245 96 2 0.0000 14.8060 -15.5740 27.0090 # CM
+1246 96 2 0.0000 14.5330 -15.8860 27.2880 # CM
+1247 96 2 0.0000 14.7150 -15.9430 27.7500 # CM
+1248 96 3 0.0000 14.3530 -16.1220 28.0450 # CT
+1249 97 1 -1.0000 14.7010 29.7570 19.7670 # HG
+1250 97 2 0.0000 14.6740 29.3340 19.1480 # CM
+1251 97 2 0.0000 14.5900 28.8510 19.2470 # CM
+1252 97 2 0.0000 14.5900 28.5430 18.8540 # CM
+1253 97 2 0.0000 14.4760 28.0740 18.9860 # CM
+1254 97 2 0.0000 14.5700 27.7860 18.5890 # CM
+1255 97 2 0.0000 14.5200 27.3020 18.7040 # CM
+1256 97 2 0.0000 14.6330 27.0110 18.3150 # CM
+1257 97 2 0.0000 14.4280 26.5590 18.3740 # CM
+1258 97 2 0.0000 14.5590 26.2470 18.0060 # CM
+1259 97 2 0.0000 14.3210 25.8110 18.0600 # CM
+1260 97 2 0.0000 14.2810 25.5570 17.6320 # CM
+1261 97 3 0.0000 14.1890 25.0770 17.7350 # CT
+1262 98 1 -1.0000 27.5750 -12.9640 30.3750 # HG
+1263 98 2 0.0000 27.5830 -12.2550 30.1310 # CM
+1264 98 2 0.0000 27.7190 -12.2170 29.6510 # CM
+1265 98 2 0.0000 27.7550 -11.7530 29.4690 # CM
+1266 98 2 0.0000 27.8660 -11.7550 28.9810 # CM
+1267 98 2 0.0000 27.9770 -11.2830 28.8570 # CM
+1268 98 2 0.0000 28.1470 -11.2580 28.3880 # CM
+1269 98 2 0.0000 28.2780 -10.7910 28.2690 # CM
+1270 98 2 0.0000 28.2860 -10.7370 27.7720 # CM
+1271 98 2 0.0000 28.4450 -10.2820 27.6380 # CM
+1272 98 2 0.0000 28.4160 -10.2320 27.1410 # CM
+1273 98 2 0.0000 28.3870 -9.7550 26.9960 # CM
+1274 98 3 0.0000 28.5160 -9.7230 26.5150 # CT
+1275 99 1 -1.0000 12.9200 19.0860 29.5820 # HG
+1276 99 2 0.0000 12.3180 18.6430 29.6420 # CM
+1277 99 2 0.0000 12.4170 18.1660 29.5300 # CM
+1278 99 2 0.0000 12.0280 17.8520 29.5400 # CM
+1279 99 2 0.0000 12.1690 17.3800 29.4510 # CM
+1280 99 2 0.0000 11.7500 17.1160 29.3850 # CM
+1281 99 2 0.0000 11.8550 16.6490 29.2370 # CM
+1282 99 2 0.0000 11.4380 16.3890 29.1500 # CM
+1283 99 2 0.0000 11.5350 15.8990 29.1680 # CM
+1284 99 2 0.0000 11.1320 15.6260 29.0520 # CM
+1285 99 2 0.0000 11.2340 15.1400 29.1070 # CM
+1286 99 2 0.0000 10.8260 14.8630 29.1820 # CM
+1287 99 3 0.0000 10.9320 14.3860 29.0760 # CT
+1288 100 1 -1.0000 20.1200 31.5920 26.0870 # HG
+1289 100 2 0.0000 19.7000 31.2690 26.6180 # CM
+1290 100 2 0.0000 19.3520 30.9630 26.4290 # CM
+1291 100 2 0.0000 19.0420 30.7510 26.7590 # CM
+1292 100 2 0.0000 18.7270 30.4310 26.5390 # CM
+1293 100 2 0.0000 18.3850 30.3090 26.8810 # CM
+1294 100 2 0.0000 18.0200 30.0320 26.6780 # CM
+1295 100 2 0.0000 17.6660 29.9260 27.0130 # CM
+1296 100 2 0.0000 17.4030 29.5280 26.8630 # CM
+1297 100 2 0.0000 17.0240 29.4290 27.1740 # CM
+1298 100 2 0.0000 16.7920 29.0110 27.0310 # CM
+1299 100 2 0.0000 16.5450 28.7880 27.4040 # CM
+1300 100 3 0.0000 16.2040 28.4780 27.2110 # CT
+1301 101 1 -1.0000 -20.9540 9.8070 -2.1240 # HG
+1302 101 2 0.0000 -21.4260 10.2440 -2.5110 # CM
+1303 101 2 0.0000 -21.3260 10.7310 -2.4580 # CM
+1304 101 2 0.0000 -21.6390 11.0460 -2.6880 # CM
+1305 101 2 0.0000 -21.4930 11.5220 -2.6360 # CM
+1306 101 2 0.0000 -21.8700 11.8060 -2.8010 # CM
+1307 101 2 0.0000 -21.7800 12.2900 -2.7120 # CM
+1308 101 2 0.0000 -22.1640 12.5740 -2.8570 # CM
+1309 101 2 0.0000 -22.0120 13.0460 -2.9230 # CM
+1310 101 2 0.0000 -22.3940 13.3480 -3.0380 # CM
+1311 101 2 0.0000 -22.2230 13.8080 -3.1340 # CM
+1312 101 2 0.0000 -22.5320 14.0740 -3.4220 # CM
+1313 101 3 0.0000 -22.4230 14.5590 -3.3720 # CT
+1314 102 1 -1.0000 -17.9540 -2.3510 5.9980 # HG
+1315 102 2 0.0000 -17.5520 -1.7340 6.1370 # CM
+1316 102 2 0.0000 -17.0830 -1.7660 5.9660 # CM
+1317 102 2 0.0000 -16.7860 -1.3770 6.0660 # CM
+1318 102 2 0.0000 -16.3340 -1.4310 5.8570 # CM
+1319 102 2 0.0000 -16.0440 -1.0710 6.0470 # CM
+1320 102 2 0.0000 -15.5690 -1.1300 5.9010 # CM
+1321 102 2 0.0000 -15.2730 -0.7840 6.1070 # CM
+1322 102 2 0.0000 -14.8520 -0.7400 5.8410 # CM
+1323 102 2 0.0000 -14.5330 -0.4190 6.0530 # CM
+1324 102 2 0.0000 -14.1320 -0.3600 5.7610 # CM
+1325 102 2 0.0000 -13.8950 0.0730 5.8410 # CM
+1326 102 3 0.0000 -13.4300 0.0380 5.6620 # CT
+1327 103 1 -1.0000 -3.9560 15.0670 -5.5760 # HG
+1328 103 2 0.0000 -3.9870 15.4570 -4.9360 # CM
+1329 103 2 0.0000 -3.5350 15.5450 -4.7420 # CM
+1330 103 2 0.0000 -3.5270 15.7840 -4.3030 # CM
+1331 103 2 0.0000 -3.0600 15.8800 -4.1530 # CM
+1332 103 2 0.0000 -3.0910 16.0380 -3.6800 # CM
+1333 103 2 0.0000 -2.6350 16.0900 -3.4790 # CM
+1334 103 2 0.0000 -2.6640 16.2280 -3.0000 # CM
+1335 103 2 0.0000 -2.2320 16.4360 -2.8570 # CM
+1336 103 2 0.0000 -2.2360 16.5510 -2.3690 # CM
+1337 103 2 0.0000 -1.8130 16.7870 -2.2480 # CM
+1338 103 2 0.0000 -1.8590 17.0700 -1.8390 # CM
+1339 103 3 0.0000 -1.4050 17.1630 -1.6530 # CT
+1340 104 1 -1.0000 -14.1360 -1.6170 1.7440 # HG
+1341 104 2 0.0000 -14.8260 -1.7390 1.4770 # CM
+1342 104 2 0.0000 -14.9180 -2.2230 1.3910 # CM
+1343 104 2 0.0000 -15.3630 -2.3300 1.1910 # CM
+1344 104 2 0.0000 -15.4310 -2.8240 1.1440 # CM
+1345 104 2 0.0000 -15.8420 -2.8870 0.8670 # CM
+1346 104 2 0.0000 -15.9070 -3.3700 0.7530 # CM
+1347 104 2 0.0000 -16.3050 -3.4330 0.4590 # CM
+1348 104 2 0.0000 -16.4630 -3.9070 0.4850 # CM
+1349 104 2 0.0000 -16.8430 -3.9920 0.1710 # CM
+1350 104 2 0.0000 -17.0120 -4.4590 0.2310 # CM
+1351 104 2 0.0000 -17.4850 -4.5150 0.0810 # CM
+1352 104 3 0.0000 -17.5730 -5.0010 0.0030 # CT
+1353 105 1 -1.0000 19.8710 25.8100 -30.6290 # HG
+1354 105 2 0.0000 19.9910 25.3230 -30.0710 # CM
+1355 105 2 0.0000 19.6410 25.3480 -29.7140 # CM
+1356 105 2 0.0000 19.7090 25.0500 -29.3190 # CM
+1357 105 2 0.0000 19.3280 25.0810 -28.9960 # CM
+1358 105 2 0.0000 19.4700 24.8390 -28.5830 # CM
+1359 105 2 0.0000 19.1340 24.8990 -28.2170 # CM
+1360 105 2 0.0000 19.2840 24.6760 -27.7960 # CM
+1361 105 2 0.0000 18.8910 24.5940 -27.4980 # CM
+1362 105 2 0.0000 19.0310 24.3980 -27.0590 # CM
+1363 105 2 0.0000 18.6270 24.2900 -26.7850 # CM
+1364 105 2 0.0000 18.7140 23.9380 -26.4410 # CM
+1365 105 3 0.0000 18.3580 23.9630 -26.0910 # CT
+1366 106 1 -1.0000 -28.7160 -34.2790 20.8000 # HG
+1367 106 2 0.0000 -28.2510 -33.7170 20.6270 # CM
+1368 106 2 0.0000 -27.7800 -33.8700 20.5570 # CM
+1369 106 2 0.0000 -27.4430 -33.5120 20.4630 # CM
+1370 106 2 0.0000 -26.9900 -33.7040 20.3720 # CM
+1371 106 2 0.0000 -26.6700 -33.3200 20.3680 # CM
+1372 106 2 0.0000 -26.1980 -33.4820 20.3360 # CM
+1373 106 2 0.0000 -25.8750 -33.1010 20.3530 # CM
+1374 106 2 0.0000 -25.4370 -33.2410 20.1580 # CM
+1375 106 2 0.0000 -25.0940 -32.8780 20.1960 # CM
+1376 106 2 0.0000 -24.6720 -33.0190 19.9680 # CM
+1377 106 2 0.0000 -24.3890 -32.6320 19.8270 # CM
+1378 106 3 0.0000 -23.9220 -32.7910 19.7520 # CT
+1379 107 1 -1.0000 23.5190 17.5320 32.6010 # HG
+1380 107 2 0.0000 23.7900 16.8620 32.4010 # CM
+1381 107 2 0.0000 23.7060 16.5090 32.7450 # CM
+1382 107 2 0.0000 23.8960 16.0570 32.6480 # CM
+1383 107 2 0.0000 23.7710 15.7240 32.9990 # CM
+1384 107 2 0.0000 24.0450 15.3150 32.9130 # CM
+1385 107 2 0.0000 23.9860 14.9800 33.2810 # CM
+1386 107 2 0.0000 24.2750 14.5800 33.2090 # CM
+1387 107 2 0.0000 24.0970 14.1920 33.4700 # CM
+1388 107 2 0.0000 24.3950 13.7920 33.4310 # CM
+1389 107 2 0.0000 24.1890 13.4040 33.6680 # CM
+1390 107 2 0.0000 24.3540 12.9630 33.4990 # CM
+1391 107 3 0.0000 24.2610 12.6130 33.8440 # CT
+1392 108 1 -1.0000 -27.8800 30.2890 19.6200 # HG
+1393 108 2 0.0000 -27.5220 29.6300 19.6480 # CM
+1394 108 2 0.0000 -27.0310 29.6740 19.5620 # CM
+1395 108 2 0.0000 -26.7710 29.2470 19.5520 # CM
+1396 108 2 0.0000 -26.2810 29.3300 19.4920 # CM
+1397 108 2 0.0000 -26.0710 28.8850 19.4020 # CM
+1398 108 2 0.0000 -25.5880 28.9380 19.2810 # CM
+1399 108 2 0.0000 -25.3810 28.4980 19.1700 # CM
+1400 108 2 0.0000 -24.8840 28.5280 19.2140 # CM
+1401 108 2 0.0000 -24.6600 28.1020 19.0760 # CM
+1402 108 2 0.0000 -24.1680 28.1350 19.1570 # CM
+1403 108 2 0.0000 -23.9500 27.6880 19.2080 # CM
+1404 108 3 0.0000 -23.4590 27.7380 19.1290 # CT
+1405 109 1 -1.0000 20.8170 -15.8260 30.5400 # HG
+1406 109 2 0.0000 21.5360 -15.8220 30.3250 # CM
+1407 109 2 0.0000 21.7660 -15.3910 30.4300 # CM
+1408 109 2 0.0000 22.2400 -15.3520 30.2770 # CM
+1409 109 2 0.0000 22.4470 -14.9200 30.4230 # CM
+1410 109 2 0.0000 22.8830 -14.8810 30.1820 # CM
+1411 109 2 0.0000 23.0910 -14.4330 30.2610 # CM
+1412 109 2 0.0000 23.5170 -14.3830 30.0050 # CM
+1413 109 2 0.0000 23.7970 -14.0230 30.2080 # CM
+1414 109 2 0.0000 24.2130 -13.9410 29.9420 # CM
+1415 109 2 0.0000 24.4990 -13.6030 30.1740 # CM
+1416 109 2 0.0000 24.9810 -13.6360 30.0470 # CM
+1417 109 3 0.0000 25.2080 -13.2060 30.1610 # CT
+1418 110 1 -1.0000 -17.1370 28.1480 -27.3800 # HG
+1419 110 2 0.0000 -17.8730 28.2870 -27.3450 # CM
+1420 110 2 0.0000 -18.1450 27.8710 -27.2910 # CM
+1421 110 2 0.0000 -18.6410 27.9320 -27.2870 # CM
+1422 110 2 0.0000 -18.8800 27.5000 -27.2040 # CM
+1423 110 2 0.0000 -19.3650 27.5850 -27.2920 # CM
+1424 110 2 0.0000 -19.6260 27.1590 -27.2730 # CM
+1425 110 2 0.0000 -20.1070 27.2380 -27.3810 # CM
+1426 110 2 0.0000 -20.3860 26.8630 -27.2030 # CM
+1427 110 2 0.0000 -20.8670 26.9130 -27.3310 # CM
+1428 110 2 0.0000 -21.1380 26.5510 -27.1190 # CM
+1429 110 2 0.0000 -21.6200 26.6720 -27.0710 # CM
+1430 110 3 0.0000 -21.8870 26.2540 -27.0090 # CT
+1431 111 1 -1.0000 -12.6860 -0.4460 17.0890 # HG
+1432 111 2 0.0000 -12.0210 -0.7660 16.9520 # CM
+1433 111 2 0.0000 -12.0480 -1.2650 16.9270 # CM
+1434 111 2 0.0000 -11.6160 -1.5050 16.8600 # CM
+1435 111 2 0.0000 -11.6840 -1.9990 16.8130 # CM
+1436 111 2 0.0000 -11.2300 -2.2090 16.8330 # CM
+1437 111 2 0.0000 -11.2660 -2.7070 16.8450 # CM
+1438 111 2 0.0000 -10.8150 -2.9190 16.8870 # CM
+1439 111 2 0.0000 -10.8360 -3.3950 16.7340 # CM
+1440 111 2 0.0000 -10.3980 -3.6280 16.7990 # CM
+1441 111 2 0.0000 -10.4230 -4.0910 16.6120 # CM
+1442 111 2 0.0000 -9.9750 -4.2770 16.4930 # CM
+1443 111 3 0.0000 -10.0080 -4.7740 16.4620 # CT
+1444 112 1 -1.0000 -5.3350 -21.6040 -12.3850 # HG
+1445 112 2 0.0000 -5.0070 -22.2350 -12.6250 # CM
+1446 112 2 0.0000 -5.3270 -22.6190 -12.6560 # CM
+1447 112 2 0.0000 -5.1300 -23.0580 -12.7920 # CM
+1448 112 2 0.0000 -5.4820 -23.4110 -12.8400 # CM
+1449 112 2 0.0000 -5.2420 -23.8460 -12.8910 # CM
+1450 112 2 0.0000 -5.5640 -24.2290 -12.8840 # CM
+1451 112 2 0.0000 -5.3250 -24.6660 -12.9140 # CM
+1452 112 2 0.0000 -5.6390 -25.0210 -13.0730 # CM
+1453 112 2 0.0000 -5.4210 -25.4720 -13.0780 # CM
+1454 112 2 0.0000 -5.7350 -25.8100 -13.2690 # CM
+1455 112 2 0.0000 -5.4990 -26.2090 -13.4570 # CM
+1456 112 3 0.0000 -5.8240 -26.5870 -13.4940 # CT
+1457 113 1 -1.0000 16.8950 -4.1060 3.9770 # HG
+1458 113 2 0.0000 16.2330 -4.2650 3.6650 # CM
+1459 113 2 0.0000 16.1590 -4.0240 3.2330 # CM
+1460 113 2 0.0000 15.7160 -4.0940 3.0140 # CM
+1461 113 2 0.0000 15.6880 -3.8600 2.5720 # CM
+1462 113 2 0.0000 15.2100 -3.8820 2.4280 # CM
+1463 113 2 0.0000 15.1350 -3.6080 2.0160 # CM
+1464 113 2 0.0000 14.6550 -3.6110 1.8820 # CM
+1465 113 2 0.0000 14.6110 -3.4860 1.4000 # CM
+1466 113 2 0.0000 14.1320 -3.4550 1.2600 # CM
+1467 113 2 0.0000 14.1040 -3.3620 0.7700 # CM
+1468 113 2 0.0000 13.6700 -3.5070 0.5690 # CM
+1469 113 3 0.0000 13.6050 -3.2680 0.1350 # CT
+1470 114 1 -1.0000 4.2790 -7.6500 7.8540 # HG
+1471 114 2 0.0000 3.5870 -7.8150 8.0920 # CM
+1472 114 2 0.0000 3.5670 -8.2480 8.3410 # CM
+1473 114 2 0.0000 3.1130 -8.3940 8.4920 # CM
+1474 114 2 0.0000 3.1340 -8.8160 8.7590 # CM
+1475 114 2 0.0000 2.6630 -8.9730 8.8170 # CM
+1476 114 2 0.0000 2.6500 -9.4240 9.0330 # CM
+1477 114 2 0.0000 2.1820 -9.5920 9.0720 # CM
+1478 114 2 0.0000 2.1570 -9.9460 9.4240 # CM
+1479 114 2 0.0000 1.6990 -10.1460 9.4530 # CM
+1480 114 2 0.0000 1.6800 -10.4730 9.8300 # CM
+1481 114 2 0.0000 1.2160 -10.5460 10.0010 # CM
+1482 114 3 0.0000 1.2020 -10.9760 10.2550 # CT
+1483 115 1 -1.0000 -14.8810 -11.1460 20.6330 # HG
+1484 115 2 0.0000 -15.2170 -10.8130 20.0520 # CM
+1485 115 2 0.0000 -15.1100 -11.0330 19.6150 # CM
+1486 115 2 0.0000 -15.3030 -10.8170 19.2080 # CM
+1487 115 2 0.0000 -15.2000 -11.0780 18.7930 # CM
+1488 115 2 0.0000 -15.3320 -10.7920 18.4060 # CM
+1489 115 2 0.0000 -15.1900 -10.9990 17.9740 # CM
+1490 115 2 0.0000 -15.3020 -10.7050 17.5870 # CM
+1491 115 2 0.0000 -15.3160 -10.9750 17.1660 # CM
+1492 115 2 0.0000 -15.3970 -10.6870 16.7650 # CM
+1493 115 2 0.0000 -15.4410 -10.9720 16.3570 # CM
+1494 115 2 0.0000 -15.6980 -10.7490 15.9910 # CM
+1495 115 3 0.0000 -15.5940 -10.9770 15.5580 # CT
+1496 116 1 -1.0000 6.8790 -27.9870 -29.2240 # HG
+1497 116 2 0.0000 6.9050 -28.4140 -28.6070 # CM
+1498 116 2 0.0000 6.7990 -28.1580 -28.1910 # CM
+1499 116 2 0.0000 6.8310 -28.4130 -27.7620 # CM
+1500 116 2 0.0000 6.6920 -28.1340 -27.3700 # CM
+1501 116 2 0.0000 6.8180 -28.3900 -26.9600 # CM
+1502 116 2 0.0000 6.7430 -28.1150 -26.5490 # CM
+1503 116 2 0.0000 6.8880 -28.3600 -26.1390 # CM
+1504 116 2 0.0000 6.6670 -28.1650 -25.7360 # CM
+1505 116 2 0.0000 6.8260 -28.3820 -25.3140 # CM
+1506 116 2 0.0000 6.5730 -28.2000 -24.9240 # CM
+1507 116 2 0.0000 6.5700 -28.5110 -24.5330 # CM
+1508 116 3 0.0000 6.4560 -28.2530 -24.1210 # CT
+1509 117 1 -1.0000 29.4030 -17.6280 -30.0140 # HG
+1510 117 2 0.0000 29.2460 -16.9860 -30.3690 # CM
+1511 117 2 0.0000 29.6540 -16.7090 -30.4560 # CM
+1512 117 2 0.0000 29.5750 -16.2650 -30.6720 # CM
+1513 117 2 0.0000 30.0060 -16.0280 -30.7680 # CM
+1514 117 2 0.0000 29.8850 -15.5610 -30.9010 # CM
+1515 117 2 0.0000 30.2960 -15.2790 -30.9500 # CM
+1516 117 2 0.0000 30.1770 -14.8070 -31.0620 # CM
+1517 117 2 0.0000 30.5700 -14.5780 -31.2700 # CM
+1518 117 2 0.0000 30.4750 -14.0950 -31.3590 # CM
+1519 117 2 0.0000 30.8630 -13.8870 -31.5960 # CM
+1520 117 2 0.0000 30.7360 -13.4800 -31.8570 # CM
+1521 117 3 0.0000 31.1470 -13.2110 -31.9480 # CT
+1522 118 1 -1.0000 32.0770 22.9880 -13.0580 # HG
+1523 118 2 0.0000 31.7460 22.4020 -12.7270 # CM
+1524 118 2 0.0000 31.8870 21.9640 -12.9240 # CM
+1525 118 2 0.0000 31.6640 21.5570 -12.7370 # CM
+1526 118 2 0.0000 31.8480 21.1370 -12.9370 # CM
+1527 118 2 0.0000 31.5470 20.7660 -12.7920 # CM
+1528 118 2 0.0000 31.6700 20.3380 -13.0200 # CM
+1529 118 2 0.0000 31.3570 19.9700 -12.8930 # CM
+1530 118 2 0.0000 31.5710 19.5260 -12.9820 # CM
+1531 118 2 0.0000 31.2580 19.1480 -12.8880 # CM
+1532 118 2 0.0000 31.4940 18.7120 -12.9490 # CM
+1533 118 2 0.0000 31.2820 18.3390 -12.6940 # CM
+1534 118 3 0.0000 31.4320 17.9040 -12.8890 # CT
+1535 119 1 -1.0000 -29.9760 -1.1120 20.6610 # HG
+1536 119 2 0.0000 -29.6990 -1.7340 20.9750 # CM
+1537 119 2 0.0000 -29.7310 -1.7300 21.4740 # CM
+1538 119 2 0.0000 -29.5330 -2.1230 21.7110 # CM
+1539 119 2 0.0000 -29.6080 -2.0980 22.2060 # CM
+1540 119 2 0.0000 -29.3260 -2.4560 22.4110 # CM
+1541 119 2 0.0000 -29.3330 -2.4230 22.9100 # CM
+1542 119 2 0.0000 -29.0360 -2.7670 23.1180 # CM
+1543 119 2 0.0000 -29.1690 -2.8420 23.5940 # CM
+1544 119 2 0.0000 -28.8600 -3.1620 23.8230 # CM
+1545 119 2 0.0000 -29.0240 -3.2530 24.2870 # CM
+1546 119 2 0.0000 -28.8590 -3.6880 24.4690 # CM
+1547 119 3 0.0000 -28.9000 -3.6810 24.9670 # CT
+1548 120 1 -1.0000 7.2040 31.2970 14.0580 # HG
+1549 120 2 0.0000 6.8360 31.8080 14.4640 # CM
+1550 120 2 0.0000 7.0170 31.8520 14.9290 # CM
+1551 120 2 0.0000 6.7760 32.1710 15.2290 # CM
+1552 120 2 0.0000 7.0000 32.2090 15.6760 # CM
+1553 120 2 0.0000 6.6870 32.4640 15.9710 # CM
+1554 120 2 0.0000 6.8550 32.4730 16.4420 # CM
+1555 120 2 0.0000 6.5350 32.7090 16.7440 # CM
+1556 120 2 0.0000 6.7700 32.8600 17.1580 # CM
+1557 120 2 0.0000 6.4540 33.0710 17.4830 # CM
+1558 120 2 0.0000 6.7070 33.2470 17.8760 # CM
+1559 120 2 0.0000 6.4640 33.6110 18.1160 # CM
+1560 120 3 0.0000 6.6540 33.6570 18.5770 # CT
+1561 121 1 -1.0000 -16.3900 -0.0200 4.0240 # HG
+1562 121 2 0.0000 -15.9940 0.5910 4.2040 # CM
+1563 121 2 0.0000 -15.5480 0.6050 3.9790 # CM
+1564 121 2 0.0000 -15.2530 0.9910 4.0990 # CM
+1565 121 2 0.0000 -14.8280 0.9870 3.8350 # CM
+1566 121 2 0.0000 -14.5290 1.3310 4.0410 # CM
+1567 121 2 0.0000 -14.0730 1.3160 3.8370 # CM
+1568 121 2 0.0000 -13.7660 1.6440 4.0550 # CM
+1569 121 2 0.0000 -13.3810 1.7440 3.7530 # CM
+1570 121 2 0.0000 -13.0490 2.0480 3.9720 # CM
+1571 121 2 0.0000 -12.6870 2.1660 3.6480 # CM
+1572 121 2 0.0000 -12.4560 2.5940 3.7620 # CM
+1573 121 3 0.0000 -12.0140 2.6070 3.5290 # CT
+1574 122 1 -1.0000 2.0400 -7.1840 15.1750 # HG
+1575 122 2 0.0000 1.8260 -7.7040 14.6790 # CM
+1576 122 2 0.0000 2.2050 -7.8720 14.4000 # CM
+1577 122 2 0.0000 2.0870 -8.2040 14.0450 # CM
+1578 122 2 0.0000 2.4930 -8.3700 13.8040 # CM
+1579 122 2 0.0000 2.3290 -8.6270 13.4080 # CM
+1580 122 2 0.0000 2.7100 -8.7610 13.1130 # CM
+1581 122 2 0.0000 2.5480 -9.0000 12.7060 # CM
+1582 122 2 0.0000 2.9190 -9.2700 12.5070 # CM
+1583 122 2 0.0000 2.7790 -9.4910 12.0810 # CM
+1584 122 2 0.0000 3.1470 -9.7830 11.9120 # CM
+1585 122 2 0.0000 2.9840 -10.1460 11.6100 # CM
+1586 122 3 0.0000 3.3680 -10.3160 11.3380 # CT
+1587 123 1 -1.0000 24.7770 -2.0970 -10.7200 # HG
+1588 123 2 0.0000 25.0620 -2.5030 -10.1580 # CM
+1589 123 2 0.0000 24.8620 -2.9610 -10.1300 # CM
+1590 123 2 0.0000 25.0180 -3.2460 -9.7500 # CM
+1591 123 2 0.0000 24.8180 -3.7050 -9.7700 # CM
+1592 123 2 0.0000 24.9270 -3.9270 -9.3350 # CM
+1593 123 2 0.0000 24.6940 -4.3680 -9.2980 # CM
+1594 123 2 0.0000 24.7850 -4.5830 -8.8560 # CM
+1595 123 2 0.0000 24.6970 -5.0740 -8.8840 # CM
+1596 123 2 0.0000 24.7540 -5.2970 -8.4400 # CM
+1597 123 2 0.0000 24.6970 -5.7910 -8.4890 # CM
+1598 123 2 0.0000 24.9230 -6.0500 -8.1270 # CM
+1599 123 3 0.0000 24.7250 -6.5090 -8.1080 # CT
+1600 124 1 -1.0000 16.7190 -2.9010 -28.7810 # HG
+1601 124 2 0.0000 16.0550 -3.2180 -28.9260 # CM
+1602 124 2 0.0000 15.8120 -2.9950 -29.3020 # CM
+1603 124 2 0.0000 15.3560 -3.1710 -29.4060 # CM
+1604 124 2 0.0000 15.1550 -2.9430 -29.8030 # CM
+1605 124 2 0.0000 14.6760 -3.0830 -29.8220 # CM
+1606 124 2 0.0000 14.4300 -2.8290 -30.1760 # CM
+1607 124 2 0.0000 13.9460 -2.9520 -30.1820 # CM
+1608 124 2 0.0000 13.7450 -2.8320 -30.6240 # CM
+1609 124 2 0.0000 13.2530 -2.9210 -30.6340 # CM
+1610 124 2 0.0000 13.0730 -2.8300 -31.0910 # CM
+1611 124 2 0.0000 12.6480 -3.0750 -31.1850 # CM
+1612 124 3 0.0000 12.4140 -2.8530 -31.5660 # CT
+1613 125 1 -1.0000 -31.2540 -33.8800 -16.8250 # HG
+1614 125 2 0.0000 -31.6830 -33.4760 -17.2890 # CM
+1615 125 2 0.0000 -31.5460 -32.9960 -17.3080 # CM
+1616 125 2 0.0000 -31.8290 -32.6980 -17.5930 # CM
+1617 125 2 0.0000 -31.6480 -32.2320 -17.6110 # CM
+1618 125 2 0.0000 -31.9980 -31.9500 -17.8290 # CM
+1619 125 2 0.0000 -31.8730 -31.4660 -17.8130 # CM
+1620 125 2 0.0000 -32.2310 -31.1800 -18.0120 # CM
+1621 125 2 0.0000 -32.0410 -30.7370 -18.1450 # CM
+1622 125 2 0.0000 -32.3960 -30.4290 -18.3170 # CM
+1623 125 2 0.0000 -32.1880 -30.0040 -18.4770 # CM
+1624 125 2 0.0000 -32.4700 -29.7630 -18.8120 # CM
+1625 125 3 0.0000 -32.3250 -29.2860 -18.8340 # CT
+1626 126 1 -1.0000 -9.2000 -18.8870 -23.8790 # HG
+1627 126 2 0.0000 -9.5150 -18.5170 -24.4510 # CM
+1628 126 2 0.0000 -9.2180 -18.1590 -24.6360 # CM
+1629 126 2 0.0000 -9.4120 -17.8810 -25.0030 # CM
+1630 126 2 0.0000 -9.0790 -17.5530 -25.1820 # CM
+1631 126 2 0.0000 -9.3320 -17.2420 -25.4810 # CM
+1632 126 2 0.0000 -9.0390 -16.8660 -25.6340 # CM
+1633 126 2 0.0000 -9.2940 -16.5420 -25.9160 # CM
+1634 126 2 0.0000 -8.9780 -16.2730 -26.1950 # CM
+1635 126 2 0.0000 -9.2180 -15.9230 -26.4600 # CM
+1636 126 2 0.0000 -8.8950 -15.6850 -26.7580 # CM
+1637 126 2 0.0000 -9.1160 -15.4740 -27.1530 # CM
+1638 126 3 0.0000 -8.8130 -15.1230 -27.3390 # CT
+1639 127 1 -1.0000 -25.5600 3.6800 -22.3170 # HG
+1640 127 2 0.0000 -25.7590 3.9860 -22.9720 # CM
+1641 127 2 0.0000 -26.2460 4.1000 -22.9910 # CM
+1642 127 2 0.0000 -26.4120 4.2850 -23.4250 # CM
+1643 127 2 0.0000 -26.8950 4.4130 -23.4000 # CM
+1644 127 2 0.0000 -27.0420 4.5100 -23.8670 # CM
+1645 127 2 0.0000 -27.5360 4.5870 -23.8850 # CM
+1646 127 2 0.0000 -27.6900 4.6640 -24.3540 # CM
+1647 127 2 0.0000 -28.1310 4.8990 -24.3530 # CM
+1648 127 2 0.0000 -28.3120 4.9540 -24.8160 # CM
+1649 127 2 0.0000 -28.7350 5.2200 -24.8030 # CM
+1650 127 2 0.0000 -28.8360 5.4460 -25.2360 # CM
+1651 127 3 0.0000 -29.3210 5.5650 -25.2480 # CT
+1652 128 1 -1.0000 6.3340 -7.9990 -28.9930 # HG
+1653 128 2 0.0000 6.0060 -7.8420 -29.6490 # CM
+1654 128 2 0.0000 6.2960 -7.5650 -29.9480 # CM
+1655 128 2 0.0000 6.0930 -7.4260 -30.3830 # CM
+1656 128 2 0.0000 6.4190 -7.1740 -30.6670 # CM
+1657 128 2 0.0000 6.1590 -6.9820 -31.0480 # CM
+1658 128 2 0.0000 6.4450 -6.6750 -31.3220 # CM
+1659 128 2 0.0000 6.1820 -6.4660 -31.6910 # CM
+1660 128 2 0.0000 6.4910 -6.3030 -32.0490 # CM
+1661 128 2 0.0000 6.2420 -6.0630 -32.4110 # CM
+1662 128 2 0.0000 6.5580 -5.9350 -32.7770 # CM
+1663 128 2 0.0000 6.3290 -5.8680 -33.2160 # CM
+1664 128 3 0.0000 6.6250 -5.5970 -33.5140 # CT
+1665 129 1 -1.0000 -24.3220 -4.4000 -27.2780 # HG
+1666 129 2 0.0000 -24.3200 -3.6560 -27.1840 # CM
+1667 129 2 0.0000 -24.7800 -3.4590 -27.1970 # CM
+1668 129 2 0.0000 -24.8060 -2.9610 -27.1600 # CM
+1669 129 2 0.0000 -25.2800 -2.8010 -27.1490 # CM
+1670 129 2 0.0000 -25.2650 -2.3040 -27.1970 # CM
+1671 129 2 0.0000 -25.7260 -2.1160 -27.2470 # CM
+1672 129 2 0.0000 -25.7130 -1.6220 -27.3170 # CM
+1673 129 2 0.0000 -26.1560 -1.4220 -27.2000 # CM
+1674 129 2 0.0000 -26.1670 -0.9300 -27.2950 # CM
+1675 129 2 0.0000 -26.6020 -0.7380 -27.1420 # CM
+1676 129 2 0.0000 -26.5760 -0.2470 -27.0500 # CM
+1677 129 3 0.0000 -27.0370 -0.0560 -27.0560 # CT
+1678 130 1 -1.0000 3.0660 -13.7530 -8.7980 # HG
+1679 130 2 0.0000 2.4570 -13.3580 -8.6100 # CM
+1680 130 2 0.0000 2.0380 -13.6300 -8.6220 # CM
+1681 130 2 0.0000 1.6130 -13.3860 -8.5230 # CM
+1682 130 2 0.0000 1.2190 -13.6940 -8.5170 # CM
+1683 130 2 0.0000 0.8120 -13.4060 -8.5020 # CM
+1684 130 2 0.0000 0.3970 -13.6810 -8.5510 # CM
+1685 130 2 0.0000 -0.0110 -13.3930 -8.5570 # CM
+1686 130 2 0.0000 -0.4140 -13.6650 -8.4400 # CM
+1687 130 2 0.0000 -0.8340 -13.3960 -8.4720 # CM
+1688 130 2 0.0000 -1.2230 -13.6700 -8.3200 # CM
+1689 130 2 0.0000 -1.6080 -13.3920 -8.1650 # CM
+1690 130 3 0.0000 -2.0230 -13.6710 -8.1710 # CT
+1691 131 1 -1.0000 30.2900 24.6290 -33.5910 # HG
+1692 131 2 0.0000 29.7770 24.4620 -33.0700 # CM
+1693 131 2 0.0000 29.8220 23.9940 -32.8980 # CM
+1694 131 2 0.0000 29.4780 23.8480 -32.5660 # CM
+1695 131 2 0.0000 29.5690 23.3860 -32.3970 # CM
+1696 131 2 0.0000 29.1640 23.2460 -32.1390 # CM
+1697 131 2 0.0000 29.1980 22.7660 -32.0010 # CM
+1698 131 2 0.0000 28.7870 22.6180 -31.7610 # CM
+1699 131 2 0.0000 28.8860 22.2110 -31.4880 # CM
+1700 131 2 0.0000 28.4740 22.0330 -31.2660 # CM
+1701 131 2 0.0000 28.5930 21.6480 -30.9710 # CM
+1702 131 2 0.0000 28.2600 21.5710 -30.6080 # CM
+1703 131 3 0.0000 28.3130 21.1050 -30.4340 # CT
+1704 132 1 -1.0000 -13.6580 12.0040 -23.8330 # HG
+1705 132 2 0.0000 -14.3560 12.0720 -23.5670 # CM
+1706 132 2 0.0000 -14.6400 12.3760 -23.8460 # CM
+1707 132 2 0.0000 -15.1040 12.4580 -23.6790 # CM
+1708 132 2 0.0000 -15.3670 12.7420 -23.9960 # CM
+1709 132 2 0.0000 -15.7870 12.8710 -23.7580 # CM
+1710 132 2 0.0000 -16.0490 13.2030 -24.0250 # CM
+1711 132 2 0.0000 -16.4590 13.3490 -23.7810 # CM
+1712 132 2 0.0000 -16.7910 13.5390 -24.1030 # CM
+1713 132 2 0.0000 -17.1940 13.7180 -23.8670 # CM
+1714 132 2 0.0000 -17.5310 13.8740 -24.2010 # CM
+1715 132 2 0.0000 -17.9970 13.8800 -24.0200 # CM
+1716 132 3 0.0000 -18.2780 14.1780 -24.3060 # CT
+1717 133 1 -1.0000 16.3950 5.5340 -14.9300 # HG
+1718 133 2 0.0000 15.9610 4.9380 -15.0680 # CM
+1719 133 2 0.0000 15.4810 5.0600 -15.1360 # CM
+1720 133 2 0.0000 15.1650 4.6790 -15.2070 # CM
+1721 133 2 0.0000 14.7000 4.8390 -15.2980 # CM
+1722 133 2 0.0000 14.4040 4.4370 -15.2780 # CM
+1723 133 2 0.0000 13.9220 4.5690 -15.3090 # CM
+1724 133 2 0.0000 13.6230 4.1720 -15.2690 # CM
+1725 133 2 0.0000 13.1740 4.2760 -15.4620 # CM
+1726 133 2 0.0000 12.8540 3.8960 -15.4000 # CM
+1727 133 2 0.0000 12.4210 4.0000 -15.6260 # CM
+1728 133 2 0.0000 12.1590 3.5910 -15.7430 # CM
+1729 133 3 0.0000 11.6820 3.7190 -15.8180 # CT
+1730 134 1 -1.0000 -6.1430 6.2460 9.3940 # HG
+1731 134 2 0.0000 -6.8350 6.4030 9.6370 # CM
+1732 134 2 0.0000 -6.9500 6.8880 9.5900 # CM
+1733 134 2 0.0000 -7.3980 7.0250 9.7660 # CM
+1734 134 2 0.0000 -7.4900 7.5090 9.6780 # CM
+1735 134 2 0.0000 -7.9000 7.6260 9.9390 # CM
+1736 134 2 0.0000 -7.9890 8.1180 9.9190 # CM
+1737 134 2 0.0000 -8.3860 8.2410 10.1960 # CM
+1738 134 2 0.0000 -8.5690 8.6810 10.0470 # CM
+1739 134 2 0.0000 -8.9480 8.8310 10.3360 # CM
+1740 134 2 0.0000 -9.1420 9.2550 10.1560 # CM
+1741 134 2 0.0000 -9.6150 9.3290 10.2970 # CM
+1742 134 3 0.0000 -9.7280 9.8120 10.2420 # CT
+1743 135 1 -1.0000 3.2590 8.1610 15.4260 # HG
+1744 135 2 0.0000 3.3730 8.6140 16.0130 # CM
+1745 135 2 0.0000 3.8130 8.5330 16.2370 # CM
+1746 135 2 0.0000 3.9050 8.8060 16.6450 # CM
+1747 135 2 0.0000 4.3640 8.7180 16.8260 # CM
+1748 135 2 0.0000 4.3850 8.9400 17.2740 # CM
+1749 135 2 0.0000 4.8120 8.8250 17.5080 # CM
+1750 135 2 0.0000 4.8280 9.0280 17.9640 # CM
+1751 135 2 0.0000 5.3010 9.0550 18.1230 # CM
+1752 135 2 0.0000 5.3290 9.2280 18.5920 # CM
+1753 135 2 0.0000 5.8070 9.2810 18.7250 # CM
+1754 135 2 0.0000 5.8710 9.6130 19.0930 # CM
+1755 135 3 0.0000 6.3150 9.5330 19.3080 # CT
+1756 136 1 -1.0000 18.5360 -0.9910 -0.0940 # HG
+1757 136 2 0.0000 19.2040 -0.8000 0.1890 # CM
+1758 136 2 0.0000 19.2880 -0.3070 0.1700 # CM
+1759 136 2 0.0000 19.7350 -0.1540 0.3320 # CM
+1760 136 2 0.0000 19.7740 0.3450 0.3240 # CM
+1761 136 2 0.0000 20.2540 0.4530 0.4080 # CM
+1762 136 2 0.0000 20.3390 0.9430 0.3520 # CM
+1763 136 2 0.0000 20.8220 1.0510 0.4150 # CM
+1764 136 2 0.0000 20.8760 1.5360 0.5230 # CM
+1765 136 2 0.0000 21.3590 1.6640 0.5580 # CM
+1766 136 2 0.0000 21.3970 2.1420 0.6990 # CM
+1767 136 2 0.0000 21.8340 2.2450 0.9180 # CM
+1768 136 3 0.0000 21.9100 2.7390 0.9040 # CT
+1769 137 1 -1.0000 2.5440 -33.1280 -24.7980 # HG
+1770 137 2 0.0000 3.1890 -33.3910 -25.0770 # CM
+1771 137 2 0.0000 3.2000 -33.3830 -25.5770 # CM
+1772 137 2 0.0000 3.6090 -33.5740 -25.7910 # CM
+1773 137 2 0.0000 3.5980 -33.5260 -26.2890 # CM
+1774 137 2 0.0000 3.9750 -33.8000 -26.4680 # CM
+1775 137 2 0.0000 3.9600 -33.8190 -26.9680 # CM
+1776 137 2 0.0000 4.3230 -34.1100 -27.1490 # CM
+1777 137 2 0.0000 4.4080 -33.9970 -27.6290 # CM
+1778 137 2 0.0000 4.7490 -34.3020 -27.8320 # CM
+1779 137 2 0.0000 4.8490 -34.1570 -28.2990 # CM
+1780 137 2 0.0000 5.2970 -34.3100 -28.4590 # CM
+1781 137 3 0.0000 5.3060 -34.2940 -28.9580 # CT
+1782 138 1 -1.0000 -28.6740 18.3120 -16.3790 # HG
+1783 138 2 0.0000 -28.3130 18.6760 -16.9270 # CM
+1784 138 2 0.0000 -27.8300 18.7500 -16.8230 # CM
+1785 138 2 0.0000 -27.5700 19.0110 -17.1610 # CM
+1786 138 2 0.0000 -27.0860 19.0420 -17.0390 # CM
+1787 138 2 0.0000 -26.8810 19.3760 -17.3490 # CM
+1788 138 2 0.0000 -26.4080 19.4740 -17.2180 # CM
+1789 138 2 0.0000 -26.2070 19.8220 -17.5130 # CM
+1790 138 2 0.0000 -25.7080 19.7970 -17.4920 # CM
+1791 138 2 0.0000 -25.4940 20.1610 -17.7600 # CM
+1792 138 2 0.0000 -24.9970 20.1040 -17.7580 # CM
+1793 138 2 0.0000 -24.7740 20.3220 -18.1480 # CM
+1794 138 3 0.0000 -24.2900 20.3870 -18.0430 # CT
+1795 139 1 -1.0000 -7.4370 31.2030 -18.3380 # HG
+1796 139 2 0.0000 -7.9930 30.7510 -18.1160 # CM
+1797 139 2 0.0000 -8.2290 30.5330 -18.4990 # CM
+1798 139 2 0.0000 -8.6190 30.2430 -18.3810 # CM
+1799 139 2 0.0000 -8.8130 30.0200 -18.7850 # CM
+1800 139 2 0.0000 -9.2440 29.8130 -18.6420 # CM
+1801 139 2 0.0000 -9.4930 29.6290 -19.0350 # CM
+1802 139 2 0.0000 -9.9340 29.4410 -18.8970 # CM
+1803 139 2 0.0000 -10.0980 29.1190 -19.2440 # CM
+1804 139 2 0.0000 -10.5540 28.9460 -19.1330 # CM
+1805 139 2 0.0000 -10.6910 28.6020 -19.4690 # CM
+1806 139 2 0.0000 -11.0370 28.2870 -19.2950 # CM
+1807 139 3 0.0000 -11.2640 28.0650 -19.6810 # CT
+1808 140 1 -1.0000 17.0730 26.3550 27.5760 # HG
+1809 140 2 0.0000 17.1490 25.7160 27.9600 # CM
+1810 140 2 0.0000 16.8840 25.7130 28.3850 # CM
+1811 140 2 0.0000 16.9340 25.3070 28.6720 # CM
+1812 140 2 0.0000 16.6360 25.3260 29.0730 # CM
+1813 140 2 0.0000 16.7750 24.9520 29.3740 # CM
+1814 140 2 0.0000 16.5330 24.9760 29.8120 # CM
+1815 140 2 0.0000 16.6860 24.6160 30.1220 # CM
+1816 140 2 0.0000 16.3410 24.5390 30.4750 # CM
+1817 140 2 0.0000 16.4950 24.2010 30.8120 # CM
+1818 140 2 0.0000 16.1290 24.1090 31.1390 # CM
+1819 140 2 0.0000 16.1740 23.6640 31.3610 # CM
+1820 140 3 0.0000 15.9020 23.6630 31.7800 # CT
+1821 141 1 -1.0000 8.1860 2.5060 10.4280 # HG
+1822 141 2 0.0000 8.1360 2.4450 11.1730 # CM
+1823 141 2 0.0000 7.7720 2.7290 11.3660 # CM
+1824 141 2 0.0000 7.7300 2.7250 11.8640 # CM
+1825 141 2 0.0000 7.3400 2.9980 12.0200 # CM
+1826 141 2 0.0000 7.3830 3.0390 12.5160 # CM
+1827 141 2 0.0000 7.0390 3.3540 12.6980 # CM
+1828 141 2 0.0000 7.0930 3.4130 13.1910 # CM
+1829 141 2 0.0000 6.6670 3.5830 13.3900 # CM
+1830 141 2 0.0000 6.7160 3.6770 13.8790 # CM
+1831 141 2 0.0000 6.2750 3.8130 14.0710 # CM
+1832 141 2 0.0000 6.2440 3.7340 14.5630 # CM
+1833 141 3 0.0000 5.8750 4.0130 14.7500 # CT
+1834 142 1 -1.0000 -0.4410 17.9780 -9.9990 # HG
+1835 142 2 0.0000 -1.1830 18.0660 -10.0600 # CM
+1836 142 2 0.0000 -1.3460 18.4870 -9.8440 # CM
+1837 142 2 0.0000 -1.8400 18.5610 -9.8500 # CM
+1838 142 2 0.0000 -1.9640 19.0030 -9.6510 # CM
+1839 142 2 0.0000 -2.4610 19.0020 -9.5970 # CM
+1840 142 2 0.0000 -2.6140 19.4080 -9.3480 # CM
+1841 142 2 0.0000 -3.1080 19.3990 -9.2740 # CM
+1842 142 2 0.0000 -3.2740 19.8610 -9.1820 # CM
+1843 142 2 0.0000 -3.7640 19.8630 -9.0760 # CM
+1844 142 2 0.0000 -3.9230 20.3330 -9.0190 # CM
+1845 142 2 0.0000 -4.4140 20.3820 -9.0980 # CM
+1846 142 3 0.0000 -4.5700 20.8070 -8.8870 # CT
+1847 143 1 -1.0000 18.2590 26.5500 -26.7140 # HG
+1848 143 2 0.0000 17.5440 26.5200 -26.4910 # CM
+1849 143 2 0.0000 17.3400 26.0680 -26.5580 # CM
+1850 143 2 0.0000 16.8560 26.0250 -26.4380 # CM
+1851 143 2 0.0000 16.6930 25.5550 -26.4920 # CM
+1852 143 2 0.0000 16.1960 25.5700 -26.4470 # CM
+1853 143 2 0.0000 15.9950 25.1240 -26.5510 # CM
+1854 143 2 0.0000 15.4960 25.1410 -26.5280 # CM
+1855 143 2 0.0000 15.3120 24.6800 -26.4660 # CM
+1856 143 2 0.0000 14.8120 24.6790 -26.4720 # CM
+1857 143 2 0.0000 14.6420 24.2190 -26.3760 # CM
+1858 143 2 0.0000 14.1770 24.2170 -26.1950 # CM
+1859 143 3 0.0000 13.9800 23.7620 -26.2570 # CT
+1860 144 1 -1.0000 32.5740 -5.6600 -7.6490 # HG
+1861 144 2 0.0000 32.0260 -5.1490 -7.6290 # CM
+1862 144 2 0.0000 32.1430 -4.7500 -7.3500 # CM
+1863 144 2 0.0000 31.7860 -4.4040 -7.3010 # CM
+1864 144 2 0.0000 31.9470 -4.0090 -7.0390 # CM
+1865 144 2 0.0000 31.5450 -3.7300 -6.9390 # CM
+1866 144 2 0.0000 31.6610 -3.3540 -6.6300 # CM
+1867 144 2 0.0000 31.2570 -3.0860 -6.5120 # CM
+1868 144 2 0.0000 31.3940 -2.6330 -6.3500 # CM
+1869 144 2 0.0000 31.0000 -2.3640 -6.1990 # CM
+1870 144 2 0.0000 31.1470 -1.9040 -6.0710 # CM
+1871 144 2 0.0000 30.7790 -1.5680 -6.0970 # CM
+1872 144 3 0.0000 30.9040 -1.1690 -5.8230 # CT
+1873 145 1 -1.0000 -1.9400 20.4280 -7.3690 # HG
+1874 145 2 0.0000 -1.9560 20.6360 -6.6490 # CM
+1875 145 2 0.0000 -1.6680 20.3490 -6.3580 # CM
+1876 145 2 0.0000 -1.6780 20.4510 -5.8690 # CM
+1877 145 2 0.0000 -1.3590 20.1620 -5.6130 # CM
+1878 145 2 0.0000 -1.4590 20.2330 -5.1290 # CM
+1879 145 2 0.0000 -1.1950 19.9170 -4.8450 # CM
+1880 145 2 0.0000 -1.3080 19.9700 -4.3620 # CM
+1881 145 2 0.0000 -0.9400 19.7850 -4.0790 # CM
+1882 145 2 0.0000 -1.0540 19.8050 -3.5920 # CM
+1883 145 2 0.0000 -0.6650 19.6480 -3.3200 # CM
+1884 145 2 0.0000 -0.6720 19.8240 -2.8520 # CM
+1885 145 3 0.0000 -0.3770 19.5380 -2.5680 # CT
+1886 146 1 -1.0000 -34.7250 -28.6910 12.6670 # HG
+1887 146 2 0.0000 -34.4660 -27.9890 12.7170 # CM
+1888 146 2 0.0000 -33.9690 -27.9700 12.7740 # CM
+1889 146 2 0.0000 -33.7720 -27.5150 12.8330 # CM
+1890 146 2 0.0000 -33.2720 -27.5320 12.8600 # CM
+1891 146 2 0.0000 -33.1210 -27.0770 13.0020 # CM
+1892 146 2 0.0000 -32.6290 -27.0740 13.0930 # CM
+1893 146 2 0.0000 -32.4790 -26.6260 13.2560 # CM
+1894 146 2 0.0000 -31.9870 -26.5760 13.1860 # CM
+1895 146 2 0.0000 -31.8170 -26.1440 13.3730 # CM
+1896 146 2 0.0000 -31.3310 -26.0920 13.2670 # CM
+1897 146 2 0.0000 -31.1820 -25.6160 13.2700 # CM
+1898 146 3 0.0000 -30.6850 -25.6020 13.3190 # CT
+1899 147 1 -1.0000 -7.3760 -25.5510 -19.8430 # HG
+1900 147 2 0.0000 -6.6560 -25.6980 -19.6930 # CM
+1901 147 2 0.0000 -6.3720 -25.2870 -19.6890 # CM
+1902 147 2 0.0000 -5.8830 -25.3580 -19.6140 # CM
+1903 147 2 0.0000 -5.6340 -24.9250 -19.5890 # CM
+1904 147 2 0.0000 -5.1470 -25.0380 -19.6000 # CM
+1905 147 2 0.0000 -4.8690 -24.6230 -19.6330 # CM
+1906 147 2 0.0000 -4.3830 -24.7340 -19.6650 # CM
+1907 147 2 0.0000 -4.1090 -24.3380 -19.5320 # CM
+1908 147 2 0.0000 -3.6190 -24.4250 -19.5890 # CM
+1909 147 2 0.0000 -3.3570 -24.0350 -19.4220 # CM
+1910 147 2 0.0000 -2.8900 -24.1560 -19.2920 # CM
+1911 147 3 0.0000 -2.6110 -23.7410 -19.2830 # CT
+1912 148 1 -1.0000 -6.1710 6.3500 30.6680 # HG
+1913 148 2 0.0000 -6.8940 6.5040 30.7910 # CM
+1914 148 2 0.0000 -7.1750 6.0920 30.8350 # CM
+1915 148 2 0.0000 -7.6660 6.1660 30.8950 # CM
+1916 148 2 0.0000 -7.9100 5.7340 30.9630 # CM
+1917 148 2 0.0000 -8.3980 5.8400 30.9320 # CM
+1918 148 2 0.0000 -8.6710 5.4210 30.9400 # CM
+1919 148 2 0.0000 -9.1580 5.5220 30.8890 # CM
+1920 148 2 0.0000 -9.4300 5.1400 31.0600 # CM
+1921 148 2 0.0000 -9.9200 5.2150 30.9860 # CM
+1922 148 2 0.0000 -10.1810 4.8420 31.1910 # CM
+1923 148 2 0.0000 -10.6510 4.9700 31.3000 # CM
+1924 148 3 0.0000 -10.9260 4.5560 31.3500 # CT
+1925 149 1 -1.0000 33.9980 -28.2520 8.2790 # HG
+1926 149 2 0.0000 33.3640 -28.0170 8.6040 # CM
+1927 149 2 0.0000 33.3920 -28.0160 9.1030 # CM
+1928 149 2 0.0000 32.9750 -27.8850 9.3460 # CM
+1929 149 2 0.0000 33.0470 -27.8690 9.8410 # CM
+1930 149 2 0.0000 32.5960 -27.8210 10.0500 # CM
+1931 149 2 0.0000 32.6260 -27.8570 10.5490 # CM
+1932 149 2 0.0000 32.1740 -27.8300 10.7590 # CM
+1933 149 2 0.0000 32.2170 -27.7010 11.2400 # CM
+1934 149 2 0.0000 31.7730 -27.7000 11.4710 # CM
+1935 149 2 0.0000 31.8270 -27.5370 11.9400 # CM
+1936 149 2 0.0000 31.4040 -27.3510 12.1310 # CM
+1937 149 3 0.0000 31.4400 -27.3450 12.6290 # CT
+1938 150 1 -1.0000 -18.8730 -25.3790 18.3170 # HG
+1939 150 2 0.0000 -19.4420 -25.2850 17.8380 # CM
+1940 150 2 0.0000 -19.3960 -24.8700 17.5620 # CM
+1941 150 2 0.0000 -19.7730 -24.7710 17.2500 # CM
+1942 150 2 0.0000 -19.6800 -24.3650 16.9710 # CM
+1943 150 2 0.0000 -20.1070 -24.2500 16.7390 # CM
+1944 150 2 0.0000 -20.0660 -23.8160 16.4940 # CM
+1945 150 2 0.0000 -20.4970 -23.6880 16.2790 # CM
+1946 150 2 0.0000 -20.4140 -23.3590 15.9110 # CM
+1947 150 2 0.0000 -20.8410 -23.1990 15.7060 # CM
+1948 150 2 0.0000 -20.7420 -22.8980 15.3200 # CM
+1949 150 2 0.0000 -21.1170 -22.8730 14.9920 # CM
+1950 150 3 0.0000 -21.0620 -22.4620 14.7130 # CT
+1951 151 1 -1.0000 14.4270 -8.9750 4.4160 # HG
+1952 151 2 0.0000 14.1850 -9.3080 5.0430 # CM
+1953 151 2 0.0000 13.8430 -9.6620 4.9540 # CM
+1954 151 2 0.0000 13.6470 -9.8850 5.3560 # CM
+1955 151 2 0.0000 13.3300 -10.2510 5.2290 # CM
+1956 151 2 0.0000 13.0950 -10.3890 5.6480 # CM
+1957 151 2 0.0000 12.7290 -10.7150 5.5470 # CM
+1958 151 2 0.0000 12.4790 -10.8390 5.9610 # CM
+1959 151 2 0.0000 12.2390 -11.2720 5.8920 # CM
+1960 151 2 0.0000 11.9590 -11.3920 6.2890 # CM
+1961 151 2 0.0000 11.7510 -11.8420 6.2210 # CM
+1962 151 2 0.0000 11.6280 -12.0660 6.6490 # CM
+1963 151 3 0.0000 11.2920 -12.4240 6.5540 # CT
+1964 152 1 -1.0000 26.7310 -18.5610 28.5560 # HG
+1965 152 2 0.0000 26.6690 -18.7400 29.2810 # CM
+1966 152 2 0.0000 26.2010 -18.6970 29.4520 # CM
+1967 152 2 0.0000 26.1350 -18.7890 29.9390 # CM
+1968 152 2 0.0000 25.6520 -18.7640 30.0680 # CM
+1969 152 2 0.0000 25.6360 -18.7750 30.5670 # CM
+1970 152 2 0.0000 25.1710 -18.6950 30.7330 # CM
+1971 152 2 0.0000 25.1560 -18.6850 31.2310 # CM
+1972 152 2 0.0000 24.6900 -18.7720 31.3900 # CM
+1973 152 2 0.0000 24.6540 -18.7340 31.8880 # CM
+1974 152 2 0.0000 24.1930 -18.8560 32.0350 # CM
+1975 152 2 0.0000 24.1730 -19.0070 32.5100 # CM
+1976 152 3 0.0000 23.7030 -18.9700 32.6730 # CT
+1977 153 1 -1.0000 24.2780 11.6680 22.4810 # HG
+1978 153 2 0.0000 23.6340 11.3430 22.2760 # CM
+1979 153 2 0.0000 23.6980 10.8750 22.1100 # CM
+1980 153 2 0.0000 23.2880 10.6430 21.9450 # CM
+1981 153 2 0.0000 23.3840 10.1700 21.8120 # CM
+1982 153 2 0.0000 22.9770 10.0010 21.5770 # CM
+1983 153 2 0.0000 23.0590 9.5490 21.3800 # CM
+1984 153 2 0.0000 22.6610 9.3870 21.1260 # CM
+1985 153 2 0.0000 22.6790 8.8900 21.0790 # CM
+1986 153 2 0.0000 22.3020 8.7170 20.7990 # CM
+1987 153 2 0.0000 22.3140 8.2180 20.7880 # CM
+1988 153 2 0.0000 21.8690 8.0150 20.6850 # CM
+1989 153 3 0.0000 21.9370 7.5460 20.5260 # CT
+1990 154 1 -1.0000 -24.5400 19.6400 -5.8290 # HG
+1991 154 2 0.0000 -23.8740 19.5030 -6.1450 # CM
+1992 154 2 0.0000 -23.6070 19.9190 -6.2220 # CM
+1993 154 2 0.0000 -23.1680 19.8590 -6.4530 # CM
+1994 154 2 0.0000 -22.9180 20.2910 -6.4890 # CM
+1995 154 2 0.0000 -22.5320 20.2080 -6.7960 # CM
+1996 154 2 0.0000 -22.2910 20.6340 -6.8980 # CM
+1997 154 2 0.0000 -21.9180 20.5570 -7.2210 # CM
+1998 154 2 0.0000 -21.5880 20.9320 -7.1920 # CM
+1999 154 2 0.0000 -21.2240 20.8830 -7.5320 # CM
+2000 154 2 0.0000 -20.8840 21.2440 -7.4700 # CM
+2001 154 2 0.0000 -20.4360 21.1240 -7.6550 # CM
+2002 154 3 0.0000 -20.1710 21.5420 -7.7230 # CT
+2003 155 1 -1.0000 -13.6750 13.5740 -17.6290 # HG
+2004 155 2 0.0000 -13.6630 12.8470 -17.4480 # CM
+2005 155 2 0.0000 -14.0140 12.7250 -17.1130 # CM
+2006 155 2 0.0000 -14.0140 12.2500 -16.9570 # CM
+2007 155 2 0.0000 -14.3940 12.1590 -16.6440 # CM
+2008 155 2 0.0000 -14.3110 11.7070 -16.4460 # CM
+2009 155 2 0.0000 -14.6430 11.6070 -16.0860 # CM
+2010 155 2 0.0000 -14.5500 11.1650 -15.8730 # CM
+2011 155 2 0.0000 -14.9610 10.9970 -15.6430 # CM
+2012 155 2 0.0000 -14.8730 10.5690 -15.3990 # CM
+2013 155 2 0.0000 -15.2990 10.3950 -15.2030 # CM
+2014 155 2 0.0000 -15.2880 9.9030 -15.1200 # CM
+2015 155 3 0.0000 -15.6450 9.7850 -14.7910 # CT
+2016 156 1 -1.0000 -29.5310 -12.8060 -8.3450 # HG
+2017 156 2 0.0000 -28.7920 -12.9120 -8.4210 # CM
+2018 156 2 0.0000 -28.5250 -12.5090 -8.2900 # CM
+2019 156 2 0.0000 -28.0310 -12.5440 -8.3520 # CM
+2020 156 2 0.0000 -27.7940 -12.1350 -8.1870 # CM
+2021 156 2 0.0000 -27.3210 -12.1700 -8.3420 # CM
+2022 156 2 0.0000 -27.0680 -11.7500 -8.2420 # CM
+2023 156 2 0.0000 -26.6010 -11.7750 -8.4150 # CM
+2024 156 2 0.0000 -26.3130 -11.4430 -8.1760 # CM
+2025 156 2 0.0000 -25.8480 -11.4350 -8.3610 # CM
+2026 156 2 0.0000 -25.5640 -11.1240 -8.0920 # CM
+2027 156 2 0.0000 -25.0760 -11.2290 -8.1250 # CM
+2028 156 3 0.0000 -24.8140 -10.8270 -7.9860 # CT
+2029 157 1 -1.0000 -26.7120 -24.6480 16.3400 # HG
+2030 157 2 0.0000 -26.8890 -25.3500 16.1420 # CM
+2031 157 2 0.0000 -27.3270 -25.3770 15.9020 # CM
+2032 157 2 0.0000 -27.4810 -25.8370 15.7780 # CM
+2033 157 2 0.0000 -27.9080 -25.8240 15.5170 # CM
+2034 157 2 0.0000 -28.0710 -26.2960 15.4870 # CM
+2035 157 2 0.0000 -28.5260 -26.3140 15.2800 # CM
+2036 157 2 0.0000 -28.7010 -26.7810 15.2680 # CM
+2037 157 2 0.0000 -29.0620 -26.8200 14.9240 # CM
+2038 157 2 0.0000 -29.2670 -27.2760 14.9230 # CM
+2039 157 2 0.0000 -29.6010 -27.3110 14.5530 # CM
+2040 157 2 0.0000 -29.6830 -27.7820 14.4080 # CM
+2041 157 3 0.0000 -30.1170 -27.8030 14.1630 # CT
+2042 158 1 -1.0000 25.0030 15.1800 13.1950 # HG
+2043 158 2 0.0000 24.4850 14.7620 12.8490 # CM
+2044 158 2 0.0000 24.0510 15.0030 12.7900 # CM
+2045 158 2 0.0000 23.6800 14.7400 12.5820 # CM
+2046 158 2 0.0000 23.2710 15.0200 12.5130 # CM
+2047 158 2 0.0000 22.9030 14.7060 12.3870 # CM
+2048 158 2 0.0000 22.4640 14.9460 12.3650 # CM
+2049 158 2 0.0000 22.0910 14.6320 12.2600 # CM
+2050 158 2 0.0000 21.7000 14.8850 12.0780 # CM
+2051 158 2 0.0000 21.3080 14.5860 11.9970 # CM
+2052 158 2 0.0000 20.9370 14.8450 11.7840 # CM
+2053 158 2 0.0000 20.6200 14.5570 11.5280 # CM
+2054 158 3 0.0000 20.1910 14.8040 11.4650 # CT
+2055 159 1 -1.0000 -11.6390 -9.6420 -34.1460 # HG
+2056 159 2 0.0000 -11.5020 -9.1740 -33.5770 # CM
+2057 159 2 0.0000 -11.9010 -9.1050 -33.2830 # CM
+2058 159 2 0.0000 -11.8450 -8.7800 -32.9080 # CM
+2059 159 2 0.0000 -12.2530 -8.7570 -32.6200 # CM
+2060 159 2 0.0000 -12.1920 -8.3660 -32.3140 # CM
+2061 159 2 0.0000 -12.6080 -8.2800 -32.0500 # CM
+2062 159 2 0.0000 -12.5560 -7.8770 -31.7590 # CM
+2063 159 2 0.0000 -12.8900 -7.8910 -31.3880 # CM
+2064 159 2 0.0000 -12.8700 -7.4780 -31.1060 # CM
+2065 159 2 0.0000 -13.1850 -7.5200 -30.7210 # CM
+2066 159 2 0.0000 -13.0610 -7.2280 -30.3350 # CM
+2067 159 3 0.0000 -13.4600 -7.1680 -30.0410 # CT
+2068 160 1 -1.0000 -31.2890 33.7360 -5.7760 # HG
+2069 160 2 0.0000 -31.8820 33.4250 -6.1140 # CM
+2070 160 2 0.0000 -31.8080 32.9450 -6.2310 # CM
+2071 160 2 0.0000 -32.1790 32.7190 -6.4780 # CM
+2072 160 2 0.0000 -32.0820 32.2340 -6.5540 # CM
+2073 160 2 0.0000 -32.4290 32.0660 -6.8730 # CM
+2074 160 2 0.0000 -32.3290 31.5970 -7.0150 # CM
+2075 160 2 0.0000 -32.6620 31.4350 -7.3490 # CM
+2076 160 2 0.0000 -32.6620 30.9350 -7.3610 # CM
+2077 160 2 0.0000 -32.9700 30.7590 -7.7140 # CM
+2078 160 2 0.0000 -32.9860 30.2600 -7.6920 # CM
+2079 160 2 0.0000 -33.4030 30.0700 -7.8890 # CM
+2080 160 3 0.0000 -33.3260 29.5880 -7.9970 # CT
+2081 161 1 -1.0000 23.9360 -30.6120 -31.5890 # HG
+2082 161 2 0.0000 23.2840 -30.2500 -31.6660 # CM
+2083 161 2 0.0000 23.3040 -29.7800 -31.4960 # CM
+2084 161 2 0.0000 22.8760 -29.5220 -31.5150 # CM
+2085 161 2 0.0000 22.9380 -29.0490 -31.3630 # CM
+2086 161 2 0.0000 22.4820 -28.8520 -31.3140 # CM
+2087 161 2 0.0000 22.5050 -28.3960 -31.1090 # CM
+2088 161 2 0.0000 22.0490 -28.2060 -31.0400 # CM
+2089 161 2 0.0000 22.0760 -27.7090 -30.9980 # CM
+2090 161 2 0.0000 21.6290 -27.5080 -30.8970 # CM
+2091 161 2 0.0000 21.6640 -27.0090 -30.8910 # CM
+2092 161 2 0.0000 21.2280 -26.7820 -30.9780 # CM
+2093 161 3 0.0000 21.2550 -26.3110 -30.8140 # CT
+2094 162 1 -1.0000 -8.8180 22.3790 13.7630 # HG
+2095 162 2 0.0000 -8.1890 22.3780 14.1700 # CM
+2096 162 2 0.0000 -7.9840 22.8320 14.2110 # CM
+2097 162 2 0.0000 -7.5510 22.8570 14.4590 # CM
+2098 162 2 0.0000 -7.3900 23.3290 14.5030 # CM
+2099 162 2 0.0000 -6.9220 23.3050 14.6760 # CM
+2100 162 2 0.0000 -6.7100 23.7580 14.6800 # CM
+2101 162 2 0.0000 -6.2350 23.7340 14.8320 # CM
+2102 162 2 0.0000 -6.0840 24.1840 14.9920 # CM
+2103 162 2 0.0000 -5.6000 24.1810 15.1190 # CM
+2104 162 2 0.0000 -5.4720 24.6260 15.3080 # CM
+2105 162 2 0.0000 -5.0720 24.6030 15.6050 # CM
+2106 162 3 0.0000 -4.8750 25.0600 15.6490 # CT
+2107 163 1 -1.0000 -34.1430 -5.3790 -0.0370 # HG
+2108 163 2 0.0000 -33.6730 -5.9480 0.0990 # CM
+2109 163 2 0.0000 -33.1950 -5.8020 0.1250 # CM
+2110 163 2 0.0000 -32.8580 -6.1640 0.1920 # CM
+2111 163 2 0.0000 -32.3950 -5.9800 0.2410 # CM
+2112 163 2 0.0000 -32.0830 -6.3690 0.2190 # CM
+2113 163 2 0.0000 -31.6070 -6.2150 0.2080 # CM
+2114 163 2 0.0000 -31.2930 -6.6010 0.1660 # CM
+2115 163 2 0.0000 -30.8370 -6.4680 0.3200 # CM
+2116 163 2 0.0000 -30.5050 -6.8370 0.2540 # CM
+2117 163 2 0.0000 -30.0620 -6.7020 0.4430 # CM
+2118 163 2 0.0000 -29.7740 -7.0930 0.5610 # CM
+2119 163 3 0.0000 -29.2990 -6.9400 0.5930 # CT
+2120 164 1 -1.0000 -31.6660 14.5400 27.2050 # HG
+2121 164 2 0.0000 -31.3030 13.9100 27.0210 # CM
+2122 164 2 0.0000 -31.6100 13.5180 26.9690 # CM
+2123 164 2 0.0000 -31.3920 13.0800 26.8680 # CM
+2124 164 2 0.0000 -31.7300 12.7180 26.7960 # CM
+2125 164 2 0.0000 -31.4780 12.2860 26.7850 # CM
+2126 164 2 0.0000 -31.7920 11.8970 26.7700 # CM
+2127 164 2 0.0000 -31.5430 11.4640 26.7790 # CM
+2128 164 2 0.0000 -31.8320 11.0980 26.6000 # CM
+2129 164 2 0.0000 -31.6050 10.6520 26.6330 # CM
+2130 164 2 0.0000 -31.8900 10.3010 26.4200 # CM
+2131 164 2 0.0000 -31.6290 9.9020 26.2710 # CM
+2132 164 3 0.0000 -31.9410 9.5160 26.2130 # CT
+2133 165 1 -1.0000 16.8460 8.7830 -3.9010 # HG
+2134 165 2 0.0000 16.3600 8.3930 -3.4830 # CM
+2135 165 2 0.0000 15.8840 8.4760 -3.6120 # CM
+2136 165 2 0.0000 15.5380 8.2460 -3.3340 # CM
+2137 165 2 0.0000 15.0760 8.3290 -3.5080 # CM
+2138 165 2 0.0000 14.7600 8.1580 -3.1610 # CM
+2139 165 2 0.0000 14.2880 8.2760 -3.2780 # CM
+2140 165 2 0.0000 13.9710 8.1250 -2.9220 # CM
+2141 165 2 0.0000 13.5090 8.0910 -3.1090 # CM
+2142 165 2 0.0000 13.1750 7.9700 -2.7560 # CM
+2143 165 2 0.0000 12.7250 7.9070 -2.9620 # CM
+2144 165 2 0.0000 12.4250 7.6160 -2.6880 # CM
+2145 165 3 0.0000 11.9510 7.6960 -2.8260 # CT
+2146 166 1 -1.0000 -14.4620 7.6080 0.9530 # HG
+2147 166 2 0.0000 -15.1930 7.6670 0.7960 # CM
+2148 166 2 0.0000 -15.3100 8.1040 0.5830 # CM
+2149 166 2 0.0000 -15.7950 8.1800 0.4880 # CM
+2150 166 2 0.0000 -15.8720 8.6140 0.2510 # CM
+2151 166 2 0.0000 -16.3650 8.6920 0.2510 # CM
+2152 166 2 0.0000 -16.4740 9.1460 0.0710 # CM
+2153 166 2 0.0000 -16.9640 9.2350 0.0900 # CM
+2154 166 2 0.0000 -17.0840 9.5980 -0.2320 # CM
+2155 166 2 0.0000 -17.5690 9.7190 -0.2010 # CM
+2156 166 2 0.0000 -17.6810 10.0590 -0.5500 # CM
+2157 166 2 0.0000 -18.1660 10.0620 -0.6690 # CM
+2158 166 3 0.0000 -18.2770 10.4970 -0.8890 # CT
+2159 167 1 -1.0000 -27.3620 -13.7930 -19.3990 # HG
+2160 167 2 0.0000 -26.8500 -14.3080 -19.5890 # CM
+2161 167 2 0.0000 -26.6990 -14.2640 -20.0640 # CM
+2162 167 2 0.0000 -26.3750 -14.6080 -20.2250 # CM
+2163 167 2 0.0000 -26.2250 -14.5180 -20.6940 # CM
+2164 167 2 0.0000 -25.9740 -14.9220 -20.8450 # CM
+2165 167 2 0.0000 -25.8580 -14.8890 -21.3300 # CM
+2166 167 2 0.0000 -25.6260 -15.3010 -21.4890 # CM
+2167 167 2 0.0000 -25.3710 -15.2020 -21.9080 # CM
+2168 167 2 0.0000 -25.1580 -15.6140 -22.0960 # CM
+2169 167 2 0.0000 -24.8800 -15.4960 -22.4930 # CM
+2170 167 2 0.0000 -24.5210 -15.8300 -22.5860 # CM
+2171 167 3 0.0000 -24.3680 -15.7770 -23.0590 # CT
+2172 168 1 -1.0000 -0.4160 -18.8450 14.5880 # HG
+2173 168 2 0.0000 -0.2600 -19.5640 14.7330 # CM
+2174 168 2 0.0000 0.2300 -19.6620 14.7170 # CM
+2175 168 2 0.0000 0.3610 -20.1390 14.7870 # CM
+2176 168 2 0.0000 0.8590 -20.1960 14.7920 # CM
+2177 168 2 0.0000 0.9470 -20.6870 14.7780 # CM
+2178 168 2 0.0000 1.4360 -20.7790 14.7250 # CM
+2179 168 2 0.0000 1.5250 -21.2690 14.6900 # CM
+2180 168 2 0.0000 2.0030 -21.3640 14.8040 # CM
+2181 168 2 0.0000 2.1140 -21.8480 14.7430 # CM
+2182 168 2 0.0000 2.5830 -21.9340 14.8920 # CM
+2183 168 2 0.0000 2.6620 -22.4110 15.0190 # CM
+2184 168 3 0.0000 3.1530 -22.5020 15.0090 # CT
+2185 169 1 -1.0000 25.0660 27.6470 6.8930 # HG
+2186 169 2 0.0000 25.1810 26.9260 6.7210 # CM
+2187 169 2 0.0000 24.7560 26.6640 6.6930 # CM
+2188 169 2 0.0000 24.8050 26.1750 6.6020 # CM
+2189 169 2 0.0000 24.3600 25.9500 6.5540 # CM
+2190 169 2 0.0000 24.4470 25.4580 6.5510 # CM
+2191 169 2 0.0000 24.0180 25.2010 6.5600 # CM
+2192 169 2 0.0000 24.1030 24.7090 6.5780 # CM
+2193 169 2 0.0000 23.6980 24.4610 6.4220 # CM
+2194 169 2 0.0000 23.7580 23.9660 6.4640 # CM
+2195 169 2 0.0000 23.3610 23.7300 6.2740 # CM
+2196 169 2 0.0000 23.4620 23.2620 6.1310 # CM
+2197 169 3 0.0000 23.0340 23.0070 6.0970 # CT
+2198 170 1 -1.0000 -17.6660 6.4830 13.1320 # HG
+2199 170 2 0.0000 -17.3040 5.9500 13.5160 # CM
+2200 170 2 0.0000 -16.8370 6.0840 13.6390 # CM
+2201 170 2 0.0000 -16.5650 5.7390 13.8760 # CM
+2202 170 2 0.0000 -16.1150 5.9160 14.0070 # CM
+2203 170 2 0.0000 -15.8460 5.5240 14.1610 # CM
+2204 170 2 0.0000 -15.3720 5.6570 14.2470 # CM
+2205 170 2 0.0000 -15.0950 5.2630 14.3800 # CM
+2206 170 2 0.0000 -14.6840 5.4160 14.6200 # CM
+2207 170 2 0.0000 -14.3830 5.0330 14.7330 # CM
+2208 170 2 0.0000 -13.9940 5.1960 15.0000 # CM
+2209 170 2 0.0000 -13.7850 4.8380 15.2780 # CM
+2210 170 3 0.0000 -13.3220 4.9790 15.4040 # CT
+2211 171 1 -1.0000 13.7680 25.0560 5.1700 # HG
+2212 171 2 0.0000 13.1760 25.5050 5.2650 # CM
+2213 171 2 0.0000 12.7520 25.2520 5.3450 # CM
+2214 171 2 0.0000 12.3360 25.5260 5.3890 # CM
+2215 171 2 0.0000 11.9380 25.2430 5.4960 # CM
+2216 171 2 0.0000 11.5360 25.5360 5.4470 # CM
+2217 171 2 0.0000 11.1150 25.2700 5.4920 # CM
+2218 171 2 0.0000 10.7120 25.5570 5.4230 # CM
+2219 171 2 0.0000 10.3110 25.3400 5.6270 # CM
+2220 171 2 0.0000 9.8940 25.6020 5.5390 # CM
+2221 171 2 0.0000 9.5080 25.3920 5.7760 # CM
+2222 171 2 0.0000 9.1350 25.7130 5.8630 # CM
+2223 171 3 0.0000 8.7160 25.4550 5.9500 # CT
+2224 172 1 -1.0000 19.6530 -11.3600 -7.0560 # HG
+2225 172 2 0.0000 19.1940 -11.8240 -7.4260 # CM
+2226 172 2 0.0000 19.4260 -12.2350 -7.5900 # CM
+2227 172 2 0.0000 19.1490 -12.5510 -7.8600 # CM
+2228 172 2 0.0000 19.4060 -12.9630 -7.9840 # CM
+2229 172 2 0.0000 19.1280 -13.2090 -8.3190 # CM
+2230 172 2 0.0000 19.3800 -13.5980 -8.5080 # CM
+2231 172 2 0.0000 19.1140 -13.8330 -8.8580 # CM
+2232 172 2 0.0000 19.2860 -14.2990 -8.9200 # CM
+2233 172 2 0.0000 19.0480 -14.5360 -9.2900 # CM
+2234 172 2 0.0000 19.2060 -15.0090 -9.3180 # CM
+2235 172 2 0.0000 18.8750 -15.3130 -9.5360 # CM
+2236 172 3 0.0000 19.1100 -15.7250 -9.6920 # CT
+2237 173 1 -1.0000 0.1130 -23.5380 -8.7140 # HG
+2238 173 2 0.0000 0.0490 -24.1950 -9.0690 # CM
+2239 173 2 0.0000 0.0070 -24.5820 -8.7540 # CM
+2240 173 2 0.0000 -0.0140 -25.0350 -8.9640 # CM
+2241 173 2 0.0000 -0.0830 -25.3940 -8.6220 # CM
+2242 173 2 0.0000 -0.0130 -25.8300 -8.8560 # CM
+2243 173 2 0.0000 -0.0190 -26.2100 -8.5300 # CM
+2244 173 2 0.0000 0.0710 -26.6450 -8.7580 # CM
+2245 173 2 0.0000 -0.0970 -27.0230 -8.4770 # CM
+2246 173 2 0.0000 0.0150 -27.4670 -8.6800 # CM
+2247 173 2 0.0000 -0.1870 -27.8330 -8.4070 # CM
+2248 173 2 0.0000 -0.2550 -28.2540 -8.6670 # CM
+2249 173 3 0.0000 -0.3040 -28.6360 -8.3480 # CT
+2250 174 1 -1.0000 29.5610 14.9970 -24.8720 # HG
+2251 174 2 0.0000 29.7570 14.3140 -24.6310 # CM
+2252 174 2 0.0000 29.4580 13.9540 -24.8070 # CM
+2253 174 2 0.0000 29.5520 13.4910 -24.6440 # CM
+2254 174 2 0.0000 29.2530 13.1540 -24.8620 # CM
+2255 174 2 0.0000 29.3170 12.7240 -24.6140 # CM
+2256 174 2 0.0000 28.9900 12.3790 -24.7700 # CM
+2257 174 2 0.0000 29.0380 11.9550 -24.5100 # CM
+2258 174 2 0.0000 28.8400 11.5750 -24.7660 # CM
+2259 174 2 0.0000 28.8540 11.1490 -24.5040 # CM
+2260 174 2 0.0000 28.6840 10.7710 -24.7840 # CM
+2261 174 2 0.0000 28.8520 10.3260 -24.6320 # CM
+2262 174 3 0.0000 28.5540 9.9690 -24.8170 # CT
+2263 175 1 -1.0000 -26.2010 -7.7950 16.7930 # HG
+2264 175 2 0.0000 -25.7660 -7.7690 17.4020 # CM
+2265 175 2 0.0000 -25.5350 -7.3280 17.4560 # CM
+2266 175 2 0.0000 -25.2200 -7.2910 17.8420 # CM
+2267 175 2 0.0000 -25.0280 -6.8300 17.8800 # CM
+2268 175 2 0.0000 -24.6600 -6.8550 18.2180 # CM
+2269 175 2 0.0000 -24.4090 -6.4230 18.2400 # CM
+2270 175 2 0.0000 -24.0280 -6.4530 18.5610 # CM
+2271 175 2 0.0000 -23.8890 -5.9940 18.7040 # CM
+2272 175 2 0.0000 -23.4880 -6.0070 19.0020 # CM
+2273 175 2 0.0000 -23.3820 -5.5460 19.1630 # CM
+2274 175 2 0.0000 -23.1210 -5.5450 19.5900 # CM
+2275 175 3 0.0000 -22.8980 -5.1010 19.6420 # CT
+2276 176 1 -1.0000 -25.3230 7.8700 -1.7380 # HG
+2277 176 2 0.0000 -24.9240 7.4200 -2.1850 # CM
+2278 176 2 0.0000 -24.5030 7.6350 -2.3500 # CM
+2279 176 2 0.0000 -24.2290 7.3660 -2.6690 # CM
+2280 176 2 0.0000 -23.8030 7.6000 -2.7900 # CM
+2281 176 2 0.0000 -23.6020 7.3440 -3.1690 # CM
+2282 176 2 0.0000 -23.2030 7.5830 -3.3530 # CM
+2283 176 2 0.0000 -23.0120 7.3400 -3.7450 # CM
+2284 176 2 0.0000 -22.5380 7.4800 -3.8180 # CM
+2285 176 2 0.0000 -22.3430 7.2670 -4.2270 # CM
+2286 176 2 0.0000 -21.8600 7.3890 -4.2690 # CM
+2287 176 2 0.0000 -21.6000 7.0600 -4.5410 # CM
+2288 176 3 0.0000 -21.1780 7.2770 -4.6960 # CT
+2289 177 1 -1.0000 -21.7590 -34.4690 10.1950 # HG
+2290 177 2 0.0000 -22.2660 -34.1280 9.7610 # CM
+2291 177 2 0.0000 -22.3930 -33.6750 9.9320 # CM
+2292 177 2 0.0000 -22.7470 -33.4340 9.6730 # CM
+2293 177 2 0.0000 -22.8280 -32.9750 9.8560 # CM
+2294 177 2 0.0000 -23.2400 -32.8030 9.6300 # CM
+2295 177 2 0.0000 -23.3830 -32.3680 9.8310 # CM
+2296 177 2 0.0000 -23.8060 -32.2030 9.6220 # CM
+2297 177 2 0.0000 -23.8530 -31.7110 9.6970 # CM
+2298 177 2 0.0000 -24.2880 -31.5390 9.5190 # CM
+2299 177 2 0.0000 -24.3070 -31.0420 9.5710 # CM
+2300 177 2 0.0000 -24.6230 -30.8260 9.2500 # CM
+2301 177 3 0.0000 -24.7410 -30.3710 9.4210 # CT
+2302 178 1 -1.0000 19.1340 26.1820 28.9400 # HG
+2303 178 2 0.0000 19.5810 26.7450 29.1520 # CM
+2304 178 2 0.0000 19.3680 27.1930 29.0930 # CM
+2305 178 2 0.0000 19.6520 27.5890 29.2050 # CM
+2306 178 2 0.0000 19.3990 28.0180 29.1610 # CM
+2307 178 2 0.0000 19.7340 28.3870 29.1970 # CM
+2308 178 2 0.0000 19.5220 28.8300 29.1010 # CM
+2309 178 2 0.0000 19.8590 29.1980 29.1150 # CM
+2310 178 2 0.0000 19.6300 29.6360 29.1850 # CM
+2311 178 2 0.0000 19.9530 30.0180 29.1710 # CM
+2312 178 2 0.0000 19.7160 30.4450 29.2750 # CM
+2313 178 2 0.0000 20.0230 30.8000 29.4490 # CM
+2314 178 3 0.0000 19.8020 31.2450 29.3950 # CT
+2315 179 1 -1.0000 19.0870 8.1440 -24.2410 # HG
+2316 179 2 0.0000 19.2180 8.8380 -23.9900 # CM
+2317 179 2 0.0000 19.4960 9.1090 -24.3050 # CM
+2318 179 2 0.0000 19.6180 9.5690 -24.1520 # CM
+2319 179 2 0.0000 19.8720 9.8190 -24.5030 # CM
+2320 179 2 0.0000 20.0470 10.2330 -24.2850 # CM
+2321 179 2 0.0000 20.3550 10.4800 -24.5930 # CM
+2322 179 2 0.0000 20.5470 10.8830 -24.3700 # CM
+2323 179 2 0.0000 20.7100 11.2070 -24.7150 # CM
+2324 179 2 0.0000 20.9340 11.6030 -24.5050 # CM
+2325 179 2 0.0000 21.0610 11.9320 -24.8580 # CM
+2326 179 2 0.0000 21.1110 12.3970 -24.6810 # CM
+2327 179 3 0.0000 21.3830 12.6650 -25.0030 # CT
+2328 180 1 -1.0000 -24.0650 31.9050 4.6080 # HG
+2329 180 2 0.0000 -24.3520 31.2460 4.8230 # CM
+2330 180 2 0.0000 -24.5530 30.9900 4.4430 # CM
+2331 180 2 0.0000 -24.7710 30.5570 4.5620 # CM
+2332 180 2 0.0000 -24.9370 30.3150 4.1560 # CM
+2333 180 2 0.0000 -25.2200 29.9370 4.3190 # CM
+2334 180 2 0.0000 -25.4480 29.7080 3.9370 # CM
+2335 180 2 0.0000 -25.7470 29.3430 4.0990 # CM
+2336 180 2 0.0000 -25.8370 29.0190 3.7290 # CM
+2337 180 2 0.0000 -26.1610 28.6640 3.8680 # CM
+2338 180 2 0.0000 -26.2160 28.3300 3.5010 # CM
+2339 180 2 0.0000 -26.3730 27.8850 3.6650 # CM
+2340 180 3 0.0000 -26.5670 27.6300 3.2810 # CT
+2341 181 1 -1.0000 11.5540 -24.4000 1.8040 # HG
+2342 181 2 0.0000 12.0820 -24.7630 1.4150 # CM
+2343 181 2 0.0000 12.0090 -25.2570 1.4050 # CM
+2344 181 2 0.0000 12.3600 -25.5270 1.1710 # CM
+2345 181 2 0.0000 12.2400 -26.0130 1.1570 # CM
+2346 181 2 0.0000 12.6470 -26.2550 0.9960 # CM
+2347 181 2 0.0000 12.5810 -26.7500 1.0230 # CM
+2348 181 2 0.0000 12.9930 -26.9950 0.8820 # CM
+2349 181 2 0.0000 12.8760 -27.4640 0.7520 # CM
+2350 181 2 0.0000 13.2840 -27.7300 0.6380 # CM
+2351 181 2 0.0000 13.1510 -28.1840 0.4780 # CM
+2352 181 2 0.0000 13.4990 -28.3990 0.1910 # CM
+2353 181 3 0.0000 13.4180 -28.8910 0.1780 # CT
+2354 182 1 -1.0000 -24.2490 -27.7150 9.0480 # HG
+2355 182 2 0.0000 -24.0590 -27.0810 8.6970 # CM
+2356 182 2 0.0000 -23.5690 -26.9860 8.7220 # CM
+2357 182 2 0.0000 -23.4170 -26.5560 8.5150 # CM
+2358 182 2 0.0000 -22.9190 -26.5070 8.5340 # CM
+2359 182 2 0.0000 -22.8160 -26.0370 8.3990 # CM
+2360 182 2 0.0000 -22.3300 -25.9370 8.4610 # CM
+2361 182 2 0.0000 -22.2280 -25.4620 8.3470 # CM
+2362 182 2 0.0000 -21.7410 -25.4110 8.2490 # CM
+2363 182 2 0.0000 -21.6190 -24.9330 8.1630 # CM
+2364 182 2 0.0000 -21.1370 -24.9010 8.0340 # CM
+2365 182 2 0.0000 -21.0330 -24.4900 7.7700 # CM
+2366 182 3 0.0000 -20.5420 -24.4040 7.7910 # CT
+2367 183 1 -1.0000 14.3090 -9.2830 9.9460 # HG
+2368 183 2 0.0000 14.0100 -9.9690 9.8990 # CM
+2369 183 2 0.0000 14.3560 -10.3300 9.8830 # CM
+2370 183 2 0.0000 14.1840 -10.7970 9.8290 # CM
+2371 183 2 0.0000 14.5550 -11.1330 9.8440 # CM
+2372 183 2 0.0000 14.3580 -11.5700 9.7020 # CM
+2373 183 2 0.0000 14.7140 -11.9180 9.6520 # CM
+2374 183 2 0.0000 14.5230 -12.3500 9.4900 # CM
+2375 183 2 0.0000 14.8340 -12.7250 9.5990 # CM
+2376 183 2 0.0000 14.6690 -13.1610 9.4150 # CM
+2377 183 2 0.0000 14.9710 -13.5310 9.5590 # CM
+2378 183 2 0.0000 14.7470 -13.9770 9.5560 # CM
+2379 183 3 0.0000 15.0960 -14.3350 9.5480 # CT
+2380 184 1 -1.0000 -17.3570 -31.0470 17.3790 # HG
+2381 184 2 0.0000 -17.6480 -30.3570 17.4160 # CM
+2382 184 2 0.0000 -17.5690 -30.1370 17.8580 # CM
+2383 184 2 0.0000 -17.7720 -29.6840 17.9190 # CM
+2384 184 2 0.0000 -17.6500 -29.4840 18.3610 # CM
+2385 184 2 0.0000 -17.9360 -29.0790 18.4190 # CM
+2386 184 2 0.0000 -17.8800 -28.8850 18.8760 # CM
+2387 184 2 0.0000 -18.1810 -28.4920 18.9440 # CM
+2388 184 2 0.0000 -18.0090 -28.2090 19.3190 # CM
+2389 184 2 0.0000 -18.3180 -27.8280 19.4180 # CM
+2390 184 2 0.0000 -18.1190 -27.5360 19.7710 # CM
+2391 184 2 0.0000 -18.2970 -27.0690 19.7600 # CM
+2392 184 3 0.0000 -18.2090 -26.8520 20.2020 # CT
+2393 185 1 -1.0000 23.0170 -18.0570 12.2720 # HG
+2394 185 2 0.0000 22.6150 -18.3130 12.8510 # CM
+2395 185 2 0.0000 22.8710 -18.3110 13.2800 # CM
+2396 185 2 0.0000 22.6350 -18.4990 13.6780 # CM
+2397 185 2 0.0000 22.9100 -18.4560 14.0940 # CM
+2398 185 2 0.0000 22.6800 -18.7260 14.4460 # CM
+2399 185 2 0.0000 22.9590 -18.7510 14.8610 # CM
+2400 185 2 0.0000 22.7420 -19.0380 15.2070 # CM
+2401 185 2 0.0000 22.9270 -18.9300 15.6590 # CM
+2402 185 2 0.0000 22.7400 -19.2320 16.0120 # CM
+2403 185 2 0.0000 22.9070 -19.0910 16.4610 # CM
+2404 185 2 0.0000 22.6090 -19.2390 16.8340 # CM
+2405 185 3 0.0000 22.8670 -19.2280 17.2620 # CT
+2406 186 1 -1.0000 15.2690 23.1070 -8.5020 # HG
+2407 186 2 0.0000 14.5430 23.1290 -8.3130 # CM
+2408 186 2 0.0000 14.3790 22.6960 -8.1250 # CM
+2409 186 2 0.0000 13.8930 22.6750 -8.0110 # CM
+2410 186 2 0.0000 13.7700 22.2380 -7.8010 # CM
+2411 186 2 0.0000 13.2710 22.2230 -7.7820 # CM
+2412 186 2 0.0000 13.1120 21.7740 -7.6280 # CM
+2413 186 2 0.0000 12.6140 21.7490 -7.6280 # CM
+2414 186 2 0.0000 12.4610 21.3810 -7.3270 # CM
+2415 186 2 0.0000 11.9640 21.3240 -7.3420 # CM
+2416 186 2 0.0000 11.8230 20.9760 -7.0120 # CM
+2417 186 2 0.0000 11.3470 21.0260 -6.8690 # CM
+2418 186 3 0.0000 11.1900 20.5930 -6.6750 # CT
+2419 187 1 -1.0000 24.6520 12.5610 30.0310 # HG
+2420 187 2 0.0000 24.7330 13.2440 29.7320 # CM
+2421 187 2 0.0000 24.9140 13.5770 30.0580 # CM
+2422 187 2 0.0000 24.9570 14.0470 29.8920 # CM
+2423 187 2 0.0000 25.1660 14.3460 30.2340 # CM
+2424 187 2 0.0000 25.1130 14.8140 30.0670 # CM
+2425 187 2 0.0000 25.2610 15.1440 30.4120 # CM
+2426 187 2 0.0000 25.1900 15.6130 30.2560 # CM
+2427 187 2 0.0000 25.4820 15.9260 30.5160 # CM
+2428 187 2 0.0000 25.3980 16.4030 30.3900 # CM
+2429 187 2 0.0000 25.7180 16.7000 30.6320 # CM
+2430 187 2 0.0000 25.7890 17.1380 30.4020 # CM
+2431 187 3 0.0000 25.9760 17.4650 30.7300 # CT
+2432 188 1 -1.0000 1.4940 -6.4440 -0.9810 # HG
+2433 188 2 0.0000 0.9200 -6.1490 -1.3640 # CM
+2434 188 2 0.0000 0.9450 -5.6500 -1.3940 # CM
+2435 188 2 0.0000 0.5630 -5.4250 -1.6250 # CM
+2436 188 2 0.0000 0.6340 -4.9300 -1.6610 # CM
+2437 188 2 0.0000 0.2020 -4.7340 -1.8160 # CM
+2438 188 2 0.0000 0.2200 -4.2340 -1.8080 # CM
+2439 188 2 0.0000 -0.2180 -4.0360 -1.9430 # CM
+2440 188 2 0.0000 -0.1510 -3.5630 -2.0940 # CM
+2441 188 2 0.0000 -0.5870 -3.3420 -2.2020 # CM
+2442 188 2 0.0000 -0.5040 -2.8840 -2.3830 # CM
+2443 188 2 0.0000 -0.8790 -2.7140 -2.6650 # CM
+2444 188 3 0.0000 -0.8460 -2.2170 -2.6980 # CT
+2445 189 1 -1.0000 -23.6820 11.5890 -22.3600 # HG
+2446 189 2 0.0000 -24.2770 12.0400 -22.2970 # CM
+2447 189 2 0.0000 -24.1980 12.4230 -21.9850 # CM
+2448 189 2 0.0000 -24.5860 12.7270 -21.9070 # CM
+2449 189 2 0.0000 -24.4630 13.1130 -21.6120 # CM
+2450 189 2 0.0000 -24.8900 13.3420 -21.4890 # CM
+2451 189 2 0.0000 -24.8090 13.7000 -21.1490 # CM
+2452 189 2 0.0000 -25.2360 13.9160 -21.0090 # CM
+2453 189 2 0.0000 -25.1430 14.3640 -20.8090 # CM
+2454 189 2 0.0000 -25.5600 14.5800 -20.6360 # CM
+2455 189 2 0.0000 -25.4580 15.0400 -20.4700 # CM
+2456 189 2 0.0000 -25.8580 15.3390 -20.4670 # CM
+2457 189 3 0.0000 -25.7700 15.7230 -20.1610 # CT
+2458 190 1 -1.0000 0.3830 19.9890 -25.7030 # HG
+2459 190 2 0.0000 0.0020 19.5840 -26.2050 # CM
+2460 190 2 0.0000 -0.4930 19.6000 -26.1310 # CM
+2461 190 2 0.0000 -0.7700 19.3200 -26.4380 # CM
+2462 190 2 0.0000 -1.2600 19.3820 -26.3530 # CM
+2463 190 2 0.0000 -1.4960 19.0280 -26.6150 # CM
+2464 190 2 0.0000 -1.9850 19.0250 -26.5090 # CM
+2465 190 2 0.0000 -2.2210 18.6590 -26.7540 # CM
+2466 190 2 0.0000 -2.7100 18.7590 -26.7800 # CM
+2467 190 2 0.0000 -2.9630 18.3850 -26.9960 # CM
+2468 190 2 0.0000 -3.4440 18.5120 -27.0450 # CM
+2469 190 2 0.0000 -3.6760 18.2590 -27.4080 # CM
+2470 190 3 0.0000 -4.1690 18.2840 -27.3340 # CT
+2471 191 1 -1.0000 13.1870 -8.9170 33.7110 # HG
+2472 191 2 0.0000 12.4720 -9.0480 33.5260 # CM
+2473 191 2 0.0000 12.2060 -8.6270 33.4730 # CM
+2474 191 2 0.0000 11.7200 -8.6850 33.3720 # CM
+2475 191 2 0.0000 11.4920 -8.2460 33.2990 # CM
+2476 191 2 0.0000 11.0010 -8.3390 33.2870 # CM
+2477 191 2 0.0000 10.7400 -7.9120 33.2710 # CM
+2478 191 2 0.0000 10.2490 -8.0020 33.2800 # CM
+2479 191 2 0.0000 10.0000 -7.6070 33.1000 # CM
+2480 191 2 0.0000 9.5050 -7.6700 33.1330 # CM
+2481 191 2 0.0000 9.2700 -7.2840 32.9190 # CM
+2482 191 2 0.0000 8.8070 -7.3970 32.7700 # CM
+2483 191 3 0.0000 8.5480 -6.9740 32.7110 # CT
+2484 192 1 -1.0000 -3.7770 14.1840 -1.3450 # HG
+2485 192 2 0.0000 -4.4680 14.4290 -1.5040 # CM
+2486 192 2 0.0000 -4.8100 14.0650 -1.4850 # CM
+2487 192 2 0.0000 -5.2770 14.1950 -1.6090 # CM
+2488 192 2 0.0000 -5.5970 13.8140 -1.5520 # CM
+2489 192 2 0.0000 -6.0270 13.9560 -1.7640 # CM
+2490 192 2 0.0000 -6.3530 13.5770 -1.7760 # CM
+2491 192 2 0.0000 -6.7760 13.7090 -2.0050 # CM
+2492 192 2 0.0000 -7.1460 13.4010 -1.8720 # CM
+2493 192 2 0.0000 -7.5690 13.5040 -2.1190 # CM
+2494 192 2 0.0000 -7.9380 13.2110 -1.9520 # CM
+2495 192 2 0.0000 -8.3910 13.4040 -2.0340 # CM
+2496 192 3 0.0000 -8.7310 13.0390 -2.0060 # CT
+2497 193 1 -1.0000 -1.6230 -8.3120 -31.5140 # HG
+2498 193 2 0.0000 -0.9830 -8.0210 -31.2530 # CM
+2499 193 2 0.0000 -0.6800 -8.3670 -31.0560 # CM
+2500 193 2 0.0000 -0.2550 -8.1970 -30.8540 # CM
+2501 193 2 0.0000 0.0350 -8.5720 -30.6920 # CM
+2502 193 2 0.0000 0.4020 -8.3630 -30.4250 # CM
+2503 193 2 0.0000 0.6800 -8.7140 -30.2000 # CM
+2504 193 2 0.0000 1.0340 -8.5080 -29.9150 # CM
+2505 193 2 0.0000 1.4000 -8.8390 -29.8330 # CM
+2506 193 2 0.0000 1.7470 -8.6560 -29.5220 # CM
+2507 193 2 0.0000 2.1220 -8.9830 -29.4750 # CM
+2508 193 2 0.0000 2.5510 -8.7690 -29.3350 # CM
+2509 193 3 0.0000 2.8530 -9.1190 -29.1460 # CT
+2510 194 1 -1.0000 28.0190 18.1130 31.9420 # HG
+2511 194 2 0.0000 28.1820 17.4100 31.7390 # CM
+2512 194 2 0.0000 28.1470 17.0860 32.1180 # CM
+2513 194 2 0.0000 28.2720 16.6130 32.0160 # CM
+2514 194 2 0.0000 28.1990 16.3130 32.4100 # CM
+2515 194 2 0.0000 28.4130 15.8750 32.2980 # CM
+2516 194 2 0.0000 28.4080 15.5690 32.6930 # CM
+2517 194 2 0.0000 28.6400 15.1380 32.5910 # CM
+2518 194 2 0.0000 28.4920 14.7850 32.9120 # CM
+2519 194 2 0.0000 28.7400 14.3560 32.8400 # CM
+2520 194 2 0.0000 28.5590 14.0030 33.1440 # CM
+2521 194 2 0.0000 28.6450 13.5400 32.9770 # CM
+2522 194 3 0.0000 28.6010 13.2190 33.3580 # CT
+2523 195 1 -1.0000 -33.4980 -17.6400 11.7990 # HG
+2524 195 2 0.0000 -32.8100 -17.9110 11.9240 # CM
+2525 195 2 0.0000 -32.4660 -17.5510 11.9730 # CM
+2526 195 2 0.0000 -31.9950 -17.7050 12.0340 # CM
+2527 195 2 0.0000 -31.6830 -17.3200 12.1070 # CM
+2528 195 2 0.0000 -31.2190 -17.5040 12.0780 # CM
+2529 195 2 0.0000 -30.8800 -17.1360 12.0900 # CM
+2530 195 2 0.0000 -30.4170 -17.3150 12.0400 # CM
+2531 195 2 0.0000 -30.0860 -16.9840 12.2160 # CM
+2532 195 2 0.0000 -29.6160 -17.1380 12.1440 # CM
+2533 195 2 0.0000 -29.2980 -16.8140 12.3530 # CM
+2534 195 2 0.0000 -28.8560 -17.0190 12.4630 # CM
+2535 195 3 0.0000 -28.5170 -16.6550 12.5180 # CT
+2536 196 1 -1.0000 2.6310 29.1680 17.2560 # HG
+2537 196 2 0.0000 2.1570 29.7490 17.2520 # CM
+2538 196 2 0.0000 1.8330 29.7380 17.6320 # CM
+2539 196 2 0.0000 1.4900 30.1020 17.6410 # CM
+2540 196 2 0.0000 1.2010 30.0740 18.0480 # CM
+2541 196 2 0.0000 0.8250 30.3950 17.9790 # CM
+2542 196 2 0.0000 0.4850 30.3520 18.3440 # CM
+2543 196 2 0.0000 0.0970 30.6570 18.2660 # CM
+2544 196 2 0.0000 -0.1470 30.7350 18.6950 # CM
+2545 196 2 0.0000 -0.5570 31.0150 18.6250 # CM
+2546 196 2 0.0000 -0.7710 31.1130 19.0660 # CM
+2547 196 2 0.0000 -1.0560 31.5230 19.0560 # CM
+2548 196 3 0.0000 -1.3730 31.5110 19.4420 # CT
+2549 197 1 -1.0000 -25.4650 1.1950 -15.4860 # HG
+2550 197 2 0.0000 -25.2320 1.4030 -14.8050 # CM
+2551 197 2 0.0000 -24.7400 1.4950 -14.7890 # CM
+2552 197 2 0.0000 -24.5530 1.6140 -14.3410 # CM
+2553 197 2 0.0000 -24.0660 1.7250 -14.3670 # CM
+2554 197 2 0.0000 -23.9000 1.7540 -13.8970 # CM
+2555 197 2 0.0000 -23.4020 1.8090 -13.8870 # CM
+2556 197 2 0.0000 -23.2310 1.8160 -13.4180 # CM
+2557 197 2 0.0000 -22.7800 2.0320 -13.4050 # CM
+2558 197 2 0.0000 -22.5830 2.0190 -12.9450 # CM
+2559 197 2 0.0000 -22.1490 2.2670 -12.9390 # CM
+2560 197 2 0.0000 -22.0250 2.4290 -12.4840 # CM
+2561 197 3 0.0000 -21.5350 2.5270 -12.4750 # CT
+2562 198 1 -1.0000 3.1190 -0.9520 -6.9540 # HG
+2563 198 2 0.0000 3.1750 -1.3320 -6.3100 # CM
+2564 198 2 0.0000 3.1880 -1.0320 -5.9100 # CM
+2565 198 2 0.0000 3.2480 -1.2580 -5.4680 # CM
+2566 198 2 0.0000 3.2290 -0.9310 -5.0890 # CM
+2567 198 2 0.0000 3.3760 -1.1780 -4.6800 # CM
+2568 198 2 0.0000 3.4230 -0.8660 -4.2920 # CM
+2569 198 2 0.0000 3.5900 -1.1050 -3.8870 # CM
+2570 198 2 0.0000 3.4790 -0.8440 -3.4760 # CM
+2571 198 2 0.0000 3.6680 -1.0580 -3.0640 # CM
+2572 198 2 0.0000 3.5210 -0.8050 -2.6590 # CM
+2573 198 2 0.0000 3.5300 -1.0820 -2.2440 # CM
+2574 198 3 0.0000 3.5350 -0.7780 -1.8470 # CT
+2575 199 1 -1.0000 25.6590 -31.6970 -12.1900 # HG
+2576 199 2 0.0000 25.0340 -31.4380 -11.8660 # CM
+2577 199 2 0.0000 24.6990 -31.2720 -12.1990 # CM
+2578 199 2 0.0000 24.2820 -31.0720 -12.0090 # CM
+2579 199 2 0.0000 23.9590 -30.9420 -12.3690 # CM
+2580 199 2 0.0000 23.6000 -30.6730 -12.1490 # CM
+2581 199 2 0.0000 23.2890 -30.4790 -12.4900 # CM
+2582 199 2 0.0000 22.9420 -30.1920 -12.2750 # CM
+2583 199 2 0.0000 22.5500 -30.1410 -12.5810 # CM
+2584 199 2 0.0000 22.2070 -29.8310 -12.3900 # CM
+2585 199 2 0.0000 21.8070 -29.8150 -12.6900 # CM
+2586 199 2 0.0000 21.3910 -29.6740 -12.4510 # CM
+2587 199 3 0.0000 21.0570 -29.5160 -12.7880 # CT
+2588 200 1 -1.0000 3.4270 -25.1360 -5.7970 # HG
+2589 200 2 0.0000 3.5280 -25.5260 -5.1640 # CM
+2590 200 2 0.0000 3.4870 -26.0190 -5.2320 # CM
+2591 200 2 0.0000 3.5270 -26.3020 -4.8210 # CM
+2592 200 2 0.0000 3.5080 -26.7900 -4.9300 # CM
+2593 200 2 0.0000 3.4650 -27.0330 -4.4960 # CM
+2594 200 2 0.0000 3.3860 -27.5210 -4.5710 # CM
+2595 200 2 0.0000 3.3220 -27.7620 -4.1390 # CM
+2596 200 2 0.0000 3.4110 -28.2500 -4.2010 # CM
+2597 200 2 0.0000 3.3200 -28.5090 -3.7830 # CM
+2598 200 2 0.0000 3.4440 -28.9890 -3.8490 # CM
+2599 200 2 0.0000 3.5430 -29.2250 -3.4210 # CM
+2600 200 3 0.0000 3.5080 -29.7180 -3.4950 # CT
+2601 201 1 -1.0000 -11.8950 -0.8540 27.0460 # HG
+2602 201 2 0.0000 -12.6370 -0.9610 27.0450 # CM
+2603 201 2 0.0000 -12.7630 -1.4450 27.0520 # CM
+2604 201 2 0.0000 -13.2520 -1.5450 27.0300 # CM
+2605 201 2 0.0000 -13.3420 -2.0360 27.0670 # CM
+2606 201 2 0.0000 -13.8240 -2.1030 26.9550 # CM
+2607 201 2 0.0000 -13.9350 -2.5900 26.9280 # CM
+2608 201 2 0.0000 -14.4120 -2.6590 26.7950 # CM
+2609 201 2 0.0000 -14.5610 -3.1170 26.9290 # CM
+2610 201 2 0.0000 -15.0280 -3.2110 26.7750 # CM
+2611 201 2 0.0000 -15.1750 -3.6580 26.9430 # CM
+2612 201 2 0.0000 -15.6720 -3.7010 26.9700 # CM
+2613 201 3 0.0000 -15.7920 -4.1860 26.9850 # CT
+2614 202 1 -1.0000 -9.3880 -25.3910 -26.3130 # HG
+2615 202 2 0.0000 -10.0620 -25.6930 -26.4370 # CM
+2616 202 2 0.0000 -10.4030 -25.3550 -26.5780 # CM
+2617 202 2 0.0000 -10.8680 -25.5260 -26.6460 # CM
+2618 202 2 0.0000 -11.1740 -25.1670 -26.8120 # CM
+2619 202 2 0.0000 -11.6380 -25.3510 -26.7850 # CM
+2620 202 2 0.0000 -11.9760 -24.9980 -26.8910 # CM
+2621 202 2 0.0000 -12.4410 -25.1730 -26.8450 # CM
+2622 202 2 0.0000 -12.7580 -24.8860 -27.1030 # CM
+2623 202 2 0.0000 -13.2330 -25.0330 -27.0400 # CM
+2624 202 2 0.0000 -13.5350 -24.7590 -27.3300 # CM
+2625 202 2 0.0000 -13.9660 -24.9890 -27.4330 # CM
+2626 202 3 0.0000 -14.3000 -24.6480 -27.5800 # CT
+2627 203 1 -1.0000 -19.4360 7.0260 -27.2800 # HG
+2628 203 2 0.0000 -20.0090 6.7890 -27.7010 # CM
+2629 203 2 0.0000 -20.2570 7.1650 -27.9190 # CM
+2630 203 2 0.0000 -20.6590 7.0370 -28.1880 # CM
+2631 203 2 0.0000 -20.8650 7.4330 -28.4120 # CM
+2632 203 2 0.0000 -21.3040 7.2810 -28.5960 # CM
+2633 203 2 0.0000 -21.5640 7.6680 -28.7790 # CM
+2634 203 2 0.0000 -22.0120 7.5220 -28.9450 # CM
+2635 203 2 0.0000 -22.1920 7.8590 -29.2670 # CM
+2636 203 2 0.0000 -22.6550 7.7410 -29.4180 # CM
+2637 203 2 0.0000 -22.8090 8.0670 -29.7640 # CM
+2638 203 2 0.0000 -23.1670 7.8820 -30.0590 # CM
+2639 203 3 0.0000 -23.4070 8.2600 -30.2800 # CT
+2640 204 1 -1.0000 -11.9050 -1.7780 14.4070 # HG
+2641 204 2 0.0000 -11.3470 -1.9160 13.9250 # CM
+2642 204 2 0.0000 -11.3240 -2.3970 13.7890 # CM
+2643 204 2 0.0000 -10.9470 -2.5220 13.4860 # CM
+2644 204 2 0.0000 -10.9710 -3.0030 13.3490 # CM
+2645 204 2 0.0000 -10.5380 -3.1090 13.1220 # CM
+2646 204 2 0.0000 -10.5060 -3.5980 13.0210 # CM
+2647 204 2 0.0000 -10.0660 -3.7100 12.8130 # CM
+2648 204 2 0.0000 -10.0990 -4.1450 12.5690 # CM
+2649 204 2 0.0000 -9.6570 -4.2850 12.3810 # CM
+2650 204 2 0.0000 -9.7110 -4.7020 12.1120 # CM
+2651 204 2 0.0000 -9.3510 -4.7630 11.7710 # CM
+2652 204 3 0.0000 -9.3370 -5.2420 11.6330 # CT
+2653 205 1 -1.0000 13.2800 13.3190 -2.6500 # HG
+2654 205 2 0.0000 13.4850 14.0180 -2.4720 # CM
+2655 205 2 0.0000 13.9820 14.0750 -2.4530 # CM
+2656 205 2 0.0000 14.1460 14.5260 -2.3140 # CM
+2657 205 2 0.0000 14.6460 14.5550 -2.3330 # CM
+2658 205 2 0.0000 14.7730 14.9830 -2.1080 # CM
+2659 205 2 0.0000 15.2700 15.0170 -2.0590 # CM
+2660 205 2 0.0000 15.3990 15.4340 -1.8170 # CM
+2661 205 2 0.0000 15.8760 15.5470 -1.9140 # CM
+2662 205 2 0.0000 16.0280 15.9460 -1.6530 # CM
+2663 205 2 0.0000 16.4950 16.0670 -1.7850 # CM
+2664 205 2 0.0000 16.6050 16.5450 -1.6920 # CM
+2665 205 3 0.0000 17.1020 16.5990 -1.6810 # CT
+2666 206 1 -1.0000 -7.2330 18.9400 -4.7840 # HG
+2667 206 2 0.0000 -6.5510 19.2390 -4.8700 # CM
+2668 206 2 0.0000 -6.5150 19.6970 -4.6720 # CM
+2669 206 2 0.0000 -6.0770 19.9300 -4.7350 # CM
+2670 206 2 0.0000 -6.0670 20.3730 -4.5020 # CM
+2671 206 2 0.0000 -5.6540 20.6080 -4.6580 # CM
+2672 206 2 0.0000 -5.6420 21.0780 -4.4870 # CM
+2673 206 2 0.0000 -5.2410 21.3220 -4.6570 # CM
+2674 206 2 0.0000 -5.1440 21.7150 -4.3650 # CM
+2675 206 2 0.0000 -4.7620 21.9860 -4.5420 # CM
+2676 206 2 0.0000 -4.6540 22.3560 -4.2230 # CM
+2677 206 2 0.0000 -4.1850 22.5210 -4.2690 # CM
+2678 206 3 0.0000 -4.1520 22.9750 -4.0640 # CT
+2679 207 1 -1.0000 21.1170 -32.1390 -11.1360 # HG
+2680 207 2 0.0000 20.7250 -32.1830 -10.4970 # CM
+2681 207 2 0.0000 20.4370 -32.5910 -10.4760 # CM
+2682 207 2 0.0000 20.1480 -32.6350 -10.0710 # CM
+2683 207 2 0.0000 19.8940 -33.0670 -10.0700 # CM
+2684 207 2 0.0000 19.5580 -33.0350 -9.7010 # CM
+2685 207 2 0.0000 19.2490 -33.4280 -9.7080 # CM
+2686 207 2 0.0000 18.9000 -33.3890 -9.3530 # CM
+2687 207 2 0.0000 18.7070 -33.8390 -9.2540 # CM
+2688 207 2 0.0000 18.3330 -33.8100 -8.9220 # CM
+2689 207 2 0.0000 18.1730 -34.2690 -8.8070 # CM
+2690 207 2 0.0000 17.9450 -34.2900 -8.3620 # CM
+2691 207 3 0.0000 17.6640 -34.7030 -8.3430 # CT
+2692 208 1 -1.0000 9.6840 9.5020 -25.0640 # HG
+2693 208 2 0.0000 9.1320 9.7410 -24.6160 # CM
+2694 208 2 0.0000 9.1510 9.5370 -24.1600 # CM
+2695 208 2 0.0000 8.7810 9.6610 -23.8480 # CM
+2696 208 2 0.0000 8.8480 9.4610 -23.3930 # CM
+2697 208 2 0.0000 8.4230 9.5340 -23.1410 # CM
+2698 208 2 0.0000 8.4350 9.2970 -22.7010 # CM
+2699 208 2 0.0000 8.0030 9.3510 -22.4550 # CM
+2700 208 2 0.0000 8.0720 9.2640 -21.9680 # CM
+2701 208 2 0.0000 7.6420 9.2850 -21.7140 # CM
+2702 208 2 0.0000 7.7300 9.2290 -21.2250 # CM
+2703 208 2 0.0000 7.3700 9.4240 -20.9390 # CM
+2704 208 3 0.0000 7.3980 9.2230 -20.4830 # CT
+2705 209 1 -1.0000 -29.7760 17.5490 -18.5720 # HG
+2706 209 2 0.0000 -29.8110 17.0150 -19.0970 # CM
+2707 209 2 0.0000 -29.7140 17.1880 -19.5560 # CM
+2708 209 2 0.0000 -29.7530 16.8580 -19.9290 # CM
+2709 209 2 0.0000 -29.6230 17.0590 -20.3680 # CM
+2710 209 2 0.0000 -29.7550 16.7300 -20.7210 # CM
+2711 209 2 0.0000 -29.6910 16.9230 -21.1780 # CM
+2712 209 2 0.0000 -29.8420 16.6050 -21.5310 # CM
+2713 209 2 0.0000 -29.6290 16.7220 -21.9680 # CM
+2714 209 2 0.0000 -29.7960 16.4290 -22.3390 # CM
+2715 209 2 0.0000 -29.5510 16.5350 -22.7610 # CM
+2716 209 2 0.0000 -29.5530 16.1570 -23.0870 # CM
+2717 209 3 0.0000 -29.4490 16.3340 -23.5420 # CT
+2718 210 1 -1.0000 -25.1600 18.6470 11.8920 # HG
+2719 210 2 0.0000 -24.5370 18.2430 11.7830 # CM
+2720 210 2 0.0000 -24.6050 17.8680 11.4600 # CM
+2721 210 2 0.0000 -24.2110 17.5680 11.3860 # CM
+2722 210 2 0.0000 -24.3060 17.2220 11.0370 # CM
+2723 210 2 0.0000 -23.9270 16.8960 11.0540 # CM
+2724 210 2 0.0000 -24.0170 16.5040 10.7560 # CM
+2725 210 2 0.0000 -23.6510 16.1660 10.7860 # CM
+2726 210 2 0.0000 -23.6560 15.8720 10.3820 # CM
+2727 210 2 0.0000 -23.3130 15.5090 10.4130 # CM
+2728 210 2 0.0000 -23.3070 15.2440 9.9900 # CM
+2729 210 2 0.0000 -22.8720 15.0090 9.9140 # CM
+2730 210 3 0.0000 -22.9430 14.6400 9.5850 # CT
+2731 211 1 -1.0000 34.3780 1.2000 21.2140 # HG
+2732 211 2 0.0000 33.9640 1.8060 21.0580 # CM
+2733 211 2 0.0000 33.4840 1.6960 20.9740 # CM
+2734 211 2 0.0000 33.1890 2.0780 20.8450 # CM
+2735 211 2 0.0000 32.7120 1.9360 20.7960 # CM
+2736 211 2 0.0000 32.4690 2.3200 20.5870 # CM
+2737 211 2 0.0000 31.9990 2.1910 20.4710 # CM
+2738 211 2 0.0000 31.7610 2.5650 20.2430 # CM
+2739 211 2 0.0000 31.2670 2.5010 20.2800 # CM
+2740 211 2 0.0000 31.0150 2.8530 20.0290 # CM
+2741 211 2 0.0000 30.5240 2.7950 20.1030 # CM
+2742 211 2 0.0000 30.2660 3.2170 20.0290 # CM
+2743 211 3 0.0000 29.7860 3.1020 19.9530 # CT
+2744 212 1 -1.0000 -16.3700 17.0820 -10.2990 # HG
+2745 212 2 0.0000 -16.9280 16.6260 -10.0930 # CM
+2746 212 2 0.0000 -17.0680 16.6950 -9.6180 # CM
+2747 212 2 0.0000 -17.4240 16.3880 -9.4470 # CM
+2748 212 2 0.0000 -17.5580 16.5030 -8.9780 # CM
+2749 212 2 0.0000 -17.8470 16.1280 -8.8160 # CM
+2750 212 2 0.0000 -17.9530 16.1840 -8.3300 # CM
+2751 212 2 0.0000 -18.2240 15.8000 -8.1600 # CM
+2752 212 2 0.0000 -18.4630 15.9330 -7.7410 # CM
+2753 212 2 0.0000 -18.7140 15.5480 -7.5430 # CM
+2754 212 2 0.0000 -18.9750 15.7020 -7.1450 # CM
+2755 212 2 0.0000 -19.3640 15.4080 -7.0420 # CM
+2756 212 3 0.0000 -19.5050 15.4860 -6.5690 # CT
+2757 213 1 -1.0000 6.8310 -17.3410 -4.0340 # HG
+2758 213 2 0.0000 6.3220 -17.0040 -4.4700 # CM
+2759 213 2 0.0000 6.3110 -16.5080 -4.4060 # CM
+2760 213 2 0.0000 5.9650 -16.2600 -4.6680 # CM
+2761 213 2 0.0000 6.0010 -15.7650 -4.6000 # CM
+2762 213 2 0.0000 5.5930 -15.5630 -4.8060 # CM
+2763 213 2 0.0000 5.5680 -15.0730 -4.7070 # CM
+2764 213 2 0.0000 5.1510 -14.8720 -4.8930 # CM
+2765 213 2 0.0000 5.2070 -14.3770 -4.9410 # CM
+2766 213 2 0.0000 4.7850 -14.1580 -5.0970 # CM
+2767 213 2 0.0000 4.8640 -13.6710 -5.1730 # CM
+2768 213 2 0.0000 4.5390 -13.4680 -5.4930 # CM
+2769 213 3 0.0000 4.5370 -12.9730 -5.4310 # CT
+2770 214 1 -1.0000 -19.5540 -14.3630 -20.6300 # HG
+2771 214 2 0.0000 -19.6500 -14.2390 -19.8970 # CM
+2772 214 2 0.0000 -19.5940 -13.7570 -19.7730 # CM
+2773 214 2 0.0000 -19.6310 -13.6490 -19.2870 # CM
+2774 214 2 0.0000 -19.5970 -13.1570 -19.2030 # CM
+2775 214 2 0.0000 -19.5520 -13.0980 -18.7090 # CM
+2776 214 2 0.0000 -19.4600 -12.6200 -18.5950 # CM
+2777 214 2 0.0000 -19.3930 -12.5610 -18.1040 # CM
+2778 214 2 0.0000 -19.4680 -12.0830 -17.9770 # CM
+2779 214 2 0.0000 -19.3740 -12.0040 -17.4920 # CM
+2780 214 2 0.0000 -19.4850 -11.5320 -17.3720 # CM
+2781 214 2 0.0000 -19.5810 -11.4720 -16.8860 # CM
+2782 214 3 0.0000 -19.5320 -10.9880 -16.7690 # CT
+2783 215 1 -1.0000 -31.1770 -10.1080 0.5220 # HG
+2784 215 2 0.0000 -31.8670 -10.3260 0.7180 # CM
+2785 215 2 0.0000 -31.9560 -10.2700 1.2070 # CM
+2786 215 2 0.0000 -32.4010 -10.4290 1.3690 # CM
+2787 215 2 0.0000 -32.4660 -10.3330 1.8560 # CM
+2788 215 2 0.0000 -32.8770 -10.5790 1.9980 # CM
+2789 215 2 0.0000 -32.9400 -10.5500 2.4930 # CM
+2790 215 2 0.0000 -33.3380 -10.8130 2.6400 # CM
+2791 215 2 0.0000 -33.4930 -10.6520 3.0870 # CM
+2792 215 2 0.0000 -33.8740 -10.9270 3.2610 # CM
+2793 215 2 0.0000 -34.0390 -10.7350 3.6910 # CM
+2794 215 2 0.0000 -34.5120 -10.8610 3.7910 # CM
+2795 215 3 0.0000 -34.5980 -10.7960 4.2790 # CT
+2796 216 1 -1.0000 3.7810 26.1000 15.3200 # HG
+2797 216 2 0.0000 3.2060 26.4550 14.9930 # CM
+2798 216 2 0.0000 2.7630 26.2610 15.1190 # CM
+2799 216 2 0.0000 2.3630 26.4640 14.8980 # CM
+2800 216 2 0.0000 1.9370 26.2650 15.0670 # CM
+2801 216 2 0.0000 1.5730 26.4290 14.7670 # CM
+2802 216 2 0.0000 1.1390 26.2040 14.8740 # CM
+2803 216 2 0.0000 0.7780 26.3490 14.5610 # CM
+2804 216 2 0.0000 0.3300 26.2610 14.7650 # CM
+2805 216 2 0.0000 -0.0420 26.3740 14.4490 # CM
+2806 216 2 0.0000 -0.4820 26.3120 14.6770 # CM
+2807 216 2 0.0000 -0.8480 26.5820 14.4690 # CM
+2808 216 3 0.0000 -1.2880 26.3900 14.6040 # CT
+2809 217 1 -1.0000 17.9020 0.2730 5.7030 # HG
+2810 217 2 0.0000 17.6350 0.8840 6.0460 # CM
+2811 217 2 0.0000 17.1350 0.8990 6.0530 # CM
+2812 217 2 0.0000 16.9300 1.3070 6.2560 # CM
+2813 217 2 0.0000 16.4300 1.2750 6.2710 # CM
+2814 217 2 0.0000 16.2620 1.7280 6.3980 # CM
+2815 217 2 0.0000 15.7620 1.7470 6.3680 # CM
+2816 217 2 0.0000 15.5920 2.2040 6.4740 # CM
+2817 217 2 0.0000 15.1100 2.1800 6.6050 # CM
+2818 217 2 0.0000 14.9190 2.6360 6.6840 # CM
+2819 217 2 0.0000 14.4480 2.5960 6.8460 # CM
+2820 217 2 0.0000 14.2960 2.9960 7.1030 # CM
+2821 217 3 0.0000 13.7960 3.0020 7.1140 # CT
+2822 218 1 -1.0000 11.0990 2.5710 -28.3530 # HG
+2823 218 2 0.0000 10.7270 3.2170 -28.2740 # CM
+2824 218 2 0.0000 10.6400 3.3320 -27.7950 # CM
+2825 218 2 0.0000 10.3740 3.7470 -27.7130 # CM
+2826 218 2 0.0000 10.3300 3.8460 -27.2240 # CM
+2827 218 2 0.0000 9.9920 4.2110 -27.1820 # CM
+2828 218 2 0.0000 9.8820 4.2970 -26.7010 # CM
+2829 218 2 0.0000 9.5280 4.6460 -26.6560 # CM
+2830 218 2 0.0000 9.5410 4.8440 -26.1970 # CM
+2831 218 2 0.0000 9.1720 5.1750 -26.1280 # CM
+2832 218 2 0.0000 9.2170 5.3880 -25.6780 # CM
+2833 218 2 0.0000 8.9940 5.8340 -25.6520 # CM
+2834 218 3 0.0000 8.9160 5.9480 -25.1710 # CT
+2835 219 1 -1.0000 10.2610 -17.3220 30.9520 # HG
+2836 219 2 0.0000 10.7340 -17.8180 31.2570 # CM
+2837 219 2 0.0000 10.6520 -18.2850 31.0970 # CM
+2838 219 2 0.0000 10.9380 -18.6410 31.3020 # CM
+2839 219 2 0.0000 10.8490 -19.0900 31.1000 # CM
+2840 219 2 0.0000 11.0860 -19.4250 31.3840 # CM
+2841 219 2 0.0000 10.9720 -19.8910 31.2440 # CM
+2842 219 2 0.0000 11.1910 -20.2280 31.5390 # CM
+2843 219 2 0.0000 11.2150 -20.6700 31.3060 # CM
+2844 219 2 0.0000 11.4050 -21.0250 31.6030 # CM
+2845 219 2 0.0000 11.4530 -21.4520 31.3480 # CM
+2846 219 2 0.0000 11.7970 -21.7570 31.5430 # CM
+2847 219 3 0.0000 11.7160 -22.2210 31.3750 # CT
+2848 220 1 -1.0000 2.3110 8.3990 -27.6970 # HG
+2849 220 2 0.0000 2.3610 8.5970 -28.4190 # CM
+2850 220 2 0.0000 2.8240 8.5500 -28.6000 # CM
+2851 220 2 0.0000 2.8910 8.6980 -29.0730 # CM
+2852 220 2 0.0000 3.3590 8.6110 -29.2290 # CM
+2853 220 2 0.0000 3.4090 8.8460 -29.6680 # CM
+2854 220 2 0.0000 3.8840 8.8270 -29.8260 # CM
+2855 220 2 0.0000 3.9410 9.0790 -30.2540 # CM
+2856 220 2 0.0000 4.3540 8.9240 -30.4880 # CM
+2857 220 2 0.0000 4.4410 9.1890 -30.9040 # CM
+2858 220 2 0.0000 4.8370 9.0030 -31.1450 # CM
+2859 220 2 0.0000 4.8370 9.1140 -31.6320 # CM
+2860 220 3 0.0000 5.3010 9.0580 -31.8100 # CT
+2861 221 1 -1.0000 10.0140 -14.3400 -12.1810 # HG
+2862 221 2 0.0000 10.4620 -13.8600 -11.8190 # CM
+2863 221 2 0.0000 10.9350 -13.8770 -11.9810 # CM
+2864 221 2 0.0000 11.2610 -13.5830 -11.7410 # CM
+2865 221 2 0.0000 11.7160 -13.6050 -11.9480 # CM
+2866 221 2 0.0000 12.0270 -13.3710 -11.6340 # CM
+2867 221 2 0.0000 12.5020 -13.4220 -11.7820 # CM
+2868 221 2 0.0000 12.8160 -13.2070 -11.4590 # CM
+2869 221 2 0.0000 13.2530 -13.1140 -11.6830 # CM
+2870 221 2 0.0000 13.5880 -12.9260 -11.3630 # CM
+2871 221 2 0.0000 14.0080 -12.8070 -11.6060 # CM
+2872 221 2 0.0000 14.2780 -12.4600 -11.3690 # CM
+2873 221 3 0.0000 14.7480 -12.4760 -11.5400 # CT
+2874 222 1 -1.0000 -22.4590 20.8440 -27.9850 # HG
+2875 222 2 0.0000 -22.9590 21.3730 -27.8020 # CM
+2876 222 2 0.0000 -23.4290 21.2040 -27.8070 # CM
+2877 222 2 0.0000 -23.7850 21.5410 -27.7120 # CM
+2878 222 2 0.0000 -24.2400 21.3320 -27.6980 # CM
+2879 222 2 0.0000 -24.5700 21.7070 -27.6860 # CM
+2880 222 2 0.0000 -25.0380 21.5340 -27.7290 # CM
+2881 222 2 0.0000 -25.3680 21.9080 -27.7390 # CM
+2882 222 2 0.0000 -25.8220 21.7380 -27.6150 # CM
+2883 222 2 0.0000 -26.1690 22.0960 -27.6500 # CM
+2884 222 2 0.0000 -26.6100 21.9220 -27.4920 # CM
+2885 222 2 0.0000 -26.9190 22.2840 -27.3400 # CM
+2886 222 3 0.0000 -27.3870 22.1080 -27.3400 # CT
+2887 223 1 -1.0000 -11.7740 0.5370 -24.7740 # HG
+2888 223 2 0.0000 -12.3370 0.1310 -25.0570 # CM
+2889 223 2 0.0000 -12.4440 0.2530 -25.5300 # CM
+2890 223 2 0.0000 -12.8310 0.0130 -25.7360 # CM
+2891 223 2 0.0000 -12.8930 0.1390 -26.2170 # CM
+2892 223 2 0.0000 -13.3320 -0.0510 -26.3600 # CM
+2893 223 2 0.0000 -13.4510 0.1040 -26.8200 # CM
+2894 223 2 0.0000 -13.8990 -0.0670 -26.9580 # CM
+2895 223 2 0.0000 -13.9410 -0.0550 -27.4560 # CM
+2896 223 2 0.0000 -14.3970 -0.1960 -27.6070 # CM
+2897 223 2 0.0000 -14.4140 -0.2110 -28.1060 # CM
+2898 223 2 0.0000 -14.7720 -0.5140 -28.2790 # CM
+2899 223 3 0.0000 -14.8700 -0.3940 -28.7540 # CT
+2900 224 1 -1.0000 23.5750 -33.9400 -12.2410 # HG
+2901 224 2 0.0000 23.3680 -33.3220 -12.6110 # CM
+2902 224 2 0.0000 23.2340 -33.4160 -13.0840 # CM
+2903 224 2 0.0000 23.1120 -33.0180 -13.3610 # CM
+2904 224 2 0.0000 22.9570 -33.1510 -13.8180 # CM
+2905 224 2 0.0000 22.9290 -32.7320 -14.0880 # CM
+2906 224 2 0.0000 22.8300 -32.8350 -14.5680 # CM
+2907 224 2 0.0000 22.8220 -32.4190 -14.8440 # CM
+2908 224 2 0.0000 22.5670 -32.5000 -15.2660 # CM
+2909 224 2 0.0000 22.5770 -32.1000 -15.5670 # CM
+2910 224 2 0.0000 22.2920 -32.1820 -15.9690 # CM
+2911 224 2 0.0000 22.1330 -31.7610 -16.1840 # CM
+2912 224 3 0.0000 21.9930 -31.8610 -16.6530 # CT
+2913 225 1 -1.0000 -8.5260 -28.2030 -32.5530 # HG
+2914 225 2 0.0000 -8.1830 -28.8250 -32.3150 # CM
+2915 225 2 0.0000 -8.2820 -28.9290 -31.8360 # CM
+2916 225 2 0.0000 -8.0470 -29.3260 -31.6440 # CM
+2917 225 2 0.0000 -8.1900 -29.4160 -31.1720 # CM
+2918 225 2 0.0000 -7.8770 -29.7600 -30.9910 # CM
+2919 225 2 0.0000 -7.9570 -29.8320 -30.5020 # CM
+2920 225 2 0.0000 -7.6310 -30.1610 -30.3130 # CM
+2921 225 2 0.0000 -7.8100 -30.3520 -29.8870 # CM
+2922 225 2 0.0000 -7.4810 -30.6600 -29.6710 # CM
+2923 225 2 0.0000 -7.6850 -30.8690 -29.2650 # CM
+2924 225 2 0.0000 -7.4680 -31.3010 -29.1400 # CM
+2925 225 3 0.0000 -7.5750 -31.4040 -28.6630 # CT
+2926 226 1 -1.0000 0.2260 -12.6490 -6.4530 # HG
+2927 226 2 0.0000 0.0180 -11.9460 -6.2950 # CM
+2928 226 2 0.0000 -0.4730 -11.9040 -6.2070 # CM
+2929 226 2 0.0000 -0.6420 -11.4420 -6.1220 # CM
+2930 226 2 0.0000 -1.1300 -11.4410 -6.0110 # CM
+2931 226 2 0.0000 -1.2780 -10.9640 -6.0180 # CM
+2932 226 2 0.0000 -1.7750 -10.9310 -5.9660 # CM
+2933 226 2 0.0000 -1.9280 -10.4570 -5.9930 # CM
+2934 226 2 0.0000 -2.3790 -10.4110 -5.7810 # CM
+2935 226 2 0.0000 -2.5580 -9.9460 -5.8290 # CM
+2936 226 2 0.0000 -2.9920 -9.9050 -5.5840 # CM
+2937 226 2 0.0000 -3.0990 -9.4350 -5.4550 # CM
+2938 226 3 0.0000 -3.5880 -9.4000 -5.3610 # CT
+2939 227 1 -1.0000 -18.5810 -6.8370 18.0380 # HG
+2940 227 2 0.0000 -17.8860 -7.1110 17.9680 # CM
+2941 227 2 0.0000 -17.6790 -7.0020 17.5260 # CM
+2942 227 2 0.0000 -17.2240 -7.1920 17.4430 # CM
+2943 227 2 0.0000 -17.0380 -7.0410 17.0040 # CM
+2944 227 2 0.0000 -16.6280 -7.3150 16.9200 # CM
+2945 227 2 0.0000 -16.4470 -7.2300 16.4620 # CM
+2946 227 2 0.0000 -16.0500 -7.5170 16.3680 # CM
+2947 227 2 0.0000 -15.7810 -7.3190 15.9970 # CM
+2948 227 2 0.0000 -15.3960 -7.6140 15.8710 # CM
+2949 227 2 0.0000 -15.1170 -7.3890 15.5230 # CM
+2950 227 2 0.0000 -14.6460 -7.5580 15.5120 # CM
+2951 227 3 0.0000 -14.4420 -7.4400 15.0720 # CT
+2952 228 1 -1.0000 1.3340 11.8210 16.8540 # HG
+2953 228 2 0.0000 0.6170 11.8430 16.6370 # CM
+2954 228 2 0.0000 0.4700 12.3020 16.5020 # CM
+2955 228 2 0.0000 -0.0110 12.3500 16.3750 # CM
+2956 228 2 0.0000 -0.1160 12.8150 16.2200 # CM
+2957 228 2 0.0000 -0.6130 12.8450 16.1850 # CM
+2958 228 2 0.0000 -0.7560 13.3150 16.0870 # CM
+2959 228 2 0.0000 -1.2530 13.3520 16.0720 # CM
+2960 228 2 0.0000 -1.3860 13.7620 15.8170 # CM
+2961 228 2 0.0000 -1.8820 13.8290 15.8210 # CM
+2962 228 2 0.0000 -2.0020 14.2210 15.5360 # CM
+2963 228 2 0.0000 -2.4730 14.2040 15.3700 # CM
+2964 228 3 0.0000 -2.6120 14.6630 15.2290 # CT
+2965 229 1 -1.0000 31.9080 -17.0320 -15.5440 # HG
+2966 229 2 0.0000 31.2550 -16.9640 -15.9060 # CM
+2967 229 2 0.0000 30.9130 -16.7130 -15.6410 # CM
+2968 229 2 0.0000 30.4600 -16.6720 -15.8490 # CM
+2969 229 2 0.0000 30.1530 -16.3920 -15.5700 # CM
+2970 229 2 0.0000 29.6950 -16.4460 -15.7630 # CM
+2971 229 2 0.0000 29.3530 -16.2230 -15.4740 # CM
+2972 229 2 0.0000 28.8920 -16.2930 -15.6530 # CM
+2973 229 2 0.0000 28.5830 -15.9450 -15.4700 # CM
+2974 229 2 0.0000 28.1110 -16.0210 -15.6170 # CM
+2975 229 2 0.0000 27.8200 -15.6490 -15.4550 # CM
+2976 229 2 0.0000 27.4060 -15.5930 -15.7270 # CM
+2977 229 3 0.0000 27.0700 -15.3350 -15.4620 # CT
+2978 230 1 -1.0000 -10.2210 -9.6640 -19.7440 # HG
+2979 230 2 0.0000 -10.3360 -9.1750 -20.3010 # CM
+2980 230 2 0.0000 -10.4230 -8.7110 -20.1360 # CM
+2981 230 2 0.0000 -10.5250 -8.3690 -20.4860 # CM
+2982 230 2 0.0000 -10.5790 -7.9130 -20.2880 # CM
+2983 230 2 0.0000 -10.7620 -7.6200 -20.6500 # CM
+2984 230 2 0.0000 -10.8820 -7.1690 -20.4700 # CM
+2985 230 2 0.0000 -11.0840 -6.8820 -20.8250 # CM
+2986 230 2 0.0000 -11.0470 -6.4000 -20.6960 # CM
+2987 230 2 0.0000 -11.2740 -6.1020 -21.0290 # CM
+2988 230 2 0.0000 -11.2000 -5.6240 -20.9060 # CM
+2989 230 2 0.0000 -11.2450 -5.3140 -21.2950 # CM
+2990 230 3 0.0000 -11.3240 -4.8510 -21.1250 # CT
+2991 231 1 -1.0000 -16.3660 13.9270 -15.6370 # HG
+2992 231 2 0.0000 -16.7750 13.3300 -15.8350 # CM
+2993 231 2 0.0000 -17.0990 13.4310 -16.2020 # CM
+2994 231 2 0.0000 -17.4010 13.0570 -16.3380 # CM
+2995 231 2 0.0000 -17.6920 13.1850 -16.7240 # CM
+2996 231 2 0.0000 -18.0320 12.8220 -16.7740 # CM
+2997 231 2 0.0000 -18.3750 12.9450 -17.1160 # CM
+2998 231 2 0.0000 -18.7280 12.5940 -17.1530 # CM
+2999 231 2 0.0000 -18.9630 12.6330 -17.5930 # CM
+3000 231 2 0.0000 -19.3400 12.3060 -17.6300 # CM
+3001 231 2 0.0000 -19.5440 12.3340 -18.0850 # CM
+3002 231 2 0.0000 -19.7830 11.9160 -18.2180 # CM
+3003 231 3 0.0000 -20.1000 12.0200 -18.5890 # CT
+3004 232 1 -1.0000 -34.9350 -21.2100 -16.9800 # HG
+3005 232 2 0.0000 -34.6160 -20.5380 -16.8830 # CM
+3006 232 2 0.0000 -34.1790 -20.4960 -17.1230 # CM
+3007 232 2 0.0000 -33.9330 -20.0660 -17.0570 # CM
+3008 232 2 0.0000 -33.5160 -20.0470 -17.3330 # CM
+3009 232 2 0.0000 -33.2590 -19.6480 -17.1770 # CM
+3010 232 2 0.0000 -32.8080 -19.6310 -17.3940 # CM
+3011 232 2 0.0000 -32.5410 -19.2450 -17.2240 # CM
+3012 232 2 0.0000 -32.1770 -19.1340 -17.5480 # CM
+3013 232 2 0.0000 -31.8820 -18.7680 -17.3760 # CM
+3014 232 2 0.0000 -31.5440 -18.6450 -17.7240 # CM
+3015 232 2 0.0000 -31.3670 -18.1810 -17.6660 # CM
+3016 232 3 0.0000 -30.9350 -18.1410 -17.9140 # CT
+3017 233 1 -1.0000 -4.2340 -24.5180 7.6970 # HG
+3018 233 2 0.0000 -4.8200 -24.8140 7.3360 # CM
+3019 233 2 0.0000 -5.1760 -24.4770 7.2370 # CM
+3020 233 2 0.0000 -5.5890 -24.6520 7.0160 # CM
+3021 233 2 0.0000 -5.9110 -24.2840 6.9070 # CM
+3022 233 2 0.0000 -6.3380 -24.5030 6.7700 # CM
+3023 233 2 0.0000 -6.7000 -24.1640 6.7080 # CM
+3024 233 2 0.0000 -7.1340 -24.3820 6.5910 # CM
+3025 233 2 0.0000 -7.4380 -24.0510 6.3720 # CM
+3026 233 2 0.0000 -7.8880 -24.2480 6.2780 # CM
+3027 233 2 0.0000 -8.1690 -23.9180 6.0300 # CM
+3028 233 2 0.0000 -8.5340 -24.1330 5.7660 # CM
+3029 233 3 0.0000 -8.8840 -23.7910 5.6620 # CT
+3030 234 1 -1.0000 9.4450 1.1150 31.6780 # HG
+3031 234 2 0.0000 9.0390 1.6720 31.3830 # CM
+3032 234 2 0.0000 9.3170 1.9970 31.1220 # CM
+3033 234 2 0.0000 9.0750 2.3920 30.9330 # CM
+3034 234 2 0.0000 9.3780 2.6790 30.6580 # CM
+3035 234 2 0.0000 9.1270 3.1000 30.5600 # CM
+3036 234 2 0.0000 9.4210 3.4340 30.3320 # CM
+3037 234 2 0.0000 9.1780 3.8630 30.2530 # CM
+3038 234 2 0.0000 9.4060 4.1230 29.8910 # CM
+3039 234 2 0.0000 9.1910 4.5700 29.8220 # CM
+3040 234 2 0.0000 9.4060 4.8040 29.4370 # CM
+3041 234 2 0.0000 9.1100 5.1480 29.2280 # CM
+3042 234 3 0.0000 9.3910 5.4650 28.9630 # CT
+3043 235 1 -1.0000 16.8730 12.3070 1.0750 # HG
+3044 235 2 0.0000 16.5360 12.4940 0.4310 # CM
+3045 235 2 0.0000 16.6280 12.1680 0.0630 # CM
+3046 235 2 0.0000 16.4350 12.2800 -0.3840 # CM
+3047 235 2 0.0000 16.5240 11.9200 -0.7200 # CM
+3048 235 2 0.0000 16.3930 12.1050 -1.1650 # CM
+3049 235 2 0.0000 16.5210 11.7900 -1.5330 # CM
+3050 235 2 0.0000 16.4110 11.9810 -1.9810 # CM
+3051 235 2 0.0000 16.3820 11.6150 -2.3200 # CM
+3052 235 2 0.0000 16.3020 11.7950 -2.7800 # CM
+3053 235 2 0.0000 16.2430 11.4180 -3.1020 # CM
+3054 235 2 0.0000 15.9860 11.5500 -3.5100 # CM
+3055 235 3 0.0000 16.0760 11.2170 -3.8720 # CT
+3056 236 1 -1.0000 1.6900 26.6890 -0.0050 # HG
+3057 236 2 0.0000 1.9820 26.2750 -0.5580 # CM
+3058 236 2 0.0000 2.0250 26.5280 -0.9870 # CM
+3059 236 2 0.0000 2.1960 26.2690 -1.3790 # CM
+3060 236 2 0.0000 2.2510 26.5600 -1.7830 # CM
+3061 236 2 0.0000 2.3390 26.2550 -2.1680 # CM
+3062 236 2 0.0000 2.3440 26.5090 -2.5990 # CM
+3063 236 2 0.0000 2.4110 26.2030 -2.9880 # CM
+3064 236 2 0.0000 2.5790 26.4620 -3.3810 # CM
+3065 236 2 0.0000 2.6220 26.1730 -3.7880 # CM
+3066 236 2 0.0000 2.8220 26.4360 -4.1630 # CM
+3067 236 2 0.0000 3.0430 26.1480 -4.5050 # CM
+3068 236 3 0.0000 3.0910 26.4080 -4.9300 # CT
+3069 237 1 -1.0000 -15.1710 17.9850 8.4550 # HG
+3070 237 2 0.0000 -15.2860 17.6480 9.1140 # CM
+3071 237 2 0.0000 -15.7430 17.4480 9.1520 # CM
+3072 237 2 0.0000 -15.8540 17.2360 9.5910 # CM
+3073 237 2 0.0000 -16.3070 17.0230 9.5840 # CM
+3074 237 2 0.0000 -16.4160 16.9010 10.0560 # CM
+3075 237 2 0.0000 -16.8870 16.7360 10.0940 # CM
+3076 237 2 0.0000 -17.0050 16.6320 10.5680 # CM
+3077 237 2 0.0000 -17.3960 16.3220 10.5820 # CM
+3078 237 2 0.0000 -17.5440 16.2340 11.0520 # CM
+3079 237 2 0.0000 -17.9130 15.8970 11.0540 # CM
+3080 237 2 0.0000 -17.9540 15.6560 11.4890 # CM
+3081 237 3 0.0000 -18.4090 15.4510 11.5190 # CT
+3082 238 1 -1.0000 23.2080 -26.1870 -34.1870 # HG
+3083 238 2 0.0000 23.4170 -26.6310 -33.6200 # CM
+3084 238 2 0.0000 23.8410 -26.4780 -33.4020 # CM
+3085 238 2 0.0000 24.0150 -26.7690 -33.0340 # CM
+3086 238 2 0.0000 24.4240 -26.5730 -32.8210 # CM
+3087 238 2 0.0000 24.6140 -26.9270 -32.5240 # CM
+3088 238 2 0.0000 25.0560 -26.7830 -32.3380 # CM
+3089 238 2 0.0000 25.2590 -27.1430 -32.0570 # CM
+3090 238 2 0.0000 25.5990 -26.9470 -31.7480 # CM
+3091 238 2 0.0000 25.8330 -27.3010 -31.4830 # CM
+3092 238 2 0.0000 26.1450 -27.0890 -31.1550 # CM
+3093 238 2 0.0000 26.2470 -27.3830 -30.7650 # CM
+3094 238 3 0.0000 26.6660 -27.2230 -30.5450 # CT
+3095 239 1 -1.0000 29.3790 1.3730 29.6680 # HG
+3096 239 2 0.0000 29.4060 0.6440 29.8420 # CM
+3097 239 2 0.0000 29.7760 0.4030 29.6070 # CM
+3098 239 2 0.0000 29.8030 -0.0900 29.6870 # CM
+3099 239 2 0.0000 30.2000 -0.2930 29.4590 # CM
+3100 239 2 0.0000 30.1450 -0.7880 29.4900 # CM
+3101 239 2 0.0000 30.4970 -1.0230 29.2230 # CM
+3102 239 2 0.0000 30.4320 -1.5180 29.2340 # CM
+3103 239 2 0.0000 30.8590 -1.7490 29.1170 # CM
+3104 239 2 0.0000 30.8010 -2.2460 29.0940 # CM
+3105 239 2 0.0000 31.2410 -2.4650 29.0090 # CM
+3106 239 2 0.0000 31.2550 -2.9400 29.1620 # CM
+3107 239 3 0.0000 31.6310 -3.1740 28.9310 # CT
+3108 240 1 -1.0000 -22.4800 -23.3140 -10.7740 # HG
+3109 240 2 0.0000 -22.0460 -23.9000 -10.5990 # CM
+3110 240 2 0.0000 -21.5670 -23.7730 -10.5330 # CM
+3111 240 2 0.0000 -21.2510 -24.1490 -10.4380 # CM
+3112 240 2 0.0000 -20.7870 -23.9820 -10.3520 # CM
+3113 240 2 0.0000 -20.4900 -24.3840 -10.3460 # CM
+3114 240 2 0.0000 -20.0090 -24.2490 -10.3180 # CM
+3115 240 2 0.0000 -19.7080 -24.6470 -10.3330 # CM
+3116 240 2 0.0000 -19.2610 -24.5310 -10.1420 # CM
+3117 240 2 0.0000 -18.9400 -24.9120 -10.1790 # CM
+3118 240 2 0.0000 -18.5090 -24.7940 -9.9550 # CM
+3119 240 2 0.0000 -18.2480 -25.1950 -9.8120 # CM
+3120 240 3 0.0000 -17.7710 -25.0620 -9.7410 # CT
+3121 241 1 -1.0000 -3.8330 20.9300 19.7710 # HG
+3122 241 2 0.0000 -4.2300 21.5620 19.7000 # CM
+3123 241 2 0.0000 -3.9410 21.9660 19.6420 # CM
+3124 241 2 0.0000 -4.1790 22.4050 19.6150 # CM
+3125 241 2 0.0000 -3.8620 22.7830 19.5290 # CM
+3126 241 2 0.0000 -4.1210 23.2050 19.5940 # CM
+3127 241 2 0.0000 -3.8200 23.6040 19.5710 # CM
+3128 241 2 0.0000 -4.0730 24.0260 19.6560 # CM
+3129 241 2 0.0000 -3.8200 24.4160 19.4720 # CM
+3130 241 2 0.0000 -4.0470 24.8490 19.5780 # CM
+3131 241 2 0.0000 -3.8020 25.2270 19.3610 # CM
+3132 241 2 0.0000 -4.0900 25.6290 19.2890 # CM
+3133 241 3 0.0000 -3.7970 26.0280 19.2230 # CT
+3134 242 1 -1.0000 -1.2390 -16.3060 -10.6790 # HG
+3135 242 2 0.0000 -1.8750 -16.6710 -10.5180 # CM
+3136 242 2 0.0000 -1.9990 -16.6390 -10.0350 # CM
+3137 242 2 0.0000 -2.4070 -16.8920 -9.8960 # CM
+3138 242 2 0.0000 -2.5160 -16.8160 -9.4130 # CM
+3139 242 2 0.0000 -2.8710 -17.1460 -9.2930 # CM
+3140 242 2 0.0000 -2.9650 -17.1360 -8.8010 # CM
+3141 242 2 0.0000 -3.3040 -17.4790 -8.6750 # CM
+3142 242 2 0.0000 -3.5130 -17.3590 -8.2360 # CM
+3143 242 2 0.0000 -3.8330 -17.7120 -8.0820 # CM
+3144 242 2 0.0000 -4.0580 -17.5640 -7.6620 # CM
+3145 242 2 0.0000 -4.4970 -17.7900 -7.5870 # CM
+3146 242 3 0.0000 -4.6210 -17.7490 -7.1040 # CT
+3147 243 1 -1.0000 -19.2710 -4.7360 18.2890 # HG
+3148 243 2 0.0000 -18.5650 -4.4930 18.3540 # CM
+3149 243 2 0.0000 -18.3890 -4.5320 18.8210 # CM
+3150 243 2 0.0000 -17.9280 -4.3560 18.8980 # CM
+3151 243 2 0.0000 -17.7750 -4.4360 19.3680 # CM
+3152 243 2 0.0000 -17.3530 -4.1750 19.4280 # CM
+3153 243 2 0.0000 -17.2030 -4.1870 19.9050 # CM
+3154 243 2 0.0000 -16.7930 -3.9100 19.9720 # CM
+3155 243 2 0.0000 -16.5570 -4.0520 20.3890 # CM
+3156 243 2 0.0000 -16.1610 -3.7620 20.4840 # CM
+3157 243 2 0.0000 -15.9150 -3.9360 20.8840 # CM
+3158 243 2 0.0000 -15.4360 -3.7950 20.8940 # CM
+3159 243 3 0.0000 -15.2640 -3.8420 21.3610 # CT
+3160 244 1 -1.0000 21.7800 -30.1590 16.9410 # HG
+3161 244 2 0.0000 22.3990 -29.7360 16.9540 # CM
+3162 244 2 0.0000 22.8110 -30.0000 17.0550 # CM
+3163 244 2 0.0000 23.2360 -29.7390 17.0920 # CM
+3164 244 2 0.0000 23.6310 -30.0380 17.1660 # CM
+3165 244 2 0.0000 24.0160 -29.7410 17.2820 # CM
+3166 244 2 0.0000 24.4140 -30.0110 17.4180 # CM
+3167 244 2 0.0000 24.7940 -29.7160 17.5550 # CM
+3168 244 2 0.0000 25.2240 -29.9690 17.5270 # CM
+3169 244 2 0.0000 25.6090 -29.6940 17.6910 # CM
+3170 244 2 0.0000 26.0360 -29.9460 17.6260 # CM
+3171 244 2 0.0000 26.4360 -29.6480 17.6020 # CM
+3172 244 3 0.0000 26.8460 -29.9170 17.6960 # CT
+3173 245 1 -1.0000 22.5200 25.8130 -14.2650 # HG
+3174 245 2 0.0000 21.7750 25.8700 -14.3310 # CM
+3175 245 2 0.0000 21.5960 26.2960 -14.1400 # CM
+3176 245 2 0.0000 21.1000 26.3500 -14.1510 # CM
+3177 245 2 0.0000 20.9590 26.7980 -13.9770 # CM
+3178 245 2 0.0000 20.4620 26.7810 -13.9230 # CM
+3179 245 2 0.0000 20.2930 27.1940 -13.6980 # CM
+3180 245 2 0.0000 19.8000 27.1710 -13.6240 # CM
+3181 245 2 0.0000 19.6160 27.6310 -13.5590 # CM
+3182 245 2 0.0000 19.1260 27.6200 -13.4530 # CM
+3183 245 2 0.0000 18.9490 28.0860 -13.4230 # CM
+3184 245 2 0.0000 18.4570 28.1120 -13.5050 # CM
+3185 245 3 0.0000 18.2840 28.5430 -13.3190 # CT
+3186 246 1 -1.0000 -15.5700 28.2580 -11.0360 # HG
+3187 246 2 0.0000 -15.5870 27.5090 -11.0400 # CM
+3188 246 2 0.0000 -15.1640 27.3070 -11.2140 # CM
+3189 246 2 0.0000 -15.1560 26.8080 -11.2490 # CM
+3190 246 2 0.0000 -14.7090 26.6400 -11.4010 # CM
+3191 246 2 0.0000 -14.7670 26.1550 -11.5050 # CM
+3192 246 2 0.0000 -14.3520 25.9670 -11.7130 # CM
+3193 246 2 0.0000 -14.4140 25.4880 -11.8370 # CM
+3194 246 2 0.0000 -13.9690 25.2650 -11.8840 # CM
+3195 246 2 0.0000 -14.0150 24.7910 -12.0390 # CM
+3196 246 2 0.0000 -13.5660 24.5720 -12.0490 # CM
+3197 246 2 0.0000 -13.5920 24.0740 -12.0160 # CM
+3198 246 3 0.0000 -13.1640 23.8780 -12.1840 # CT
+3199 247 1 -1.0000 -0.0150 16.5220 18.6220 # HG
+3200 247 2 0.0000 0.3190 15.9810 18.2250 # CM
+3201 247 2 0.0000 0.3930 16.1090 17.7470 # CM
+3202 247 2 0.0000 0.5940 15.7580 17.4530 # CM
+3203 247 2 0.0000 0.6770 15.9300 16.9910 # CM
+3204 247 2 0.0000 0.7950 15.5340 16.7100 # CM
+3205 247 2 0.0000 0.8310 15.6620 16.2280 # CM
+3206 247 2 0.0000 0.9280 15.2640 15.9420 # CM
+3207 247 2 0.0000 1.1230 15.4100 15.5060 # CM
+3208 247 2 0.0000 1.1970 15.0230 15.1980 # CM
+3209 247 2 0.0000 1.4230 15.1790 14.7800 # CM
+3210 247 2 0.0000 1.6710 14.8150 14.5450 # CM
+3211 247 3 0.0000 1.7480 14.9510 14.0710 # CT
+3212 248 1 -1.0000 -27.8870 7.5890 -13.5930 # HG
+3213 248 2 0.0000 -27.4250 7.0090 -13.4760 # CM
+3214 248 2 0.0000 -27.5960 6.5830 -13.6750 # CM
+3215 248 2 0.0000 -27.3190 6.1760 -13.5930 # CM
+3216 248 2 0.0000 -27.5040 5.7750 -13.8290 # CM
+3217 248 2 0.0000 -27.2540 5.3780 -13.6560 # CM
+3218 248 2 0.0000 -27.4530 4.9530 -13.8300 # CM
+3219 248 2 0.0000 -27.2190 4.5540 -13.6420 # CM
+3220 248 2 0.0000 -27.3000 4.1560 -13.9330 # CM
+3221 248 2 0.0000 -27.0960 3.7420 -13.7390 # CM
+3222 248 2 0.0000 -27.1570 3.3600 -14.0550 # CM
+3223 248 2 0.0000 -26.8200 2.9970 -13.9880 # CM
+3224 248 3 0.0000 -26.9910 2.5760 -14.1960 # CT
+3225 249 1 -1.0000 -21.3410 -30.2520 29.1910 # HG
+3226 249 2 0.0000 -21.7790 -30.8440 29.0470 # CM
+3227 249 2 0.0000 -22.2160 -30.7150 28.8400 # CM
+3228 249 2 0.0000 -22.5370 -31.0880 28.7540 # CM
+3229 249 2 0.0000 -22.9510 -30.9260 28.5230 # CM
+3230 249 2 0.0000 -23.2770 -31.3050 28.5320 # CM
+3231 249 2 0.0000 -23.7230 -31.1590 28.3590 # CM
+3232 249 2 0.0000 -24.0570 -31.5290 28.3860 # CM
+3233 249 2 0.0000 -24.4350 -31.4420 28.0710 # CM
+3234 249 2 0.0000 -24.7930 -31.7900 28.1110 # CM
+3235 249 2 0.0000 -25.1470 -31.7090 27.7680 # CM
+3236 249 2 0.0000 -25.4070 -32.1210 27.6560 # CM
+3237 249 3 0.0000 -25.8390 -31.9870 27.4430 # CT
+3238 250 1 -1.0000 28.3560 28.8400 7.9130 # HG
+3239 250 2 0.0000 28.8600 28.3370 8.1480 # CM
+3240 250 2 0.0000 28.8760 28.2970 8.6460 # CM
+3241 250 2 0.0000 29.2190 27.9850 8.8320 # CM
+3242 250 2 0.0000 29.1880 27.9500 9.3300 # CM
+3243 250 2 0.0000 29.5940 27.7020 9.4820 # CM
+3244 250 2 0.0000 29.6240 27.6980 9.9810 # CM
+3245 250 2 0.0000 30.0400 27.4680 10.1360 # CM
+3246 250 2 0.0000 29.9870 27.3210 10.6100 # CM
+3247 250 2 0.0000 30.4080 27.1160 10.7880 # CM
+3248 250 2 0.0000 30.3310 26.9440 11.2500 # CM
+3249 250 2 0.0000 30.6520 26.5840 11.3790 # CM
+3250 250 3 0.0000 30.6590 26.5430 11.8770 # CT
+3251 251 1 -1.0000 25.5170 9.1230 18.1170 # HG
+3252 251 2 0.0000 25.2390 9.7900 18.3180 # CM
+3253 251 2 0.0000 24.8030 9.7530 18.5610 # CM
+3254 251 2 0.0000 24.5830 10.1840 18.6870 # CM
+3255 251 2 0.0000 24.1650 10.1080 18.9510 # CM
+3256 251 2 0.0000 23.9340 10.5500 18.9820 # CM
+3257 251 2 0.0000 23.4830 10.5000 19.1930 # CM
+3258 251 2 0.0000 23.2410 10.9360 19.2060 # CM
+3259 251 2 0.0000 22.8810 10.9210 19.5530 # CM
+3260 251 2 0.0000 22.6100 11.3420 19.5560 # CM
+3261 251 2 0.0000 22.2760 11.3260 19.9280 # CM
+3262 251 2 0.0000 22.1270 11.7800 20.0750 # CM
+3263 251 3 0.0000 21.6960 11.7360 20.3230 # CT
+3264 252 1 -1.0000 26.3000 -26.2300 12.9160 # HG
+3265 252 2 0.0000 26.3140 -26.4230 12.1920 # CM
+3266 252 2 0.0000 25.8730 -26.3560 11.9650 # CM
+3267 252 2 0.0000 25.8470 -26.4980 11.4870 # CM
+3268 252 2 0.0000 25.4020 -26.3920 11.2850 # CM
+3269 252 2 0.0000 25.3860 -26.6220 10.8420 # CM
+3270 252 2 0.0000 24.9310 -26.5830 10.6380 # CM
+3271 252 2 0.0000 24.9060 -26.8310 10.2050 # CM
+3272 252 2 0.0000 24.5250 -26.6570 9.9310 # CM
+3273 252 2 0.0000 24.4700 -26.9180 9.5070 # CM
+3274 252 2 0.0000 24.1080 -26.7140 9.2290 # CM
+3275 252 2 0.0000 24.1510 -26.8230 8.7440 # CM
+3276 252 3 0.0000 23.7110 -26.7470 8.5200 # CT
+3277 253 1 -1.0000 15.0410 -3.2190 14.9730 # HG
+3278 253 2 0.0000 14.3210 -3.3980 14.8670 # CM
+3279 253 2 0.0000 14.0200 -2.9980 14.8760 # CM
+3280 253 2 0.0000 13.5300 -3.0910 14.8300 # CM
+3281 253 2 0.0000 13.2630 -2.6680 14.8160 # CM
+3282 253 2 0.0000 12.7830 -2.8010 14.8570 # CM
+3283 253 2 0.0000 12.4900 -2.3970 14.9020 # CM
+3284 253 2 0.0000 12.0120 -2.5280 14.9640 # CM
+3285 253 2 0.0000 11.7140 -2.1450 14.8430 # CM
+3286 253 2 0.0000 11.2330 -2.2510 14.9300 # CM
+3287 253 2 0.0000 10.9450 -1.8740 14.7740 # CM
+3288 253 2 0.0000 10.4760 -2.0160 14.6740 # CM
+3289 253 3 0.0000 10.1810 -1.6130 14.6760 # CT
+3290 254 1 -1.0000 -0.9950 34.3380 -12.5560 # HG
+3291 254 2 0.0000 -0.6170 33.8980 -13.0310 # CM
+3292 254 2 0.0000 -0.4600 34.1430 -13.4380 # CM
+3293 254 2 0.0000 -0.2250 33.8690 -13.7830 # CM
+3294 254 2 0.0000 -0.0590 34.1510 -14.1620 # CM
+3295 254 2 0.0000 0.0910 33.8360 -14.5200 # CM
+3296 254 2 0.0000 0.2110 34.0850 -14.9370 # CM
+3297 254 2 0.0000 0.3410 33.7720 -15.3030 # CM
+3298 254 2 0.0000 0.6120 34.0140 -15.6470 # CM
+3299 254 2 0.0000 0.7230 33.7180 -16.0360 # CM
+3300 254 2 0.0000 1.0210 33.9620 -16.3540 # CM
+3301 254 2 0.0000 1.2930 33.6560 -16.6400 # CM
+3302 254 3 0.0000 1.4530 33.9070 -17.0410 # CT
+3303 255 1 -1.0000 -14.3960 28.9790 10.4630 # HG
+3304 255 2 0.0000 -14.9050 29.4970 10.6490 # CM
+3305 255 2 0.0000 -15.3620 29.3040 10.7150 # CM
+3306 255 2 0.0000 -15.7260 29.6310 10.8180 # CM
+3307 255 2 0.0000 -16.1620 29.4010 10.9040 # CM
+3308 255 2 0.0000 -16.5120 29.7570 10.9160 # CM
+3309 255 2 0.0000 -16.9690 29.5570 10.9450 # CM
+3310 255 2 0.0000 -17.3220 29.9100 10.9370 # CM
+3311 255 2 0.0000 -17.7480 29.7300 11.1280 # CM
+3312 255 2 0.0000 -18.1190 30.0640 11.0980 # CM
+3313 255 2 0.0000 -18.5280 29.8850 11.3220 # CM
+3314 255 2 0.0000 -18.8410 30.2440 11.4720 # CM
+3315 255 3 0.0000 -19.2940 30.0450 11.5440 # CT
+3316 256 1 -1.0000 -8.7920 18.3620 -2.1040 # HG
+3317 256 2 0.0000 -8.9910 18.1600 -2.7990 # CM
+3318 256 2 0.0000 -9.2370 18.5220 -3.0420 # CM
+3319 256 2 0.0000 -9.4020 18.4060 -3.4990 # CM
+3320 256 2 0.0000 -9.6180 18.7990 -3.7220 # CM
+3321 256 2 0.0000 -9.8420 18.6240 -4.1340 # CM
+3322 256 2 0.0000 -10.1160 18.9810 -4.3520 # CM
+3323 256 2 0.0000 -10.3580 18.8040 -4.7520 # CM
+3324 256 2 0.0000 -10.4880 19.1800 -5.0530 # CM
+3325 256 2 0.0000 -10.7580 19.0200 -5.4430 # CM
+3326 256 2 0.0000 -10.8520 19.4010 -5.7520 # CM
+3327 256 2 0.0000 -10.9480 19.2520 -6.2190 # CM
+3328 256 3 0.0000 -11.1870 19.6190 -6.4600 # CT
+3329 257 1 -1.0000 28.1180 -9.8870 34.6340 # HG
+3330 257 2 0.0000 28.1020 -9.2650 34.2140 # CM
+3331 257 2 0.0000 28.5460 -9.0370 34.1900 # CM
+3332 257 2 0.0000 28.5590 -8.6080 33.9350 # CM
+3333 257 2 0.0000 29.0230 -8.4220 33.9080 # CM
+3334 257 2 0.0000 28.9830 -7.9590 33.7250 # CM
+3335 257 2 0.0000 29.4240 -7.7230 33.7370 # CM
+3336 257 2 0.0000 29.3820 -7.2540 33.5740 # CM
+3337 257 2 0.0000 29.8290 -7.0820 33.4320 # CM
+3338 257 2 0.0000 29.8070 -6.6010 33.2940 # CM
+3339 257 2 0.0000 30.2520 -6.4520 33.1240 # CM
+3340 257 2 0.0000 30.2220 -6.0590 32.8170 # CM
+3341 257 3 0.0000 30.6690 -5.8390 32.7900 # CT
+3342 258 1 -1.0000 -23.0780 -29.2690 -30.2270 # HG
+3343 258 2 0.0000 -23.1930 -29.9620 -30.4900 # CM
+3344 258 2 0.0000 -23.6280 -30.1570 -30.3370 # CM
+3345 258 2 0.0000 -23.7200 -30.6270 -30.4790 # CM
+3346 258 2 0.0000 -24.1740 -30.7790 -30.3320 # CM
+3347 258 2 0.0000 -24.1940 -31.2720 -30.4150 # CM
+3348 258 2 0.0000 -24.6140 -31.4670 -30.2270 # CM
+3349 258 2 0.0000 -24.6270 -31.9620 -30.2900 # CM
+3350 258 2 0.0000 -25.0990 -32.1260 -30.2580 # CM
+3351 258 2 0.0000 -25.1230 -32.6250 -30.2900 # CM
+3352 258 2 0.0000 -25.6010 -32.7710 -30.2900 # CM
+3353 258 2 0.0000 -25.6660 -33.2200 -30.5000 # CM
+3354 258 3 0.0000 -26.1050 -33.4070 -30.3510 # CT
+3355 259 1 -1.0000 -3.5190 -4.9870 16.3050 # HG
+3356 259 2 0.0000 -3.6670 -5.7190 16.3610 # CM
+3357 259 2 0.0000 -3.2540 -6.0010 16.3590 # CM
+3358 259 2 0.0000 -3.3240 -6.4960 16.3720 # CM
+3359 259 2 0.0000 -2.8900 -6.7440 16.3950 # CM
+3360 259 2 0.0000 -2.9970 -7.2260 16.3210 # CM
+3361 259 2 0.0000 -2.5780 -7.4970 16.2820 # CM
+3362 259 2 0.0000 -2.6810 -7.9760 16.1870 # CM
+3363 259 2 0.0000 -2.2910 -8.2630 16.3120 # CM
+3364 259 2 0.0000 -2.3690 -8.7430 16.1930 # CM
+3365 259 2 0.0000 -1.9870 -9.0220 16.3540 # CM
+3366 259 2 0.0000 -2.1110 -9.5010 16.4200 # CM
+3367 259 3 0.0000 -1.6940 -9.7770 16.4240 # CT
+3368 260 1 -1.0000 -8.1880 11.3520 4.4550 # HG
+3369 260 2 0.0000 -8.4520 11.9840 4.7590 # CM
+3370 260 2 0.0000 -8.8860 11.9170 4.9990 # CM
+3371 260 2 0.0000 -9.0960 12.3270 5.1930 # CM
+3372 260 2 0.0000 -9.5130 12.2180 5.4480 # CM
+3373 260 2 0.0000 -9.7360 12.6530 5.5500 # CM
+3374 260 2 0.0000 -10.1850 12.5790 5.7570 # CM
+3375 260 2 0.0000 -10.4200 13.0120 5.8410 # CM
+3376 260 2 0.0000 -10.7760 12.9490 6.1860 # CM
+3377 260 2 0.0000 -11.0390 13.3680 6.2570 # CM
+3378 260 2 0.0000 -11.3680 13.3010 6.6270 # CM
+3379 260 2 0.0000 -11.5080 13.7290 6.8430 # CM
+3380 260 3 0.0000 -11.9370 13.6550 7.0880 # CT
+3381 261 1 -1.0000 23.1320 1.5230 -7.9550 # HG
+3382 261 2 0.0000 22.7220 2.1260 -7.7790 # CM
+3383 261 2 0.0000 22.9920 2.4860 -7.5610 # CM
+3384 261 2 0.0000 22.7390 2.8910 -7.4120 # CM
+3385 261 2 0.0000 23.0440 3.2410 -7.2240 # CM
+3386 261 2 0.0000 22.7520 3.5860 -7.0120 # CM
+3387 261 2 0.0000 23.0260 3.9230 -6.7640 # CM
+3388 261 2 0.0000 22.7360 4.2570 -6.5330 # CM
+3389 261 2 0.0000 22.9990 4.6710 -6.4350 # CM
+3390 261 2 0.0000 22.7280 5.0030 -6.1750 # CM
+3391 261 2 0.0000 22.9910 5.4240 -6.1130 # CM
+3392 261 2 0.0000 22.7020 5.8230 -6.0310 # CM
+3393 261 3 0.0000 22.9780 6.1830 -5.8210 # CT
+3394 262 1 -1.0000 -34.4480 -6.8140 3.9210 # HG
+3395 262 2 0.0000 -33.7160 -6.7580 4.0740 # CM
+3396 262 2 0.0000 -33.4640 -6.5080 3.7210 # CM
+3397 262 2 0.0000 -32.9690 -6.4750 3.7860 # CM
+3398 262 2 0.0000 -32.7540 -6.1960 3.4300 # CM
+3399 262 2 0.0000 -32.2610 -6.2580 3.4790 # CM
+3400 262 2 0.0000 -32.0160 -6.0370 3.1030 # CM
+3401 262 2 0.0000 -31.5240 -6.1140 3.1370 # CM
+3402 262 2 0.0000 -31.2780 -5.7680 2.8730 # CM
+3403 262 2 0.0000 -30.7850 -5.8520 2.8740 # CM
+3404 262 2 0.0000 -30.5490 -5.4820 2.6350 # CM
+3405 262 2 0.0000 -30.0710 -5.4340 2.7730 # CM
+3406 262 3 0.0000 -29.8260 -5.1780 2.4210 # CT
+3407 263 1 -1.0000 23.2270 -14.9470 -9.5440 # HG
+3408 263 2 0.0000 22.5060 -15.1000 -9.4040 # CM
+3409 263 2 0.0000 22.4260 -15.5860 -9.3140 # CM
+3410 263 2 0.0000 21.9500 -15.7200 -9.2390 # CM
+3411 263 2 0.0000 21.9110 -16.2060 -9.1260 # CM
+3412 263 2 0.0000 21.4240 -16.3180 -9.1440 # CM
+3413 263 2 0.0000 21.3530 -16.8100 -9.0900 # CM
+3414 263 2 0.0000 20.8700 -16.9280 -9.1280 # CM
+3415 263 2 0.0000 20.7850 -17.3720 -8.9150 # CM
+3416 263 2 0.0000 20.3090 -17.5170 -8.9730 # CM
+3417 263 2 0.0000 20.2300 -17.9440 -8.7270 # CM
+3418 263 2 0.0000 19.7500 -18.0150 -8.6090 # CM
+3419 263 3 0.0000 19.6770 -18.5000 -8.5130 # CT
+3420 264 1 -1.0000 5.1070 18.4120 -33.2060 # HG
+3421 264 2 0.0000 4.6670 17.9520 -32.8090 # CM
+3422 264 2 0.0000 4.8890 17.5160 -32.7040 # CM
+3423 264 2 0.0000 4.6100 17.1810 -32.4590 # CM
+3424 264 2 0.0000 4.8710 16.7690 -32.3480 # CM
+3425 264 2 0.0000 4.5420 16.4310 -32.1840 # CM
+3426 264 2 0.0000 4.7630 15.9870 -32.1160 # CM
+3427 264 2 0.0000 4.4320 15.6410 -31.9730 # CM
+3428 264 2 0.0000 4.6680 15.2610 -31.7510 # CM
+3429 264 2 0.0000 4.3510 14.8930 -31.6290 # CM
+3430 264 2 0.0000 4.5950 14.5350 -31.3790 # CM
+3431 264 2 0.0000 4.2930 14.2590 -31.0920 # CM
+3432 264 3 0.0000 4.5220 13.8290 -30.9830 # CT
+3433 265 1 -1.0000 19.2780 22.4700 5.8230 # HG
+3434 265 2 0.0000 18.6800 22.7580 6.1720 # CM
+3435 265 2 0.0000 18.3610 22.4080 6.3310 # CM
+3436 265 2 0.0000 17.9420 22.5730 6.5480 # CM
+3437 265 2 0.0000 17.6610 22.1960 6.7180 # CM
+3438 265 2 0.0000 17.2200 22.3930 6.8470 # CM
+3439 265 2 0.0000 16.8930 22.0350 6.9690 # CM
+3440 265 2 0.0000 16.4460 22.2280 7.0780 # CM
+3441 265 2 0.0000 16.1830 21.9030 7.3530 # CM
+3442 265 2 0.0000 15.7200 22.0710 7.4430 # CM
+3443 265 2 0.0000 15.4800 21.7530 7.7450 # CM
+3444 265 2 0.0000 15.1070 21.9690 7.9970 # CM
+3445 265 3 0.0000 14.7950 21.6140 8.1600 # CT
+3446 266 1 -1.0000 4.4870 7.8190 30.1150 # HG
+3447 266 2 0.0000 3.9050 7.8800 30.5850 # CM
+3448 266 2 0.0000 3.9540 8.2620 30.9040 # CM
+3449 266 2 0.0000 3.5910 8.3120 31.2440 # CM
+3450 266 2 0.0000 3.6580 8.7190 31.5280 # CM
+3451 266 2 0.0000 3.3300 8.6880 31.9030 # CM
+3452 266 2 0.0000 3.4080 9.0520 32.2380 # CM
+3453 266 2 0.0000 3.0950 9.0110 32.6250 # CM
+3454 266 2 0.0000 3.0590 9.4490 32.8620 # CM
+3455 266 2 0.0000 2.7720 9.4140 33.2710 # CM
+3456 266 2 0.0000 2.7170 9.8660 33.4790 # CM
+3457 266 2 0.0000 2.3070 9.9010 33.7610 # CM
+3458 266 3 0.0000 2.3570 10.2890 34.0720 # CT
+3459 267 1 -1.0000 2.9130 -34.7210 -30.2130 # HG
+3460 267 2 0.0000 2.9030 -34.2170 -29.6580 # CM
+3461 267 2 0.0000 2.4510 -34.0140 -29.5900 # CM
+3462 267 2 0.0000 2.4210 -33.6580 -29.2400 # CM
+3463 267 2 0.0000 1.9500 -33.4970 -29.1800 # CM
+3464 267 2 0.0000 1.9740 -33.0900 -28.8910 # CM
+3465 267 2 0.0000 1.5260 -32.8710 -28.8570 # CM
+3466 267 2 0.0000 1.5500 -32.4520 -28.5860 # CM
+3467 267 2 0.0000 1.0960 -32.3310 -28.4170 # CM
+3468 267 2 0.0000 1.1000 -31.8960 -28.1690 # CM
+3469 267 2 0.0000 0.6480 -31.8050 -27.9770 # CM
+3470 267 2 0.0000 0.6620 -31.4950 -27.5860 # CM
+3471 267 3 0.0000 0.2070 -31.3010 -27.5170 # CT
+3472 268 1 -1.0000 -10.2040 17.0410 3.4310 # HG
+3473 268 2 0.0000 -10.8540 17.1840 3.7770 # CM
+3474 268 2 0.0000 -11.1600 16.7890 3.7830 # CM
+3475 268 2 0.0000 -11.6100 16.8630 3.9880 # CM
+3476 268 2 0.0000 -11.8790 16.4420 4.0010 # CM
+3477 268 2 0.0000 -12.3440 16.5720 4.1300 # CM
+3478 268 2 0.0000 -12.6540 16.1800 4.0990 # CM
+3479 268 2 0.0000 -13.1230 16.3130 4.2070 # CM
+3480 268 2 0.0000 -13.3880 15.9090 4.3370 # CM
+3481 268 2 0.0000 -13.8690 16.0230 4.4180 # CM
+3482 268 2 0.0000 -14.1140 15.6180 4.5790 # CM
+3483 268 2 0.0000 -14.5260 15.7310 4.8380 # CM
+3484 268 3 0.0000 -14.8260 15.3310 4.8480 # CT
+3485 269 1 -1.0000 -15.0240 -6.5180 29.2630 # HG
+3486 269 2 0.0000 -14.5960 -6.0570 29.6710 # CM
+3487 269 2 0.0000 -14.4630 -6.2560 30.1100 # CM
+3488 269 2 0.0000 -14.1950 -5.9610 30.4130 # CM
+3489 269 2 0.0000 -14.0570 -6.2010 30.8300 # CM
+3490 269 2 0.0000 -13.8700 -5.8560 31.1390 # CM
+3491 269 2 0.0000 -13.7740 -6.0530 31.5880 # CM
+3492 269 2 0.0000 -13.6070 -5.7050 31.9050 # CM
+3493 269 2 0.0000 -13.3600 -5.9230 32.2820 # CM
+3494 269 2 0.0000 -13.2140 -5.5880 32.6240 # CM
+3495 269 2 0.0000 -12.9410 -5.8130 32.9770 # CM
+3496 269 2 0.0000 -12.6350 -5.5000 33.2160 # CM
+3497 269 3 0.0000 -12.4990 -5.7060 33.6510 # CT
+3498 270 1 -1.0000 29.9410 30.8550 23.7690 # HG
+3499 270 2 0.0000 29.3410 30.6980 24.1920 # CM
+3500 270 2 0.0000 28.9190 30.6700 23.9250 # CM
+3501 270 2 0.0000 28.5000 30.5890 24.1850 # CM
+3502 270 2 0.0000 28.1030 30.5400 23.8840 # CM
+3503 270 2 0.0000 27.6990 30.5470 24.1790 # CM
+3504 270 2 0.0000 27.2800 30.5560 23.9050 # CM
+3505 270 2 0.0000 26.8750 30.5840 24.1970 # CM
+3506 270 2 0.0000 26.4720 30.4280 23.9440 # CM
+3507 270 2 0.0000 26.0540 30.4800 24.2150 # CM
+3508 270 2 0.0000 25.6660 30.2900 23.9640 # CM
+3509 270 2 0.0000 25.2880 30.1570 24.2630 # CM
+3510 270 3 0.0000 24.8700 30.1240 23.9910 # CT
+3511 271 1 -1.0000 3.4900 -14.0170 -20.5030 # HG
+3512 271 2 0.0000 2.9990 -13.4620 -20.6210 # CM
+3513 271 2 0.0000 2.6130 -13.4760 -20.3040 # CM
+3514 271 2 0.0000 2.2580 -13.1300 -20.3750 # CM
+3515 271 2 0.0000 1.9020 -13.1570 -20.0240 # CM
+3516 271 2 0.0000 1.5300 -12.8590 -20.1750 # CM
+3517 271 2 0.0000 1.1330 -12.9050 -19.8750 # CM
+3518 271 2 0.0000 0.7520 -12.6250 -20.0360 # CM
+3519 271 2 0.0000 0.4310 -12.5420 -19.6610 # CM
+3520 271 2 0.0000 0.0290 -12.2880 -19.8160 # CM
+3521 271 2 0.0000 -0.2660 -12.1830 -19.4260 # CM
+3522 271 2 0.0000 -0.5620 -11.7890 -19.5070 # CM
+3523 271 3 0.0000 -0.9430 -11.8030 -19.1830 # CT
+3524 272 1 -1.0000 -25.0950 -2.3570 3.5550 # HG
+3525 272 2 0.0000 -25.1610 -3.0990 3.6420 # CM
+3526 272 2 0.0000 -24.7380 -3.3130 3.8020 # CM
+3527 272 2 0.0000 -24.7470 -3.8110 3.8470 # CM
+3528 272 2 0.0000 -24.3180 -3.9880 4.0350 # CM
+3529 272 2 0.0000 -24.3330 -4.4840 3.9840 # CM
+3530 272 2 0.0000 -23.8950 -4.6900 4.1110 # CM
+3531 272 2 0.0000 -23.9000 -5.1840 4.0410 # CM
+3532 272 2 0.0000 -23.5410 -5.3990 4.3150 # CM
+3533 272 2 0.0000 -23.5150 -5.8910 4.2320 # CM
+3534 272 2 0.0000 -23.1760 -6.0970 4.5350 # CM
+3535 272 2 0.0000 -23.2540 -6.5850 4.6120 # CM
+3536 272 3 0.0000 -22.8310 -6.7930 4.7790 # CT
+3537 273 1 -1.0000 -25.1940 20.5540 -24.6320 # HG
+3538 273 2 0.0000 -25.6440 21.1430 -24.5210 # CM
+3539 273 2 0.0000 -26.0720 21.0200 -24.2930 # CM
+3540 273 2 0.0000 -26.4010 21.3900 -24.2270 # CM
+3541 273 2 0.0000 -26.8030 21.2360 -23.9720 # CM
+3542 273 2 0.0000 -27.1410 21.6040 -24.0010 # CM
+3543 273 2 0.0000 -27.5780 21.4610 -23.8040 # CM
+3544 273 2 0.0000 -27.9220 21.8190 -23.8500 # CM
+3545 273 2 0.0000 -28.2890 21.7460 -23.5180 # CM
+3546 273 2 0.0000 -28.6570 22.0810 -23.5750 # CM
+3547 273 2 0.0000 -29.0000 22.0180 -23.2160 # CM
+3548 273 2 0.0000 -29.2690 22.4300 -23.1300 # CM
+3549 273 3 0.0000 -29.6910 22.3020 -22.8950 # CT
+3550 274 1 -1.0000 -17.3600 8.3250 -7.9970 # HG
+3551 274 2 0.0000 -18.0600 8.0620 -7.9430 # CM
+3552 274 2 0.0000 -18.0940 7.6620 -7.6450 # CM
+3553 274 2 0.0000 -18.5470 7.4520 -7.6090 # CM
+3554 274 2 0.0000 -18.5490 7.0720 -7.2830 # CM
+3555 274 2 0.0000 -18.9870 6.8390 -7.3390 # CM
+3556 274 2 0.0000 -19.0010 6.4190 -7.0660 # CM
+3557 274 2 0.0000 -19.4290 6.1730 -7.1360 # CM
+3558 274 2 0.0000 -19.5100 5.8600 -6.7540 # CM
+3559 274 2 0.0000 -19.9220 5.5840 -6.8260 # CM
+3560 274 2 0.0000 -20.0090 5.3010 -6.4240 # CM
+3561 274 2 0.0000 -20.4870 5.1640 -6.3820 # CM
+3562 274 3 0.0000 -20.5160 4.7680 -6.0780 # CT
+3563 275 1 -1.0000 18.2300 34.9180 -18.1300 # HG
+3564 275 2 0.0000 18.4150 34.2360 -18.3800 # CM
+3565 275 2 0.0000 18.0170 33.9690 -18.5250 # CM
+3566 275 2 0.0000 18.1090 33.5020 -18.6760 # CM
+3567 275 2 0.0000 17.6940 33.2750 -18.8390 # CM
+3568 275 2 0.0000 17.8080 32.7920 -18.8980 # CM
+3569 275 2 0.0000 17.4000 32.5240 -19.0070 # CM
+3570 275 2 0.0000 17.5080 32.0380 -19.0450 # CM
+3571 275 2 0.0000 17.1530 31.8050 -19.3100 # CM
+3572 275 2 0.0000 17.2320 31.3120 -19.3300 # CM
+3573 275 2 0.0000 16.8900 31.0970 -19.6240 # CM
+3574 275 2 0.0000 17.0420 30.6590 -19.8110 # CM
+3575 275 3 0.0000 16.6420 30.4000 -19.9620 # CT
+3576 276 1 -1.0000 2.1800 -29.8830 34.4630 # HG
+3577 276 2 0.0000 2.4780 -29.6410 33.8190 # CM
+3578 276 2 0.0000 2.8350 -29.2980 33.8890 # CM
+3579 276 2 0.0000 3.0360 -29.1020 33.4750 # CM
+3580 276 2 0.0000 3.4070 -28.7840 33.5810 # CM
+3581 276 2 0.0000 3.5210 -28.5480 33.1560 # CM
+3582 276 2 0.0000 3.8520 -28.1820 33.2380 # CM
+3583 276 2 0.0000 3.9520 -27.9310 32.8180 # CM
+3584 276 2 0.0000 4.3880 -27.6900 32.8630 # CM
+3585 276 2 0.0000 4.4850 -27.4100 32.4600 # CM
+3586 276 2 0.0000 4.9380 -27.2010 32.5040 # CM
+3587 276 2 0.0000 5.1380 -27.0770 32.0640 # CM
+3588 276 3 0.0000 5.4990 -26.7410 32.1390 # CT
+3589 277 1 -1.0000 -11.0220 -21.2040 -12.4640 # HG
+3590 277 2 0.0000 -11.0430 -20.6410 -12.9590 # CM
+3591 277 2 0.0000 -10.6430 -20.3430 -12.9290 # CM
+3592 277 2 0.0000 -10.6420 -19.9450 -13.2320 # CM
+3593 277 2 0.0000 -10.2160 -19.6850 -13.1940 # CM
+3594 277 2 0.0000 -10.2860 -19.2570 -13.4430 # CM
+3595 277 2 0.0000 -9.8980 -18.9480 -13.3780 # CM
+3596 277 2 0.0000 -9.9760 -18.5120 -13.6080 # CM
+3597 277 2 0.0000 -9.5390 -18.2790 -13.6840 # CM
+3598 277 2 0.0000 -9.6050 -17.8260 -13.8860 # CM
+3599 277 2 0.0000 -9.1610 -17.6200 -13.9870 # CM
+3600 277 2 0.0000 -9.1850 -17.2710 -14.3440 # CM
+3601 277 3 0.0000 -8.7800 -16.9800 -14.3140 # CT
+3602 278 1 -1.0000 -26.8150 -17.2120 -15.0600 # HG
+3603 278 2 0.0000 -26.3880 -16.6550 -14.7940 # CM
+3604 278 2 0.0000 -26.6450 -16.2320 -14.7220 # CM
+3605 278 2 0.0000 -26.3810 -15.8370 -14.5670 # CM
+3606 278 2 0.0000 -26.6740 -15.4410 -14.4800 # CM
+3607 278 2 0.0000 -26.3690 -15.0500 -14.4120 # CM
+3608 278 2 0.0000 -26.6310 -14.6250 -14.3780 # CM
+3609 278 2 0.0000 -26.3280 -14.2310 -14.3300 # CM
+3610 278 2 0.0000 -26.5790 -13.8460 -14.1340 # CM
+3611 278 2 0.0000 -26.2960 -13.4340 -14.1090 # CM
+3612 278 2 0.0000 -26.5480 -13.0680 -13.8810 # CM
+3613 278 2 0.0000 -26.2490 -12.7230 -13.6790 # CM
+3614 278 3 0.0000 -26.5120 -12.3050 -13.6020 # CT
+3615 279 1 -1.0000 -22.1560 27.2340 -33.8070 # HG
+3616 279 2 0.0000 -21.4120 27.1810 -33.7360 # CM
+3617 279 2 0.0000 -21.2620 26.7180 -33.6190 # CM
+3618 279 2 0.0000 -20.7710 26.6590 -33.5430 # CM
+3619 279 2 0.0000 -20.6550 26.1800 -33.4550 # CM
+3620 279 2 0.0000 -20.1790 26.1740 -33.3020 # CM
+3621 279 2 0.0000 -20.0460 25.7160 -33.1510 # CM
+3622 279 2 0.0000 -19.5780 25.7120 -32.9780 # CM
+3623 279 2 0.0000 -19.3970 25.2460 -32.9870 # CM
+3624 279 2 0.0000 -18.9380 25.2230 -32.7870 # CM
+3625 279 2 0.0000 -18.7570 24.7600 -32.8330 # CM
+3626 279 2 0.0000 -18.2580 24.7440 -32.8190 # CM
+3627 279 3 0.0000 -18.1130 24.2790 -32.7100 # CT
+3628 280 1 -1.0000 -1.6320 34.5940 6.8010 # HG
+3629 280 2 0.0000 -1.7230 33.9250 6.4740 # CM
+3630 280 2 0.0000 -2.1990 33.8340 6.3500 # CM
+3631 280 2 0.0000 -2.2920 33.3850 6.1500 # CM
+3632 280 2 0.0000 -2.7720 33.3390 6.0150 # CM
+3633 280 2 0.0000 -2.8430 32.8580 5.9020 # CM
+3634 280 2 0.0000 -3.3270 32.7650 5.8160 # CM
+3635 280 2 0.0000 -3.4050 32.2800 5.7230 # CM
+3636 280 2 0.0000 -3.8370 32.2200 5.4810 # CM
+3637 280 2 0.0000 -3.9420 31.7360 5.4090 # CM
+3638 280 2 0.0000 -4.3590 31.6910 5.1370 # CM
+3639 280 2 0.0000 -4.3890 31.2540 4.8960 # CM
+3640 280 3 0.0000 -4.8640 31.1710 4.7690 # CT
+3641 281 1 -1.0000 -12.1510 -23.4420 -10.0880 # HG
+3642 281 2 0.0000 -12.3260 -23.4970 -10.8150 # CM
+3643 281 2 0.0000 -12.8090 -23.6040 -10.8900 # CM
+3644 281 2 0.0000 -12.9490 -23.6690 -11.3650 # CM
+3645 281 2 0.0000 -13.4410 -23.7470 -11.4040 # CM
+3646 281 2 0.0000 -13.5270 -23.8900 -11.8750 # CM
+3647 281 2 0.0000 -14.0030 -24.0310 -11.9350 # CM
+3648 281 2 0.0000 -14.0860 -24.1950 -12.3990 # CM
+3649 281 2 0.0000 -14.5750 -24.1740 -12.5020 # CM
+3650 281 2 0.0000 -14.6770 -24.3640 -12.9540 # CM
+3651 281 2 0.0000 -15.1620 -24.3070 -13.0570 # CM
+3652 281 2 0.0000 -15.2580 -24.3110 -13.5470 # CM
+3653 281 3 0.0000 -15.7430 -24.4100 -13.6170 # CT
+3654 282 1 -1.0000 30.0920 -1.4610 2.5560 # HG
+3655 282 2 0.0000 29.6220 -1.7310 2.0380 # CM
+3656 282 2 0.0000 29.2020 -1.4620 2.0000 # CM
+3657 282 2 0.0000 28.8600 -1.6330 1.6770 # CM
+3658 282 2 0.0000 28.4670 -1.3250 1.6450 # CM
+3659 282 2 0.0000 28.1160 -1.5680 1.3850 # CM
+3660 282 2 0.0000 27.6870 -1.3110 1.3810 # CM
+3661 282 2 0.0000 27.3290 -1.5610 1.1400 # CM
+3662 282 2 0.0000 26.9690 -1.2460 0.9950 # CM
+3663 282 2 0.0000 26.5880 -1.4880 0.7780 # CM
+3664 282 2 0.0000 26.2520 -1.1600 0.6090 # CM
+3665 282 2 0.0000 25.9690 -1.3430 0.2400 # CM
+3666 282 3 0.0000 25.5550 -1.0660 0.2000 # CT
+3667 283 1 -1.0000 24.8230 -16.0830 5.9120 # HG
+3668 283 2 0.0000 24.1600 -16.3860 5.7340 # CM
+3669 283 2 0.0000 23.7980 -16.0440 5.6870 # CM
+3670 283 2 0.0000 23.3400 -16.2200 5.5910 # CM
+3671 283 2 0.0000 23.0100 -15.8500 5.5240 # CM
+3672 283 2 0.0000 22.5570 -16.0610 5.5170 # CM
+3673 283 2 0.0000 22.1980 -15.7130 5.5070 # CM
+3674 283 2 0.0000 21.7440 -15.9210 5.5210 # CM
+3675 283 2 0.0000 21.4040 -15.5990 5.3470 # CM
+3676 283 2 0.0000 20.9400 -15.7830 5.3840 # CM
+3677 283 2 0.0000 20.6140 -15.4660 5.1770 # CM
+3678 283 2 0.0000 20.1920 -15.6890 5.0320 # CM
+3679 283 3 0.0000 19.8350 -15.3420 4.9790 # CT
+3680 284 1 -1.0000 -2.6240 -17.4460 17.7880 # HG
+3681 284 2 0.0000 -3.3450 -17.2400 17.7840 # CM
+3682 284 2 0.0000 -3.5010 -17.0930 17.3320 # CM
+3683 284 2 0.0000 -3.9730 -16.9290 17.3060 # CM
+3684 284 2 0.0000 -4.1030 -16.8170 16.8350 # CM
+3685 284 2 0.0000 -4.5420 -16.5800 16.8610 # CM
+3686 284 2 0.0000 -4.6760 -16.4030 16.4130 # CM
+3687 284 2 0.0000 -5.1040 -16.1470 16.4390 # CM
+3688 284 2 0.0000 -5.3140 -16.1190 15.9870 # CM
+3689 284 2 0.0000 -5.7290 -15.8390 15.9930 # CM
+3690 284 2 0.0000 -5.9460 -15.8470 15.5430 # CM
+3691 284 2 0.0000 -6.4340 -15.7430 15.5610 # CM
+3692 284 3 0.0000 -6.5870 -15.6040 15.1060 # CT
+3693 285 1 -1.0000 -6.1860 -3.5540 10.8200 # HG
+3694 285 2 0.0000 -5.5730 -3.3570 10.4360 # CM
+3695 285 2 0.0000 -5.4090 -2.8990 10.5530 # CM
+3696 285 2 0.0000 -5.0150 -2.7340 10.2950 # CM
+3697 285 2 0.0000 -4.8620 -2.2850 10.4570 # CM
+3698 285 2 0.0000 -4.5290 -2.1180 10.1250 # CM
+3699 285 2 0.0000 -4.3970 -1.6470 10.2270 # CM
+3700 285 2 0.0000 -4.0790 -1.4700 9.8850 # CM
+3701 285 2 0.0000 -3.8280 -1.0800 10.0700 # CM
+3702 285 2 0.0000 -3.5270 -0.8740 9.7270 # CM
+3703 285 2 0.0000 -3.2580 -0.5080 9.9350 # CM
+3704 285 2 0.0000 -2.8350 -0.4120 9.6870 # CM
+3705 285 3 0.0000 -2.6720 0.0430 9.8130 # CT
+3706 286 1 -1.0000 0.7140 -23.2510 16.4340 # HG
+3707 286 2 0.0000 0.6170 -23.9190 16.7610 # CM
+3708 286 2 0.0000 0.1360 -24.0550 16.7830 # CM
+3709 286 2 0.0000 0.0410 -24.4870 17.0170 # CM
+3710 286 2 0.0000 -0.4450 -24.6050 16.9950 # CM
+3711 286 2 0.0000 -0.5140 -24.9890 17.3080 # CM
+3712 286 2 0.0000 -1.0000 -25.0970 17.3540 # CM
+3713 286 2 0.0000 -1.0730 -25.4670 17.6810 # CM
+3714 286 2 0.0000 -1.5180 -25.6790 17.6020 # CM
+3715 286 2 0.0000 -1.6170 -26.0310 17.9440 # CM
+3716 286 2 0.0000 -2.0490 -26.2580 17.8340 # CM
+3717 286 2 0.0000 -2.0840 -26.7160 18.0300 # CM
+3718 286 3 0.0000 -2.5650 -26.8500 18.0420 # CT
+3719 287 1 -1.0000 -3.6740 -10.0870 20.4910 # HG
+3720 287 2 0.0000 -4.2990 -10.1670 20.8990 # CM
+3721 287 2 0.0000 -4.5570 -9.7410 20.9420 # CM
+3722 287 2 0.0000 -4.9670 -9.7610 21.2280 # CM
+3723 287 2 0.0000 -5.2140 -9.3260 21.2260 # CM
+3724 287 2 0.0000 -5.5620 -9.3570 21.5840 # CM
+3725 287 2 0.0000 -5.7920 -8.9180 21.6480 # CM
+3726 287 2 0.0000 -6.1250 -8.9410 22.0190 # CM
+3727 287 2 0.0000 -6.4590 -8.5710 21.9720 # CM
+3728 287 2 0.0000 -6.7810 -8.5640 22.3540 # CM
+3729 287 2 0.0000 -7.1270 -8.2120 22.2780 # CM
+3730 287 2 0.0000 -7.5510 -8.2980 22.5280 # CM
+3731 287 3 0.0000 -7.8090 -7.8720 22.5630 # CT
+3732 288 1 -1.0000 0.6270 5.3510 30.3200 # HG
+3733 288 2 0.0000 1.3090 5.4760 30.6060 # CM
+3734 288 2 0.0000 1.5440 5.0540 30.7360 # CM
+3735 288 2 0.0000 1.9920 5.1090 30.9510 # CM
+3736 288 2 0.0000 2.2080 4.6680 31.0430 # CM
+3737 288 2 0.0000 2.6070 4.7600 31.3310 # CM
+3738 288 2 0.0000 2.8150 4.3340 31.4890 # CM
+3739 288 2 0.0000 3.2010 4.4240 31.7930 # CM
+3740 288 2 0.0000 3.5000 4.0240 31.8120 # CM
+3741 288 2 0.0000 3.8740 4.0890 32.1380 # CM
+3742 288 2 0.0000 4.1830 3.6960 32.1220 # CM
+3743 288 2 0.0000 4.6430 3.8040 32.2830 # CM
+3744 288 3 0.0000 4.8760 3.3790 32.4050 # CT
+3745 289 1 -1.0000 -5.1560 1.8840 28.1300 # HG
+3746 289 2 0.0000 -4.9990 2.6060 28.2540 # CM
+3747 289 2 0.0000 -4.6130 2.7700 27.9810 # CM
+3748 289 2 0.0000 -4.4720 3.2430 28.0610 # CM
+3749 289 2 0.0000 -4.1030 3.3800 27.7530 # CM
+3750 289 2 0.0000 -3.9350 3.8210 27.9180 # CM
+3751 289 2 0.0000 -3.5260 3.9610 27.6650 # CM
+3752 289 2 0.0000 -3.3440 4.3910 27.8430 # CM
+3753 289 2 0.0000 -3.0530 4.6080 27.4980 # CM
+3754 289 2 0.0000 -2.8380 5.0240 27.6740 # CM
+3755 289 2 0.0000 -2.5780 5.2480 27.3100 # CM
+3756 289 2 0.0000 -2.5130 5.7360 27.3900 # CM
+3757 289 3 0.0000 -2.1310 5.8960 27.1100 # CT
+3758 290 1 -1.0000 -25.8250 27.0360 11.1760 # HG
+3759 290 2 0.0000 -25.6100 27.6560 10.8140 # CM
+3760 290 2 0.0000 -25.4710 27.5660 10.3420 # CM
+3761 290 2 0.0000 -25.3010 27.9590 10.0850 # CM
+3762 290 2 0.0000 -25.1970 27.8380 9.6100 # CM
+3763 290 2 0.0000 -24.9530 28.2280 9.4130 # CM
+3764 290 2 0.0000 -24.7850 28.1190 8.9550 # CM
+3765 290 2 0.0000 -24.5230 28.4980 8.7640 # CM
+3766 290 2 0.0000 -24.5020 28.4570 8.2660 # CM
+3767 290 2 0.0000 -24.2160 28.8150 8.0640 # CM
+3768 290 2 0.0000 -24.2310 28.7830 7.5650 # CM
+3769 290 2 0.0000 -24.1200 29.2140 7.3390 # CM
+3770 290 3 0.0000 -23.9890 29.1190 6.8660 # CT
+3771 291 1 -1.0000 22.4450 -13.3280 6.1690 # HG
+3772 291 2 0.0000 22.9910 -13.2190 6.6700 # CM
+3773 291 2 0.0000 23.3730 -13.5370 6.6120 # CM
+3774 291 2 0.0000 23.7420 -13.5020 6.9480 # CM
+3775 291 2 0.0000 24.1180 -13.8160 6.8430 # CM
+3776 291 2 0.0000 24.4210 -13.8140 7.2400 # CM
+3777 291 2 0.0000 24.7790 -14.1600 7.1920 # CM
+3778 291 2 0.0000 25.0710 -14.1740 7.5970 # CM
+3779 291 2 0.0000 25.5090 -14.3880 7.4840 # CM
+3780 291 2 0.0000 25.8000 -14.4370 7.8880 # CM
+3781 291 2 0.0000 26.2450 -14.6200 7.7550 # CM
+3782 291 2 0.0000 26.6060 -14.5100 8.0820 # CM
+3783 291 3 0.0000 26.9880 -14.8250 8.0150 # CT
+3784 292 1 -1.0000 21.7360 -5.0640 14.0370 # HG
+3785 292 2 0.0000 21.1760 -5.5500 14.1440 # CM
+3786 292 2 0.0000 21.0410 -5.7860 13.7240 # CM
+3787 292 2 0.0000 20.6540 -6.1000 13.7620 # CM
+3788 292 2 0.0000 20.5650 -6.3370 13.3300 # CM
+3789 292 2 0.0000 20.1270 -6.5710 13.3830 # CM
+3790 292 2 0.0000 19.9800 -6.7740 12.9500 # CM
+3791 292 2 0.0000 19.5320 -6.9910 12.9940 # CM
+3792 292 2 0.0000 19.4670 -7.3230 12.6270 # CM
+3793 292 2 0.0000 19.0100 -7.5260 12.6420 # CM
+3794 292 2 0.0000 18.9700 -7.8800 12.2910 # CM
+3795 292 2 0.0000 18.6160 -8.2170 12.3940 # CM
+3796 292 3 0.0000 18.4900 -8.4540 11.9730 # CT
+3797 293 1 -1.0000 -28.6210 26.7220 13.3880 # HG
+3798 293 2 0.0000 -28.8060 27.3380 13.7740 # CM
+3799 293 2 0.0000 -28.4130 27.6310 13.8690 # CM
+3800 293 2 0.0000 -28.5030 28.0380 14.1440 # CM
+3801 293 2 0.0000 -28.0940 28.3220 14.1960 # CM
+3802 293 2 0.0000 -28.2010 28.6660 14.5420 # CM
+3803 293 2 0.0000 -27.7940 28.9330 14.6600 # CM
+3804 293 2 0.0000 -27.8930 29.2630 15.0200 # CM
+3805 293 2 0.0000 -27.5500 29.6270 15.0170 # CM
+3806 293 2 0.0000 -27.6190 29.9490 15.3930 # CM
+3807 293 2 0.0000 -27.2910 30.3240 15.3580 # CM
+3808 293 2 0.0000 -27.4440 30.7390 15.5910 # CM
+3809 293 3 0.0000 -27.0490 31.0330 15.6760 # CT
+3810 294 1 -1.0000 21.2010 11.7260 -5.2700 # HG
+3811 294 2 0.0000 20.6350 11.2760 -5.0730 # CM
+3812 294 2 0.0000 20.2250 11.3480 -5.3510 # CM
+3813 294 2 0.0000 19.8250 11.0760 -5.2260 # CM
+3814 294 2 0.0000 19.4440 11.1530 -5.5420 # CM
+3815 294 2 0.0000 19.0430 10.9360 -5.3380 # CM
+3816 294 2 0.0000 18.6300 11.0420 -5.6010 # CM
+3817 294 2 0.0000 18.2250 10.8430 -5.3870 # CM
+3818 294 2 0.0000 17.8570 10.8050 -5.7240 # CM
+3819 294 2 0.0000 17.4340 10.6360 -5.5160 # CM
+3820 294 2 0.0000 17.0860 10.5710 -5.8680 # CM
+3821 294 2 0.0000 16.7340 10.2420 -5.7360 # CM
+3822 294 3 0.0000 16.3300 10.3120 -6.0220 # CT
+3823 295 1 -1.0000 27.1700 -21.8960 19.3950 # HG
+3824 295 2 0.0000 27.0280 -22.6190 19.2570 # CM
+3825 295 2 0.0000 26.5430 -22.7070 19.1700 # CM
+3826 295 2 0.0000 26.4160 -23.1860 19.0970 # CM
+3827 295 2 0.0000 25.9310 -23.2340 18.9860 # CM
+3828 295 2 0.0000 25.8270 -23.7220 19.0060 # CM
+3829 295 2 0.0000 25.3350 -23.8010 18.9550 # CM
+3830 295 2 0.0000 25.2260 -24.2870 18.9960 # CM
+3831 295 2 0.0000 24.7820 -24.3800 18.7850 # CM
+3832 295 2 0.0000 24.6460 -24.8580 18.8450 # CM
+3833 295 2 0.0000 24.2180 -24.9440 18.6010 # CM
+3834 295 2 0.0000 24.1550 -25.4260 18.4860 # CM
+3835 295 3 0.0000 23.6710 -25.5080 18.3920 # CT
+3836 296 1 -1.0000 -24.6780 -15.1730 -10.9340 # HG
+3837 296 2 0.0000 -25.2760 -15.6260 -10.9540 # CM
+3838 296 2 0.0000 -25.4650 -15.7160 -10.5000 # CM
+3839 296 2 0.0000 -25.8510 -16.0340 -10.4820 # CM
+3840 296 2 0.0000 -26.0300 -16.0790 -10.0170 # CM
+3841 296 2 0.0000 -26.3510 -16.4620 -10.0250 # CM
+3842 296 2 0.0000 -26.5080 -16.5720 -9.5620 # CM
+3843 296 2 0.0000 -26.8130 -16.9670 -9.5640 # CM
+3844 296 2 0.0000 -27.0910 -16.9710 -9.1490 # CM
+3845 296 2 0.0000 -27.3800 -17.3790 -9.1230 # CM
+3846 296 2 0.0000 -27.6750 -17.3530 -8.7210 # CM
+3847 296 2 0.0000 -28.0870 -17.6330 -8.7640 # CM
+3848 296 3 0.0000 -28.2760 -17.7140 -8.3090 # CT
+3849 297 1 -1.0000 -22.8390 -32.4630 12.0020 # HG
+3850 297 2 0.0000 -23.3460 -32.9500 12.2630 # CM
+3851 297 2 0.0000 -23.6340 -32.7550 12.6230 # CM
+3852 297 2 0.0000 -23.9660 -33.0660 12.8310 # CM
+3853 297 2 0.0000 -24.2530 -32.8310 13.1670 # CM
+3854 297 2 0.0000 -24.5080 -33.1850 13.4100 # CM
+3855 297 2 0.0000 -24.7650 -32.9890 13.7920 # CM
+3856 297 2 0.0000 -25.0040 -33.3440 14.0500 # CM
+3857 297 2 0.0000 -25.3780 -33.1410 14.3130 # CM
+3858 297 2 0.0000 -25.6070 -33.4810 14.6000 # CM
+3859 297 2 0.0000 -25.9980 -33.2730 14.8300 # CM
+3860 297 2 0.0000 -26.3440 -33.6060 14.9670 # CM
+3861 297 3 0.0000 -26.6330 -33.4050 15.3210 # CT
+3862 298 1 -1.0000 -15.8810 -22.1070 -22.6730 # HG
+3863 298 2 0.0000 -16.3450 -22.6720 -22.8410 # CM
+3864 298 2 0.0000 -16.1880 -23.1110 -22.6610 # CM
+3865 298 2 0.0000 -16.4670 -23.5090 -22.7780 # CM
+3866 298 2 0.0000 -16.2970 -23.9260 -22.5590 # CM
+3867 298 2 0.0000 -16.5440 -24.3070 -22.7650 # CM
+3868 298 2 0.0000 -16.3580 -24.7450 -22.6090 # CM
+3869 298 2 0.0000 -16.5900 -25.1280 -22.8290 # CM
+3870 298 2 0.0000 -16.5250 -25.5440 -22.5600 # CM
+3871 298 2 0.0000 -16.7270 -25.9430 -22.7850 # CM
+3872 298 2 0.0000 -16.6840 -26.3440 -22.4900 # CM
+3873 298 2 0.0000 -17.0230 -26.6970 -22.5920 # CM
+3874 298 3 0.0000 -16.8660 -27.1320 -22.4030 # CT
+3875 299 1 -1.0000 3.1000 2.3670 7.3130 # HG
+3876 299 2 0.0000 3.3070 1.8120 6.8530 # CM
+3877 299 2 0.0000 3.3480 1.3720 7.0870 # CM
+3878 299 2 0.0000 3.5060 0.9880 6.8090 # CM
+3879 299 2 0.0000 3.5090 0.5600 7.0680 # CM
+3880 299 2 0.0000 3.7500 0.2240 6.7880 # CM
+3881 299 2 0.0000 3.8210 -0.2020 7.0410 # CM
+3882 299 2 0.0000 4.0800 -0.5310 6.7700 # CM
+3883 299 2 0.0000 4.0060 -0.9930 6.9480 # CM
+3884 299 2 0.0000 4.2840 -1.3310 6.7050 # CM
+3885 299 2 0.0000 4.1760 -1.7900 6.8690 # CM
+3886 299 2 0.0000 4.2870 -2.1460 6.5370 # CM
+3887 299 3 0.0000 4.3190 -2.5850 6.7740 # CT
+3888 300 1 -1.0000 -4.4640 3.3890 -9.8740 # HG
+3889 300 2 0.0000 -4.5840 3.7750 -10.5050 # CM
+3890 300 2 0.0000 -4.2400 4.1300 -10.5830 # CM
+3891 300 2 0.0000 -4.3090 4.4180 -10.9850 # CM
+3892 300 2 0.0000 -3.9330 4.7430 -11.0470 # CM
+3893 300 2 0.0000 -4.0770 5.0640 -11.4010 # CM
+3894 300 2 0.0000 -3.7470 5.4370 -11.4480 # CM
+3895 300 2 0.0000 -3.8990 5.7710 -11.7870 # CM
+3896 300 2 0.0000 -3.5100 6.0380 -11.9500 # CM
+3897 300 2 0.0000 -3.6530 6.3980 -12.2680 # CM
+3898 300 2 0.0000 -3.2510 6.6340 -12.4480 # CM
+3899 300 2 0.0000 -3.3370 6.8570 -12.8860 # CM
+3900 300 3 0.0000 -2.9870 7.2060 -12.9630 # CT
+3901 301 4 1.0000 -15.6430 -13.1540 -6.3380 # CI
+3902 302 4 1.0000 -2.1530 -0.2490 13.4550 # CI
+3903 303 4 1.0000 24.2440 -20.2460 -2.9090 # CI
+3904 304 4 1.0000 -4.6500 19.9680 -15.0810 # CI
+3905 305 4 1.0000 8.0440 16.0690 29.4580 # CI
+3906 306 4 1.0000 -25.2340 -24.6400 -10.3170 # CI
+3907 307 4 1.0000 -7.7910 10.4690 -18.9120 # CI
+3908 308 4 1.0000 28.9720 -28.8690 -0.3350 # CI
+3909 309 4 1.0000 -16.0300 -0.4190 -33.0860 # CI
+3910 310 4 1.0000 -4.4720 -30.8520 -7.9450 # CI
+3911 311 4 1.0000 -12.2140 24.6180 33.4290 # CI
+3912 312 4 1.0000 -32.4870 3.0100 -30.2520 # CI
+3913 313 4 1.0000 16.0680 -18.8250 -10.9410 # CI
+3914 314 4 1.0000 -17.9150 -34.5180 30.7010 # CI
+3915 315 4 1.0000 11.1210 23.5280 30.7700 # CI
+3916 316 4 1.0000 -8.4460 14.4700 13.4680 # CI
+3917 317 4 1.0000 -11.8070 -32.6310 -7.9530 # CI
+3918 318 4 1.0000 -19.8090 13.6120 5.9980 # CI
+3919 319 4 1.0000 25.5340 -23.6300 6.9170 # CI
+3920 320 4 1.0000 34.1300 -13.3150 17.4200 # CI
+3921 321 4 1.0000 20.5150 30.0600 24.2700 # CI
+3922 322 4 1.0000 -23.6750 29.7520 -11.7970 # CI
+3923 323 4 1.0000 -17.9690 -0.6660 17.6300 # CI
+3924 324 4 1.0000 7.0810 17.8760 1.8980 # CI
+3925 325 4 1.0000 -28.4610 10.4140 31.1420 # CI
+3926 326 4 1.0000 -33.9660 13.8720 17.2210 # CI
+3927 327 4 1.0000 -9.9180 34.5170 34.5410 # CI
+3928 328 4 1.0000 10.0960 3.9700 -11.2180 # CI
+3929 329 4 1.0000 25.3780 2.5570 -21.1040 # CI
+3930 330 4 1.0000 2.1730 -34.7070 2.3170 # CI
+3931 331 4 1.0000 -4.8370 -25.5010 10.0160 # CI
+3932 332 4 1.0000 14.3540 31.3180 -5.4990 # CI
+3933 333 4 1.0000 -22.0430 21.5320 18.6310 # CI
+3934 334 4 1.0000 -33.7920 -21.3250 -32.5300 # CI
+3935 335 4 1.0000 27.9580 -4.1530 5.9400 # CI
+3936 336 4 1.0000 -7.7120 -13.3510 16.8580 # CI
+3937 337 4 1.0000 30.5410 -3.2640 7.2250 # CI
+3938 338 4 1.0000 7.2280 -28.1880 -5.7000 # CI
+3939 339 4 1.0000 -8.9620 -8.9880 -6.3090 # CI
+3940 340 4 1.0000 13.2800 -34.6210 -31.7550 # CI
+3941 341 4 1.0000 -22.1050 -17.6350 -21.3360 # CI
+3942 342 4 1.0000 20.4770 -26.1580 -1.0790 # CI
+3943 343 4 1.0000 2.1830 -19.1460 9.8900 # CI
+3944 344 4 1.0000 -21.3280 11.2800 10.3380 # CI
+3945 345 4 1.0000 -10.2090 11.9250 22.7930 # CI
+3946 346 4 1.0000 -31.0230 29.3960 -27.5460 # CI
+3947 347 4 1.0000 16.6040 0.7260 32.1050 # CI
+3948 348 4 1.0000 10.3880 30.3560 12.9380 # CI
+3949 349 4 1.0000 13.8040 7.7100 -33.2940 # CI
+3950 350 4 1.0000 -13.5560 -8.6110 21.3770 # CI
+3951 351 4 1.0000 -20.9610 -16.7680 1.9640 # CI
+3952 352 4 1.0000 1.6260 -24.9370 25.9050 # CI
+3953 353 4 1.0000 -1.6890 32.1080 24.3660 # CI
+3954 354 4 1.0000 -31.7410 14.6440 17.9880 # CI
+3955 355 4 1.0000 25.5370 -33.8900 18.0240 # CI
+3956 356 4 1.0000 16.2570 -25.4130 -3.3740 # CI
+3957 357 4 1.0000 8.1000 -0.7260 -34.4930 # CI
+3958 358 4 1.0000 5.2060 29.7510 -17.0990 # CI
+3959 359 4 1.0000 -10.4550 -6.6440 -33.0980 # CI
+3960 360 4 1.0000 -8.9600 -6.7620 -1.0190 # CI
+3961 361 4 1.0000 22.8850 -9.8170 26.0340 # CI
+3962 362 4 1.0000 2.2360 29.7040 -26.0460 # CI
+3963 363 4 1.0000 -6.5780 -3.6950 -30.9130 # CI
+3964 364 4 1.0000 12.3010 -28.7700 31.4600 # CI
+3965 365 4 1.0000 -30.3540 -11.6000 13.1310 # CI
+3966 366 4 1.0000 -3.5640 15.2510 10.6130 # CI
+3967 367 4 1.0000 12.0320 24.8960 28.5020 # CI
+3968 368 4 1.0000 -7.4850 -29.7130 -11.2480 # CI
+3969 369 4 1.0000 -32.3250 -27.8290 7.4000 # CI
+3970 370 4 1.0000 -24.4410 2.6400 -32.8110 # CI
+3971 371 4 1.0000 8.0920 30.2180 10.9490 # CI
+3972 372 4 1.0000 -4.7880 5.7210 34.9230 # CI
+3973 373 4 1.0000 28.5530 -13.2620 -25.5640 # CI
+3974 374 4 1.0000 -7.2940 16.6030 -33.8400 # CI
+3975 375 4 1.0000 19.4930 13.9330 -26.2270 # CI
+3976 376 4 1.0000 -15.8860 12.3630 13.3260 # CI
+3977 377 4 1.0000 -24.9470 -9.4830 34.6390 # CI
+3978 378 4 1.0000 -15.4710 7.6270 -5.2150 # CI
+3979 379 4 1.0000 11.5650 -17.7110 -24.3130 # CI
+3980 380 4 1.0000 -30.9160 -3.2260 2.4180 # CI
+3981 381 4 1.0000 -13.1350 5.0760 0.5410 # CI
+3982 382 4 1.0000 -28.6580 -5.8590 -4.2110 # CI
+3983 383 4 1.0000 19.1160 -8.5600 -24.6390 # CI
+3984 384 4 1.0000 14.7240 21.8780 30.6430 # CI
+3985 385 4 1.0000 -32.3470 -8.2300 19.1650 # CI
+3986 386 4 1.0000 5.4200 -21.3240 21.6950 # CI
+3987 387 4 1.0000 2.7730 27.9110 22.8570 # CI
+3988 388 4 1.0000 8.3280 32.3710 -22.1710 # CI
+3989 389 4 1.0000 -10.8340 6.1730 -17.3980 # CI
+3990 390 4 1.0000 15.4430 -33.5450 -13.4300 # CI
+3991 391 4 1.0000 25.7940 -29.8240 -18.1940 # CI
+3992 392 4 1.0000 5.1640 30.3160 6.4790 # CI
+3993 393 4 1.0000 34.0660 12.3580 -9.4320 # CI
+3994 394 4 1.0000 -11.8200 11.2740 28.6380 # CI
+3995 395 4 1.0000 -30.3760 24.0700 3.2900 # CI
+3996 396 4 1.0000 28.8080 10.7820 -4.2060 # CI
+3997 397 4 1.0000 -4.9710 5.5930 -25.1560 # CI
+3998 398 4 1.0000 -34.6360 18.6330 -1.5330 # CI
+3999 399 4 1.0000 -8.2310 -29.3860 13.3470 # CI
+4000 400 4 1.0000 32.8400 -13.9930 24.9000 # CI
+4001 401 4 1.0000 -5.6540 -7.4720 29.4960 # CI
+4002 402 4 1.0000 -24.2040 24.3340 21.4830 # CI
+4003 403 4 1.0000 16.7310 -4.2330 -17.0750 # CI
+4004 404 4 1.0000 -23.5510 22.9260 -12.7740 # CI
+4005 405 4 1.0000 -14.5140 18.1390 3.4840 # CI
+4006 406 4 1.0000 -33.1050 10.4170 -20.5420 # CI
+4007 407 4 1.0000 19.5980 14.4060 27.2880 # CI
+4008 408 4 1.0000 -19.5720 24.0340 -8.3520 # CI
+4009 409 4 1.0000 -14.9640 25.0940 -2.7140 # CI
+4010 410 4 1.0000 23.2280 4.4890 27.2310 # CI
+4011 411 4 1.0000 -12.1230 17.3710 16.9290 # CI
+4012 412 4 1.0000 -14.3040 -30.2090 9.2540 # CI
+4013 413 4 1.0000 -5.8090 -28.5470 -0.9440 # CI
+4014 414 4 1.0000 -12.9340 -30.2930 17.2480 # CI
+4015 415 4 1.0000 -10.7250 34.3800 -28.5530 # CI
+4016 416 4 1.0000 25.4330 32.4210 30.4770 # CI
+4017 417 4 1.0000 9.0350 20.1730 -19.1130 # CI
+4018 418 4 1.0000 -17.1120 -19.0690 -23.9220 # CI
+4019 419 4 1.0000 18.3790 -14.9440 17.3410 # CI
+4020 420 4 1.0000 2.5200 -15.1220 -12.8600 # CI
+4021 421 4 1.0000 -25.6760 1.3160 -25.0850 # CI
+4022 422 4 1.0000 11.8070 15.2560 22.5500 # CI
+4023 423 4 1.0000 7.4840 -16.8810 29.7480 # CI
+4024 424 4 1.0000 -28.2640 -12.8200 34.1060 # CI
+4025 425 4 1.0000 -31.0130 7.9350 12.4330 # CI
+4026 426 4 1.0000 5.3710 6.3660 11.2110 # CI
+4027 427 4 1.0000 -17.9560 2.5730 -0.4760 # CI
+4028 428 4 1.0000 -14.1330 -25.2180 -15.5780 # CI
+4029 429 4 1.0000 15.5840 27.8200 30.7940 # CI
+4030 430 4 1.0000 0.5880 -26.3400 -18.0380 # CI
+4031 431 4 1.0000 6.0210 -13.5190 17.3510 # CI
+4032 432 4 1.0000 -25.2230 -32.2150 -13.7060 # CI
+4033 433 4 1.0000 -27.9850 17.2740 10.5260 # CI
+4034 434 4 1.0000 -34.0870 16.0540 -32.8330 # CI
+4035 435 4 1.0000 -3.6310 27.0470 -33.5330 # CI
+4036 436 4 1.0000 0.7900 14.9280 7.3720 # CI
+4037 437 4 1.0000 -28.7110 24.7940 -18.1450 # CI
+4038 438 4 1.0000 16.3310 -34.1710 -6.3410 # CI
+4039 439 4 1.0000 -15.1340 -4.3560 10.5720 # CI
+4040 440 4 1.0000 -8.5310 31.2430 33.1970 # CI
+4041 441 4 1.0000 9.7140 25.4050 -7.7820 # CI
+4042 442 4 1.0000 19.2840 7.5170 -17.7370 # CI
+4043 443 4 1.0000 26.5510 10.8410 28.1660 # CI
+4044 444 4 1.0000 19.0110 10.9540 -30.8520 # CI
+4045 445 4 1.0000 17.5410 -14.9000 -33.2780 # CI
+4046 446 4 1.0000 -19.8550 15.5160 -20.9640 # CI
+4047 447 4 1.0000 23.3900 24.7610 -19.9140 # CI
+4048 448 4 1.0000 -23.9310 -2.3660 -5.8800 # CI
+4049 449 4 1.0000 15.4840 27.1550 6.6270 # CI
+4050 450 4 1.0000 35.0000 23.0760 -33.0020 # CI
+4051 451 4 1.0000 -4.7580 -19.8100 -27.6370 # CI
+4052 452 4 1.0000 24.3320 -26.9220 34.1980 # CI
+4053 453 4 1.0000 -25.1850 -24.8810 -22.5360 # CI
+4054 454 4 1.0000 -14.7840 9.9340 -2.8260 # CI
+4055 455 4 1.0000 -7.4200 -1.8260 20.7370 # CI
+4056 456 4 1.0000 -4.2230 -20.7950 -30.7690 # CI
+4057 457 4 1.0000 -10.4500 23.9080 -9.4110 # CI
+4058 458 4 1.0000 -10.4660 -11.2250 -8.9930 # CI
+4059 459 4 1.0000 5.3380 -9.5930 23.1690 # CI
+4060 460 4 1.0000 -13.9600 -31.0980 -28.8250 # CI
+4061 461 4 1.0000 -12.5480 1.7940 -28.7860 # CI
+4062 462 4 1.0000 22.5830 -2.7490 -29.0470 # CI
+4063 463 4 1.0000 -16.5200 11.0090 -25.7320 # CI
+4064 464 4 1.0000 11.0700 -4.2930 22.9620 # CI
+4065 465 4 1.0000 -34.6820 -12.5100 10.4140 # CI
+4066 466 4 1.0000 -26.1480 31.1840 -31.6360 # CI
+4067 467 4 1.0000 14.0220 -11.8350 23.7060 # CI
+4068 468 4 1.0000 -13.7910 10.7470 2.8740 # CI
+4069 469 4 1.0000 3.1630 -19.7700 1.8410 # CI
+4070 470 4 1.0000 10.3230 -31.8060 -27.4250 # CI
+4071 471 4 1.0000 24.1800 -21.2060 21.0550 # CI
+4072 472 4 1.0000 -9.1340 17.9600 -15.6660 # CI
+4073 473 4 1.0000 23.7900 23.0300 9.3650 # CI
+4074 474 4 1.0000 -20.9330 33.9950 31.2430 # CI
+4075 475 4 1.0000 -6.4570 27.3740 -28.7900 # CI
+4076 476 4 1.0000 -5.0950 30.6770 -24.0230 # CI
+4077 477 4 1.0000 -23.8420 -33.7030 33.8930 # CI
+4078 478 4 1.0000 -21.3040 9.5420 -7.1540 # CI
+4079 479 4 1.0000 2.5380 34.7620 -30.2770 # CI
+4080 480 4 1.0000 -8.0030 0.3400 -24.1490 # CI
+4081 481 4 1.0000 18.1820 21.4480 25.3190 # CI
+4082 482 4 1.0000 -10.2370 -12.9520 0.9130 # CI
+4083 483 4 1.0000 11.1560 -0.7870 17.7030 # CI
+4084 484 4 1.0000 -5.7420 -4.0020 21.3350 # CI
+4085 485 4 1.0000 9.4160 -2.7090 22.3390 # CI
+4086 486 4 1.0000 12.4220 -7.8550 8.3410 # CI
+4087 487 4 1.0000 -21.8180 21.9990 -10.3630 # CI
+4088 488 4 1.0000 -4.3710 15.7940 6.7760 # CI
+4089 489 4 1.0000 10.5910 -3.8580 -33.0050 # CI
+4090 490 4 1.0000 -23.7460 -14.2380 3.4310 # CI
+4091 491 4 1.0000 -34.1710 -24.1810 -27.9990 # CI
+4092 492 4 1.0000 24.0170 9.4570 31.0210 # CI
+4093 493 4 1.0000 14.5350 11.0980 17.9870 # CI
+4094 494 4 1.0000 -33.5270 -24.4750 6.3620 # CI
+4095 495 4 1.0000 28.8500 -0.5980 17.7850 # CI
+4096 496 4 1.0000 -2.5290 8.8020 26.8750 # CI
+4097 497 4 1.0000 -2.0040 23.1950 12.9320 # CI
+4098 498 4 1.0000 6.6990 2.7660 -33.5750 # CI
+4099 499 4 1.0000 -19.7410 3.3510 -18.5540 # CI
+4100 500 4 1.0000 20.7110 -1.2660 21.0810 # CI
+4101 501 4 1.0000 17.0360 -19.7440 2.6510 # CI
+4102 502 4 1.0000 -27.2510 -4.7230 29.1480 # CI
+4103 503 4 1.0000 -22.9290 3.7310 -26.2840 # CI
+4104 504 4 1.0000 28.8750 10.7140 13.4040 # CI
+4105 505 4 1.0000 11.9230 10.6040 34.8840 # CI
+4106 506 4 1.0000 -0.3570 -14.2360 4.2700 # CI
+4107 507 4 1.0000 23.3970 -7.9620 30.3530 # CI
+4108 508 4 1.0000 -3.6750 28.5730 16.6240 # CI
+4109 509 4 1.0000 15.5540 -6.3190 9.6510 # CI
+4110 510 4 1.0000 -11.7460 -11.5290 8.1040 # CI
+4111 511 4 1.0000 -13.2870 -21.7500 -6.4120 # CI
+4112 512 4 1.0000 8.2070 7.6960 33.5450 # CI
+4113 513 4 1.0000 -3.4300 10.2500 -0.2780 # CI
+4114 514 4 1.0000 -20.3760 14.4340 13.7060 # CI
+4115 515 4 1.0000 2.4660 21.7100 25.3360 # CI
+4116 516 4 1.0000 16.6210 -23.0960 -1.5010 # CI
+4117 517 4 1.0000 -7.3150 33.7700 -17.5770 # CI
+4118 518 4 1.0000 -32.4210 24.9400 34.2430 # CI
+4119 519 4 1.0000 26.7170 -7.5110 -4.2020 # CI
+4120 520 4 1.0000 33.8640 -12.6150 28.1930 # CI
+4121 521 4 1.0000 -17.1020 -3.1980 -25.3160 # CI
+4122 522 4 1.0000 -32.3670 -15.3610 26.6220 # CI
+4123 523 4 1.0000 -27.2200 2.0830 17.9830 # CI
+4124 524 4 1.0000 -20.1980 -16.9320 -7.5310 # CI
+4125 525 4 1.0000 -11.5270 -32.1400 24.5970 # CI
+4126 526 4 1.0000 -12.3840 -19.0940 12.3210 # CI
+4127 527 4 1.0000 -7.7080 -13.9230 33.0490 # CI
+4128 528 4 1.0000 -0.5340 8.3670 -15.6110 # CI
+4129 529 4 1.0000 7.3250 -31.6800 -33.0320 # CI
+4130 530 4 1.0000 -21.7950 -27.5760 18.9810 # CI
+4131 531 4 1.0000 -11.9960 7.2420 -10.2260 # CI
+4132 532 4 1.0000 -18.5980 17.1310 4.7490 # CI
+4133 533 4 1.0000 31.8310 -32.5140 33.5160 # CI
+4134 534 4 1.0000 -4.9300 -3.4940 18.6540 # CI
+4135 535 4 1.0000 -28.1010 6.8890 12.2870 # CI
+4136 536 4 1.0000 8.0360 11.3340 -8.9540 # CI
+4137 537 4 1.0000 -13.8430 -15.2090 11.0660 # CI
+4138 538 4 1.0000 -19.2180 8.4270 -17.2610 # CI
+4139 539 4 1.0000 34.7110 -26.7730 33.9990 # CI
+4140 540 4 1.0000 4.6950 3.9930 1.9680 # CI
+4141 541 4 1.0000 -1.5980 -5.1840 26.8510 # CI
+4142 542 4 1.0000 -15.5330 1.3420 -21.7420 # CI
+4143 543 4 1.0000 32.9130 -21.6660 -5.0700 # CI
+4144 544 4 1.0000 5.0500 9.3750 -34.2130 # CI
+4145 545 4 1.0000 -31.3430 32.1810 -18.0150 # CI
+4146 546 4 1.0000 -23.9030 25.4360 34.6150 # CI
+4147 547 4 1.0000 20.5450 -33.1830 -31.3110 # CI
+4148 548 4 1.0000 22.5330 -0.7140 19.9750 # CI
+4149 549 4 1.0000 -9.2170 3.5920 -27.2980 # CI
+4150 550 4 1.0000 34.3850 16.5850 15.3510 # CI
+4151 551 4 1.0000 24.4210 28.2790 18.0730 # CI
+4152 552 4 1.0000 -4.4700 -13.4580 -28.5640 # CI
+4153 553 4 1.0000 -10.8530 -19.0980 4.6880 # CI
+4154 554 4 1.0000 3.3200 -9.7810 0.5460 # CI
+4155 555 4 1.0000 8.6180 20.6330 11.0260 # CI
+4156 556 4 1.0000 13.8010 -5.4580 -22.5320 # CI
+4157 557 4 1.0000 16.7680 23.3050 -28.0070 # CI
+4158 558 4 1.0000 -30.1860 -31.1840 31.3590 # CI
+4159 559 4 1.0000 -19.2110 0.1230 -8.3690 # CI
+4160 560 4 1.0000 -9.1150 30.7950 30.5260 # CI
+4161 561 4 1.0000 20.5560 -18.4670 -20.6480 # CI
+4162 562 4 1.0000 -22.5360 -33.6700 22.5350 # CI
+4163 563 4 1.0000 -2.5930 4.9750 -30.1820 # CI
+4164 564 4 1.0000 -1.8210 -9.0480 24.6220 # CI
+4165 565 4 1.0000 -3.9730 32.6510 -18.6870 # CI
+4166 566 4 1.0000 -22.0710 -26.5110 16.9910 # CI
+4167 567 4 1.0000 -21.3810 -19.5350 31.5890 # CI
+4168 568 4 1.0000 31.6900 -11.2860 -34.5140 # CI
+4169 569 4 1.0000 -15.6490 -12.9630 34.1120 # CI
+4170 570 4 1.0000 -31.5470 7.6550 -20.5030 # CI
+4171 571 4 1.0000 25.0530 20.7610 10.3610 # CI
+4172 572 4 1.0000 -23.1110 17.8120 -25.6320 # CI
+4173 573 4 1.0000 28.9370 24.6650 20.7020 # CI
+4174 574 4 1.0000 8.8390 8.3790 22.4800 # CI
+4175 575 4 1.0000 -11.3290 3.3740 -1.8990 # CI
+4176 576 4 1.0000 18.3990 31.0350 15.5450 # CI
+4177 577 4 1.0000 -4.4510 27.1180 31.8910 # CI
+4178 578 4 1.0000 11.7270 5.2040 -5.2800 # CI
+4179 579 4 1.0000 -4.9520 2.4720 -12.3700 # CI
+4180 580 4 1.0000 -5.8890 -5.6990 6.6580 # CI
+4181 581 4 1.0000 18.4940 -22.9360 15.8390 # CI
+4182 582 4 1.0000 -15.4070 23.2400 32.7000 # CI
+4183 583 4 1.0000 -3.2500 28.0630 22.2520 # CI
+4184 584 4 1.0000 3.2460 -17.2170 -5.9800 # CI
+4185 585 4 1.0000 -11.4940 21.0450 -28.7900 # CI
+4186 586 4 1.0000 19.9110 -28.5130 -10.9570 # CI
+4187 587 4 1.0000 27.2600 18.2050 8.4990 # CI
+4188 588 4 1.0000 6.8000 -21.5220 26.0920 # CI
+4189 589 4 1.0000 20.5980 28.4730 33.5230 # CI
+4190 590 4 1.0000 -27.8990 -18.4530 -6.0910 # CI
+4191 591 4 1.0000 2.7430 -21.9920 -17.7250 # CI
+4192 592 4 1.0000 5.4690 18.3390 -1.1910 # CI
+4193 593 4 1.0000 -23.0030 16.9360 -6.1050 # CI
+4194 594 4 1.0000 30.0530 8.1160 21.9170 # CI
+4195 595 4 1.0000 11.4440 -20.9510 33.8300 # CI
+4196 596 4 1.0000 20.7130 30.6230 -32.6420 # CI
+4197 597 4 1.0000 -10.6620 28.8880 21.8470 # CI
+4198 598 4 1.0000 -11.8480 21.8330 -19.4110 # CI
+4199 599 4 1.0000 12.1590 -6.9200 15.2940 # CI
+4200 600 4 1.0000 30.0060 -25.8740 -23.2920 # CI
+
+Bonds
+
+1 1 1 2 # HG CM
+2 2 2 3 # CM CM
+3 3 3 4 # CM CM
+4 4 4 5 # CM CM
+5 5 5 6 # CM CM
+6 6 6 7 # CM CM
+7 7 7 8 # CM CM
+8 8 8 9 # CM CM
+9 9 9 10 # CM CM
+10 10 10 11 # CM CM
+11 11 11 12 # CM CM
+12 12 12 13 # CM CT
+13 1 14 15 # HG CM
+14 2 15 16 # CM CM
+15 3 16 17 # CM CM
+16 4 17 18 # CM CM
+17 5 18 19 # CM CM
+18 6 19 20 # CM CM
+19 7 20 21 # CM CM
+20 8 21 22 # CM CM
+21 9 22 23 # CM CM
+22 10 23 24 # CM CM
+23 11 24 25 # CM CM
+24 12 25 26 # CM CT
+25 1 27 28 # HG CM
+26 2 28 29 # CM CM
+27 3 29 30 # CM CM
+28 4 30 31 # CM CM
+29 5 31 32 # CM CM
+30 6 32 33 # CM CM
+31 7 33 34 # CM CM
+32 8 34 35 # CM CM
+33 9 35 36 # CM CM
+34 10 36 37 # CM CM
+35 11 37 38 # CM CM
+36 12 38 39 # CM CT
+37 1 40 41 # HG CM
+38 2 41 42 # CM CM
+39 3 42 43 # CM CM
+40 4 43 44 # CM CM
+41 5 44 45 # CM CM
+42 6 45 46 # CM CM
+43 7 46 47 # CM CM
+44 8 47 48 # CM CM
+45 9 48 49 # CM CM
+46 10 49 50 # CM CM
+47 11 50 51 # CM CM
+48 12 51 52 # CM CT
+49 1 53 54 # HG CM
+50 2 54 55 # CM CM
+51 3 55 56 # CM CM
+52 4 56 57 # CM CM
+53 5 57 58 # CM CM
+54 6 58 59 # CM CM
+55 7 59 60 # CM CM
+56 8 60 61 # CM CM
+57 9 61 62 # CM CM
+58 10 62 63 # CM CM
+59 11 63 64 # CM CM
+60 12 64 65 # CM CT
+61 1 66 67 # HG CM
+62 2 67 68 # CM CM
+63 3 68 69 # CM CM
+64 4 69 70 # CM CM
+65 5 70 71 # CM CM
+66 6 71 72 # CM CM
+67 7 72 73 # CM CM
+68 8 73 74 # CM CM
+69 9 74 75 # CM CM
+70 10 75 76 # CM CM
+71 11 76 77 # CM CM
+72 12 77 78 # CM CT
+73 1 79 80 # HG CM
+74 2 80 81 # CM CM
+75 3 81 82 # CM CM
+76 4 82 83 # CM CM
+77 5 83 84 # CM CM
+78 6 84 85 # CM CM
+79 7 85 86 # CM CM
+80 8 86 87 # CM CM
+81 9 87 88 # CM CM
+82 10 88 89 # CM CM
+83 11 89 90 # CM CM
+84 12 90 91 # CM CT
+85 1 92 93 # HG CM
+86 2 93 94 # CM CM
+87 3 94 95 # CM CM
+88 4 95 96 # CM CM
+89 5 96 97 # CM CM
+90 6 97 98 # CM CM
+91 7 98 99 # CM CM
+92 8 99 100 # CM CM
+93 9 100 101 # CM CM
+94 10 101 102 # CM CM
+95 11 102 103 # CM CM
+96 12 103 104 # CM CT
+97 1 105 106 # HG CM
+98 2 106 107 # CM CM
+99 3 107 108 # CM CM
+100 4 108 109 # CM CM
+101 5 109 110 # CM CM
+102 6 110 111 # CM CM
+103 7 111 112 # CM CM
+104 8 112 113 # CM CM
+105 9 113 114 # CM CM
+106 10 114 115 # CM CM
+107 11 115 116 # CM CM
+108 12 116 117 # CM CT
+109 1 118 119 # HG CM
+110 2 119 120 # CM CM
+111 3 120 121 # CM CM
+112 4 121 122 # CM CM
+113 5 122 123 # CM CM
+114 6 123 124 # CM CM
+115 7 124 125 # CM CM
+116 8 125 126 # CM CM
+117 9 126 127 # CM CM
+118 10 127 128 # CM CM
+119 11 128 129 # CM CM
+120 12 129 130 # CM CT
+121 1 131 132 # HG CM
+122 2 132 133 # CM CM
+123 3 133 134 # CM CM
+124 4 134 135 # CM CM
+125 5 135 136 # CM CM
+126 6 136 137 # CM CM
+127 7 137 138 # CM CM
+128 8 138 139 # CM CM
+129 9 139 140 # CM CM
+130 10 140 141 # CM CM
+131 11 141 142 # CM CM
+132 12 142 143 # CM CT
+133 1 144 145 # HG CM
+134 2 145 146 # CM CM
+135 3 146 147 # CM CM
+136 4 147 148 # CM CM
+137 5 148 149 # CM CM
+138 6 149 150 # CM CM
+139 7 150 151 # CM CM
+140 8 151 152 # CM CM
+141 9 152 153 # CM CM
+142 10 153 154 # CM CM
+143 11 154 155 # CM CM
+144 12 155 156 # CM CT
+145 1 157 158 # HG CM
+146 2 158 159 # CM CM
+147 3 159 160 # CM CM
+148 4 160 161 # CM CM
+149 5 161 162 # CM CM
+150 6 162 163 # CM CM
+151 7 163 164 # CM CM
+152 8 164 165 # CM CM
+153 9 165 166 # CM CM
+154 10 166 167 # CM CM
+155 11 167 168 # CM CM
+156 12 168 169 # CM CT
+157 1 170 171 # HG CM
+158 2 171 172 # CM CM
+159 3 172 173 # CM CM
+160 4 173 174 # CM CM
+161 5 174 175 # CM CM
+162 6 175 176 # CM CM
+163 7 176 177 # CM CM
+164 8 177 178 # CM CM
+165 9 178 179 # CM CM
+166 10 179 180 # CM CM
+167 11 180 181 # CM CM
+168 12 181 182 # CM CT
+169 1 183 184 # HG CM
+170 2 184 185 # CM CM
+171 3 185 186 # CM CM
+172 4 186 187 # CM CM
+173 5 187 188 # CM CM
+174 6 188 189 # CM CM
+175 7 189 190 # CM CM
+176 8 190 191 # CM CM
+177 9 191 192 # CM CM
+178 10 192 193 # CM CM
+179 11 193 194 # CM CM
+180 12 194 195 # CM CT
+181 1 196 197 # HG CM
+182 2 197 198 # CM CM
+183 3 198 199 # CM CM
+184 4 199 200 # CM CM
+185 5 200 201 # CM CM
+186 6 201 202 # CM CM
+187 7 202 203 # CM CM
+188 8 203 204 # CM CM
+189 9 204 205 # CM CM
+190 10 205 206 # CM CM
+191 11 206 207 # CM CM
+192 12 207 208 # CM CT
+193 1 209 210 # HG CM
+194 2 210 211 # CM CM
+195 3 211 212 # CM CM
+196 4 212 213 # CM CM
+197 5 213 214 # CM CM
+198 6 214 215 # CM CM
+199 7 215 216 # CM CM
+200 8 216 217 # CM CM
+201 9 217 218 # CM CM
+202 10 218 219 # CM CM
+203 11 219 220 # CM CM
+204 12 220 221 # CM CT
+205 1 222 223 # HG CM
+206 2 223 224 # CM CM
+207 3 224 225 # CM CM
+208 4 225 226 # CM CM
+209 5 226 227 # CM CM
+210 6 227 228 # CM CM
+211 7 228 229 # CM CM
+212 8 229 230 # CM CM
+213 9 230 231 # CM CM
+214 10 231 232 # CM CM
+215 11 232 233 # CM CM
+216 12 233 234 # CM CT
+217 1 235 236 # HG CM
+218 2 236 237 # CM CM
+219 3 237 238 # CM CM
+220 4 238 239 # CM CM
+221 5 239 240 # CM CM
+222 6 240 241 # CM CM
+223 7 241 242 # CM CM
+224 8 242 243 # CM CM
+225 9 243 244 # CM CM
+226 10 244 245 # CM CM
+227 11 245 246 # CM CM
+228 12 246 247 # CM CT
+229 1 248 249 # HG CM
+230 2 249 250 # CM CM
+231 3 250 251 # CM CM
+232 4 251 252 # CM CM
+233 5 252 253 # CM CM
+234 6 253 254 # CM CM
+235 7 254 255 # CM CM
+236 8 255 256 # CM CM
+237 9 256 257 # CM CM
+238 10 257 258 # CM CM
+239 11 258 259 # CM CM
+240 12 259 260 # CM CT
+241 1 261 262 # HG CM
+242 2 262 263 # CM CM
+243 3 263 264 # CM CM
+244 4 264 265 # CM CM
+245 5 265 266 # CM CM
+246 6 266 267 # CM CM
+247 7 267 268 # CM CM
+248 8 268 269 # CM CM
+249 9 269 270 # CM CM
+250 10 270 271 # CM CM
+251 11 271 272 # CM CM
+252 12 272 273 # CM CT
+253 1 274 275 # HG CM
+254 2 275 276 # CM CM
+255 3 276 277 # CM CM
+256 4 277 278 # CM CM
+257 5 278 279 # CM CM
+258 6 279 280 # CM CM
+259 7 280 281 # CM CM
+260 8 281 282 # CM CM
+261 9 282 283 # CM CM
+262 10 283 284 # CM CM
+263 11 284 285 # CM CM
+264 12 285 286 # CM CT
+265 1 287 288 # HG CM
+266 2 288 289 # CM CM
+267 3 289 290 # CM CM
+268 4 290 291 # CM CM
+269 5 291 292 # CM CM
+270 6 292 293 # CM CM
+271 7 293 294 # CM CM
+272 8 294 295 # CM CM
+273 9 295 296 # CM CM
+274 10 296 297 # CM CM
+275 11 297 298 # CM CM
+276 12 298 299 # CM CT
+277 1 300 301 # HG CM
+278 2 301 302 # CM CM
+279 3 302 303 # CM CM
+280 4 303 304 # CM CM
+281 5 304 305 # CM CM
+282 6 305 306 # CM CM
+283 7 306 307 # CM CM
+284 8 307 308 # CM CM
+285 9 308 309 # CM CM
+286 10 309 310 # CM CM
+287 11 310 311 # CM CM
+288 12 311 312 # CM CT
+289 1 313 314 # HG CM
+290 2 314 315 # CM CM
+291 3 315 316 # CM CM
+292 4 316 317 # CM CM
+293 5 317 318 # CM CM
+294 6 318 319 # CM CM
+295 7 319 320 # CM CM
+296 8 320 321 # CM CM
+297 9 321 322 # CM CM
+298 10 322 323 # CM CM
+299 11 323 324 # CM CM
+300 12 324 325 # CM CT
+301 1 326 327 # HG CM
+302 2 327 328 # CM CM
+303 3 328 329 # CM CM
+304 4 329 330 # CM CM
+305 5 330 331 # CM CM
+306 6 331 332 # CM CM
+307 7 332 333 # CM CM
+308 8 333 334 # CM CM
+309 9 334 335 # CM CM
+310 10 335 336 # CM CM
+311 11 336 337 # CM CM
+312 12 337 338 # CM CT
+313 1 339 340 # HG CM
+314 2 340 341 # CM CM
+315 3 341 342 # CM CM
+316 4 342 343 # CM CM
+317 5 343 344 # CM CM
+318 6 344 345 # CM CM
+319 7 345 346 # CM CM
+320 8 346 347 # CM CM
+321 9 347 348 # CM CM
+322 10 348 349 # CM CM
+323 11 349 350 # CM CM
+324 12 350 351 # CM CT
+325 1 352 353 # HG CM
+326 2 353 354 # CM CM
+327 3 354 355 # CM CM
+328 4 355 356 # CM CM
+329 5 356 357 # CM CM
+330 6 357 358 # CM CM
+331 7 358 359 # CM CM
+332 8 359 360 # CM CM
+333 9 360 361 # CM CM
+334 10 361 362 # CM CM
+335 11 362 363 # CM CM
+336 12 363 364 # CM CT
+337 1 365 366 # HG CM
+338 2 366 367 # CM CM
+339 3 367 368 # CM CM
+340 4 368 369 # CM CM
+341 5 369 370 # CM CM
+342 6 370 371 # CM CM
+343 7 371 372 # CM CM
+344 8 372 373 # CM CM
+345 9 373 374 # CM CM
+346 10 374 375 # CM CM
+347 11 375 376 # CM CM
+348 12 376 377 # CM CT
+349 1 378 379 # HG CM
+350 2 379 380 # CM CM
+351 3 380 381 # CM CM
+352 4 381 382 # CM CM
+353 5 382 383 # CM CM
+354 6 383 384 # CM CM
+355 7 384 385 # CM CM
+356 8 385 386 # CM CM
+357 9 386 387 # CM CM
+358 10 387 388 # CM CM
+359 11 388 389 # CM CM
+360 12 389 390 # CM CT
+361 1 391 392 # HG CM
+362 2 392 393 # CM CM
+363 3 393 394 # CM CM
+364 4 394 395 # CM CM
+365 5 395 396 # CM CM
+366 6 396 397 # CM CM
+367 7 397 398 # CM CM
+368 8 398 399 # CM CM
+369 9 399 400 # CM CM
+370 10 400 401 # CM CM
+371 11 401 402 # CM CM
+372 12 402 403 # CM CT
+373 1 404 405 # HG CM
+374 2 405 406 # CM CM
+375 3 406 407 # CM CM
+376 4 407 408 # CM CM
+377 5 408 409 # CM CM
+378 6 409 410 # CM CM
+379 7 410 411 # CM CM
+380 8 411 412 # CM CM
+381 9 412 413 # CM CM
+382 10 413 414 # CM CM
+383 11 414 415 # CM CM
+384 12 415 416 # CM CT
+385 1 417 418 # HG CM
+386 2 418 419 # CM CM
+387 3 419 420 # CM CM
+388 4 420 421 # CM CM
+389 5 421 422 # CM CM
+390 6 422 423 # CM CM
+391 7 423 424 # CM CM
+392 8 424 425 # CM CM
+393 9 425 426 # CM CM
+394 10 426 427 # CM CM
+395 11 427 428 # CM CM
+396 12 428 429 # CM CT
+397 1 430 431 # HG CM
+398 2 431 432 # CM CM
+399 3 432 433 # CM CM
+400 4 433 434 # CM CM
+401 5 434 435 # CM CM
+402 6 435 436 # CM CM
+403 7 436 437 # CM CM
+404 8 437 438 # CM CM
+405 9 438 439 # CM CM
+406 10 439 440 # CM CM
+407 11 440 441 # CM CM
+408 12 441 442 # CM CT
+409 1 443 444 # HG CM
+410 2 444 445 # CM CM
+411 3 445 446 # CM CM
+412 4 446 447 # CM CM
+413 5 447 448 # CM CM
+414 6 448 449 # CM CM
+415 7 449 450 # CM CM
+416 8 450 451 # CM CM
+417 9 451 452 # CM CM
+418 10 452 453 # CM CM
+419 11 453 454 # CM CM
+420 12 454 455 # CM CT
+421 1 456 457 # HG CM
+422 2 457 458 # CM CM
+423 3 458 459 # CM CM
+424 4 459 460 # CM CM
+425 5 460 461 # CM CM
+426 6 461 462 # CM CM
+427 7 462 463 # CM CM
+428 8 463 464 # CM CM
+429 9 464 465 # CM CM
+430 10 465 466 # CM CM
+431 11 466 467 # CM CM
+432 12 467 468 # CM CT
+433 1 469 470 # HG CM
+434 2 470 471 # CM CM
+435 3 471 472 # CM CM
+436 4 472 473 # CM CM
+437 5 473 474 # CM CM
+438 6 474 475 # CM CM
+439 7 475 476 # CM CM
+440 8 476 477 # CM CM
+441 9 477 478 # CM CM
+442 10 478 479 # CM CM
+443 11 479 480 # CM CM
+444 12 480 481 # CM CT
+445 1 482 483 # HG CM
+446 2 483 484 # CM CM
+447 3 484 485 # CM CM
+448 4 485 486 # CM CM
+449 5 486 487 # CM CM
+450 6 487 488 # CM CM
+451 7 488 489 # CM CM
+452 8 489 490 # CM CM
+453 9 490 491 # CM CM
+454 10 491 492 # CM CM
+455 11 492 493 # CM CM
+456 12 493 494 # CM CT
+457 1 495 496 # HG CM
+458 2 496 497 # CM CM
+459 3 497 498 # CM CM
+460 4 498 499 # CM CM
+461 5 499 500 # CM CM
+462 6 500 501 # CM CM
+463 7 501 502 # CM CM
+464 8 502 503 # CM CM
+465 9 503 504 # CM CM
+466 10 504 505 # CM CM
+467 11 505 506 # CM CM
+468 12 506 507 # CM CT
+469 1 508 509 # HG CM
+470 2 509 510 # CM CM
+471 3 510 511 # CM CM
+472 4 511 512 # CM CM
+473 5 512 513 # CM CM
+474 6 513 514 # CM CM
+475 7 514 515 # CM CM
+476 8 515 516 # CM CM
+477 9 516 517 # CM CM
+478 10 517 518 # CM CM
+479 11 518 519 # CM CM
+480 12 519 520 # CM CT
+481 1 521 522 # HG CM
+482 2 522 523 # CM CM
+483 3 523 524 # CM CM
+484 4 524 525 # CM CM
+485 5 525 526 # CM CM
+486 6 526 527 # CM CM
+487 7 527 528 # CM CM
+488 8 528 529 # CM CM
+489 9 529 530 # CM CM
+490 10 530 531 # CM CM
+491 11 531 532 # CM CM
+492 12 532 533 # CM CT
+493 1 534 535 # HG CM
+494 2 535 536 # CM CM
+495 3 536 537 # CM CM
+496 4 537 538 # CM CM
+497 5 538 539 # CM CM
+498 6 539 540 # CM CM
+499 7 540 541 # CM CM
+500 8 541 542 # CM CM
+501 9 542 543 # CM CM
+502 10 543 544 # CM CM
+503 11 544 545 # CM CM
+504 12 545 546 # CM CT
+505 1 547 548 # HG CM
+506 2 548 549 # CM CM
+507 3 549 550 # CM CM
+508 4 550 551 # CM CM
+509 5 551 552 # CM CM
+510 6 552 553 # CM CM
+511 7 553 554 # CM CM
+512 8 554 555 # CM CM
+513 9 555 556 # CM CM
+514 10 556 557 # CM CM
+515 11 557 558 # CM CM
+516 12 558 559 # CM CT
+517 1 560 561 # HG CM
+518 2 561 562 # CM CM
+519 3 562 563 # CM CM
+520 4 563 564 # CM CM
+521 5 564 565 # CM CM
+522 6 565 566 # CM CM
+523 7 566 567 # CM CM
+524 8 567 568 # CM CM
+525 9 568 569 # CM CM
+526 10 569 570 # CM CM
+527 11 570 571 # CM CM
+528 12 571 572 # CM CT
+529 1 573 574 # HG CM
+530 2 574 575 # CM CM
+531 3 575 576 # CM CM
+532 4 576 577 # CM CM
+533 5 577 578 # CM CM
+534 6 578 579 # CM CM
+535 7 579 580 # CM CM
+536 8 580 581 # CM CM
+537 9 581 582 # CM CM
+538 10 582 583 # CM CM
+539 11 583 584 # CM CM
+540 12 584 585 # CM CT
+541 1 586 587 # HG CM
+542 2 587 588 # CM CM
+543 3 588 589 # CM CM
+544 4 589 590 # CM CM
+545 5 590 591 # CM CM
+546 6 591 592 # CM CM
+547 7 592 593 # CM CM
+548 8 593 594 # CM CM
+549 9 594 595 # CM CM
+550 10 595 596 # CM CM
+551 11 596 597 # CM CM
+552 12 597 598 # CM CT
+553 1 599 600 # HG CM
+554 2 600 601 # CM CM
+555 3 601 602 # CM CM
+556 4 602 603 # CM CM
+557 5 603 604 # CM CM
+558 6 604 605 # CM CM
+559 7 605 606 # CM CM
+560 8 606 607 # CM CM
+561 9 607 608 # CM CM
+562 10 608 609 # CM CM
+563 11 609 610 # CM CM
+564 12 610 611 # CM CT
+565 1 612 613 # HG CM
+566 2 613 614 # CM CM
+567 3 614 615 # CM CM
+568 4 615 616 # CM CM
+569 5 616 617 # CM CM
+570 6 617 618 # CM CM
+571 7 618 619 # CM CM
+572 8 619 620 # CM CM
+573 9 620 621 # CM CM
+574 10 621 622 # CM CM
+575 11 622 623 # CM CM
+576 12 623 624 # CM CT
+577 1 625 626 # HG CM
+578 2 626 627 # CM CM
+579 3 627 628 # CM CM
+580 4 628 629 # CM CM
+581 5 629 630 # CM CM
+582 6 630 631 # CM CM
+583 7 631 632 # CM CM
+584 8 632 633 # CM CM
+585 9 633 634 # CM CM
+586 10 634 635 # CM CM
+587 11 635 636 # CM CM
+588 12 636 637 # CM CT
+589 1 638 639 # HG CM
+590 2 639 640 # CM CM
+591 3 640 641 # CM CM
+592 4 641 642 # CM CM
+593 5 642 643 # CM CM
+594 6 643 644 # CM CM
+595 7 644 645 # CM CM
+596 8 645 646 # CM CM
+597 9 646 647 # CM CM
+598 10 647 648 # CM CM
+599 11 648 649 # CM CM
+600 12 649 650 # CM CT
+601 1 651 652 # HG CM
+602 2 652 653 # CM CM
+603 3 653 654 # CM CM
+604 4 654 655 # CM CM
+605 5 655 656 # CM CM
+606 6 656 657 # CM CM
+607 7 657 658 # CM CM
+608 8 658 659 # CM CM
+609 9 659 660 # CM CM
+610 10 660 661 # CM CM
+611 11 661 662 # CM CM
+612 12 662 663 # CM CT
+613 1 664 665 # HG CM
+614 2 665 666 # CM CM
+615 3 666 667 # CM CM
+616 4 667 668 # CM CM
+617 5 668 669 # CM CM
+618 6 669 670 # CM CM
+619 7 670 671 # CM CM
+620 8 671 672 # CM CM
+621 9 672 673 # CM CM
+622 10 673 674 # CM CM
+623 11 674 675 # CM CM
+624 12 675 676 # CM CT
+625 1 677 678 # HG CM
+626 2 678 679 # CM CM
+627 3 679 680 # CM CM
+628 4 680 681 # CM CM
+629 5 681 682 # CM CM
+630 6 682 683 # CM CM
+631 7 683 684 # CM CM
+632 8 684 685 # CM CM
+633 9 685 686 # CM CM
+634 10 686 687 # CM CM
+635 11 687 688 # CM CM
+636 12 688 689 # CM CT
+637 1 690 691 # HG CM
+638 2 691 692 # CM CM
+639 3 692 693 # CM CM
+640 4 693 694 # CM CM
+641 5 694 695 # CM CM
+642 6 695 696 # CM CM
+643 7 696 697 # CM CM
+644 8 697 698 # CM CM
+645 9 698 699 # CM CM
+646 10 699 700 # CM CM
+647 11 700 701 # CM CM
+648 12 701 702 # CM CT
+649 1 703 704 # HG CM
+650 2 704 705 # CM CM
+651 3 705 706 # CM CM
+652 4 706 707 # CM CM
+653 5 707 708 # CM CM
+654 6 708 709 # CM CM
+655 7 709 710 # CM CM
+656 8 710 711 # CM CM
+657 9 711 712 # CM CM
+658 10 712 713 # CM CM
+659 11 713 714 # CM CM
+660 12 714 715 # CM CT
+661 1 716 717 # HG CM
+662 2 717 718 # CM CM
+663 3 718 719 # CM CM
+664 4 719 720 # CM CM
+665 5 720 721 # CM CM
+666 6 721 722 # CM CM
+667 7 722 723 # CM CM
+668 8 723 724 # CM CM
+669 9 724 725 # CM CM
+670 10 725 726 # CM CM
+671 11 726 727 # CM CM
+672 12 727 728 # CM CT
+673 1 729 730 # HG CM
+674 2 730 731 # CM CM
+675 3 731 732 # CM CM
+676 4 732 733 # CM CM
+677 5 733 734 # CM CM
+678 6 734 735 # CM CM
+679 7 735 736 # CM CM
+680 8 736 737 # CM CM
+681 9 737 738 # CM CM
+682 10 738 739 # CM CM
+683 11 739 740 # CM CM
+684 12 740 741 # CM CT
+685 1 742 743 # HG CM
+686 2 743 744 # CM CM
+687 3 744 745 # CM CM
+688 4 745 746 # CM CM
+689 5 746 747 # CM CM
+690 6 747 748 # CM CM
+691 7 748 749 # CM CM
+692 8 749 750 # CM CM
+693 9 750 751 # CM CM
+694 10 751 752 # CM CM
+695 11 752 753 # CM CM
+696 12 753 754 # CM CT
+697 1 755 756 # HG CM
+698 2 756 757 # CM CM
+699 3 757 758 # CM CM
+700 4 758 759 # CM CM
+701 5 759 760 # CM CM
+702 6 760 761 # CM CM
+703 7 761 762 # CM CM
+704 8 762 763 # CM CM
+705 9 763 764 # CM CM
+706 10 764 765 # CM CM
+707 11 765 766 # CM CM
+708 12 766 767 # CM CT
+709 1 768 769 # HG CM
+710 2 769 770 # CM CM
+711 3 770 771 # CM CM
+712 4 771 772 # CM CM
+713 5 772 773 # CM CM
+714 6 773 774 # CM CM
+715 7 774 775 # CM CM
+716 8 775 776 # CM CM
+717 9 776 777 # CM CM
+718 10 777 778 # CM CM
+719 11 778 779 # CM CM
+720 12 779 780 # CM CT
+721 1 781 782 # HG CM
+722 2 782 783 # CM CM
+723 3 783 784 # CM CM
+724 4 784 785 # CM CM
+725 5 785 786 # CM CM
+726 6 786 787 # CM CM
+727 7 787 788 # CM CM
+728 8 788 789 # CM CM
+729 9 789 790 # CM CM
+730 10 790 791 # CM CM
+731 11 791 792 # CM CM
+732 12 792 793 # CM CT
+733 1 794 795 # HG CM
+734 2 795 796 # CM CM
+735 3 796 797 # CM CM
+736 4 797 798 # CM CM
+737 5 798 799 # CM CM
+738 6 799 800 # CM CM
+739 7 800 801 # CM CM
+740 8 801 802 # CM CM
+741 9 802 803 # CM CM
+742 10 803 804 # CM CM
+743 11 804 805 # CM CM
+744 12 805 806 # CM CT
+745 1 807 808 # HG CM
+746 2 808 809 # CM CM
+747 3 809 810 # CM CM
+748 4 810 811 # CM CM
+749 5 811 812 # CM CM
+750 6 812 813 # CM CM
+751 7 813 814 # CM CM
+752 8 814 815 # CM CM
+753 9 815 816 # CM CM
+754 10 816 817 # CM CM
+755 11 817 818 # CM CM
+756 12 818 819 # CM CT
+757 1 820 821 # HG CM
+758 2 821 822 # CM CM
+759 3 822 823 # CM CM
+760 4 823 824 # CM CM
+761 5 824 825 # CM CM
+762 6 825 826 # CM CM
+763 7 826 827 # CM CM
+764 8 827 828 # CM CM
+765 9 828 829 # CM CM
+766 10 829 830 # CM CM
+767 11 830 831 # CM CM
+768 12 831 832 # CM CT
+769 1 833 834 # HG CM
+770 2 834 835 # CM CM
+771 3 835 836 # CM CM
+772 4 836 837 # CM CM
+773 5 837 838 # CM CM
+774 6 838 839 # CM CM
+775 7 839 840 # CM CM
+776 8 840 841 # CM CM
+777 9 841 842 # CM CM
+778 10 842 843 # CM CM
+779 11 843 844 # CM CM
+780 12 844 845 # CM CT
+781 1 846 847 # HG CM
+782 2 847 848 # CM CM
+783 3 848 849 # CM CM
+784 4 849 850 # CM CM
+785 5 850 851 # CM CM
+786 6 851 852 # CM CM
+787 7 852 853 # CM CM
+788 8 853 854 # CM CM
+789 9 854 855 # CM CM
+790 10 855 856 # CM CM
+791 11 856 857 # CM CM
+792 12 857 858 # CM CT
+793 1 859 860 # HG CM
+794 2 860 861 # CM CM
+795 3 861 862 # CM CM
+796 4 862 863 # CM CM
+797 5 863 864 # CM CM
+798 6 864 865 # CM CM
+799 7 865 866 # CM CM
+800 8 866 867 # CM CM
+801 9 867 868 # CM CM
+802 10 868 869 # CM CM
+803 11 869 870 # CM CM
+804 12 870 871 # CM CT
+805 1 872 873 # HG CM
+806 2 873 874 # CM CM
+807 3 874 875 # CM CM
+808 4 875 876 # CM CM
+809 5 876 877 # CM CM
+810 6 877 878 # CM CM
+811 7 878 879 # CM CM
+812 8 879 880 # CM CM
+813 9 880 881 # CM CM
+814 10 881 882 # CM CM
+815 11 882 883 # CM CM
+816 12 883 884 # CM CT
+817 1 885 886 # HG CM
+818 2 886 887 # CM CM
+819 3 887 888 # CM CM
+820 4 888 889 # CM CM
+821 5 889 890 # CM CM
+822 6 890 891 # CM CM
+823 7 891 892 # CM CM
+824 8 892 893 # CM CM
+825 9 893 894 # CM CM
+826 10 894 895 # CM CM
+827 11 895 896 # CM CM
+828 12 896 897 # CM CT
+829 1 898 899 # HG CM
+830 2 899 900 # CM CM
+831 3 900 901 # CM CM
+832 4 901 902 # CM CM
+833 5 902 903 # CM CM
+834 6 903 904 # CM CM
+835 7 904 905 # CM CM
+836 8 905 906 # CM CM
+837 9 906 907 # CM CM
+838 10 907 908 # CM CM
+839 11 908 909 # CM CM
+840 12 909 910 # CM CT
+841 1 911 912 # HG CM
+842 2 912 913 # CM CM
+843 3 913 914 # CM CM
+844 4 914 915 # CM CM
+845 5 915 916 # CM CM
+846 6 916 917 # CM CM
+847 7 917 918 # CM CM
+848 8 918 919 # CM CM
+849 9 919 920 # CM CM
+850 10 920 921 # CM CM
+851 11 921 922 # CM CM
+852 12 922 923 # CM CT
+853 1 924 925 # HG CM
+854 2 925 926 # CM CM
+855 3 926 927 # CM CM
+856 4 927 928 # CM CM
+857 5 928 929 # CM CM
+858 6 929 930 # CM CM
+859 7 930 931 # CM CM
+860 8 931 932 # CM CM
+861 9 932 933 # CM CM
+862 10 933 934 # CM CM
+863 11 934 935 # CM CM
+864 12 935 936 # CM CT
+865 1 937 938 # HG CM
+866 2 938 939 # CM CM
+867 3 939 940 # CM CM
+868 4 940 941 # CM CM
+869 5 941 942 # CM CM
+870 6 942 943 # CM CM
+871 7 943 944 # CM CM
+872 8 944 945 # CM CM
+873 9 945 946 # CM CM
+874 10 946 947 # CM CM
+875 11 947 948 # CM CM
+876 12 948 949 # CM CT
+877 1 950 951 # HG CM
+878 2 951 952 # CM CM
+879 3 952 953 # CM CM
+880 4 953 954 # CM CM
+881 5 954 955 # CM CM
+882 6 955 956 # CM CM
+883 7 956 957 # CM CM
+884 8 957 958 # CM CM
+885 9 958 959 # CM CM
+886 10 959 960 # CM CM
+887 11 960 961 # CM CM
+888 12 961 962 # CM CT
+889 1 963 964 # HG CM
+890 2 964 965 # CM CM
+891 3 965 966 # CM CM
+892 4 966 967 # CM CM
+893 5 967 968 # CM CM
+894 6 968 969 # CM CM
+895 7 969 970 # CM CM
+896 8 970 971 # CM CM
+897 9 971 972 # CM CM
+898 10 972 973 # CM CM
+899 11 973 974 # CM CM
+900 12 974 975 # CM CT
+901 1 976 977 # HG CM
+902 2 977 978 # CM CM
+903 3 978 979 # CM CM
+904 4 979 980 # CM CM
+905 5 980 981 # CM CM
+906 6 981 982 # CM CM
+907 7 982 983 # CM CM
+908 8 983 984 # CM CM
+909 9 984 985 # CM CM
+910 10 985 986 # CM CM
+911 11 986 987 # CM CM
+912 12 987 988 # CM CT
+913 1 989 990 # HG CM
+914 2 990 991 # CM CM
+915 3 991 992 # CM CM
+916 4 992 993 # CM CM
+917 5 993 994 # CM CM
+918 6 994 995 # CM CM
+919 7 995 996 # CM CM
+920 8 996 997 # CM CM
+921 9 997 998 # CM CM
+922 10 998 999 # CM CM
+923 11 999 1000 # CM CM
+924 12 1000 1001 # CM CT
+925 1 1002 1003 # HG CM
+926 2 1003 1004 # CM CM
+927 3 1004 1005 # CM CM
+928 4 1005 1006 # CM CM
+929 5 1006 1007 # CM CM
+930 6 1007 1008 # CM CM
+931 7 1008 1009 # CM CM
+932 8 1009 1010 # CM CM
+933 9 1010 1011 # CM CM
+934 10 1011 1012 # CM CM
+935 11 1012 1013 # CM CM
+936 12 1013 1014 # CM CT
+937 1 1015 1016 # HG CM
+938 2 1016 1017 # CM CM
+939 3 1017 1018 # CM CM
+940 4 1018 1019 # CM CM
+941 5 1019 1020 # CM CM
+942 6 1020 1021 # CM CM
+943 7 1021 1022 # CM CM
+944 8 1022 1023 # CM CM
+945 9 1023 1024 # CM CM
+946 10 1024 1025 # CM CM
+947 11 1025 1026 # CM CM
+948 12 1026 1027 # CM CT
+949 1 1028 1029 # HG CM
+950 2 1029 1030 # CM CM
+951 3 1030 1031 # CM CM
+952 4 1031 1032 # CM CM
+953 5 1032 1033 # CM CM
+954 6 1033 1034 # CM CM
+955 7 1034 1035 # CM CM
+956 8 1035 1036 # CM CM
+957 9 1036 1037 # CM CM
+958 10 1037 1038 # CM CM
+959 11 1038 1039 # CM CM
+960 12 1039 1040 # CM CT
+961 1 1041 1042 # HG CM
+962 2 1042 1043 # CM CM
+963 3 1043 1044 # CM CM
+964 4 1044 1045 # CM CM
+965 5 1045 1046 # CM CM
+966 6 1046 1047 # CM CM
+967 7 1047 1048 # CM CM
+968 8 1048 1049 # CM CM
+969 9 1049 1050 # CM CM
+970 10 1050 1051 # CM CM
+971 11 1051 1052 # CM CM
+972 12 1052 1053 # CM CT
+973 1 1054 1055 # HG CM
+974 2 1055 1056 # CM CM
+975 3 1056 1057 # CM CM
+976 4 1057 1058 # CM CM
+977 5 1058 1059 # CM CM
+978 6 1059 1060 # CM CM
+979 7 1060 1061 # CM CM
+980 8 1061 1062 # CM CM
+981 9 1062 1063 # CM CM
+982 10 1063 1064 # CM CM
+983 11 1064 1065 # CM CM
+984 12 1065 1066 # CM CT
+985 1 1067 1068 # HG CM
+986 2 1068 1069 # CM CM
+987 3 1069 1070 # CM CM
+988 4 1070 1071 # CM CM
+989 5 1071 1072 # CM CM
+990 6 1072 1073 # CM CM
+991 7 1073 1074 # CM CM
+992 8 1074 1075 # CM CM
+993 9 1075 1076 # CM CM
+994 10 1076 1077 # CM CM
+995 11 1077 1078 # CM CM
+996 12 1078 1079 # CM CT
+997 1 1080 1081 # HG CM
+998 2 1081 1082 # CM CM
+999 3 1082 1083 # CM CM
+1000 4 1083 1084 # CM CM
+1001 5 1084 1085 # CM CM
+1002 6 1085 1086 # CM CM
+1003 7 1086 1087 # CM CM
+1004 8 1087 1088 # CM CM
+1005 9 1088 1089 # CM CM
+1006 10 1089 1090 # CM CM
+1007 11 1090 1091 # CM CM
+1008 12 1091 1092 # CM CT
+1009 1 1093 1094 # HG CM
+1010 2 1094 1095 # CM CM
+1011 3 1095 1096 # CM CM
+1012 4 1096 1097 # CM CM
+1013 5 1097 1098 # CM CM
+1014 6 1098 1099 # CM CM
+1015 7 1099 1100 # CM CM
+1016 8 1100 1101 # CM CM
+1017 9 1101 1102 # CM CM
+1018 10 1102 1103 # CM CM
+1019 11 1103 1104 # CM CM
+1020 12 1104 1105 # CM CT
+1021 1 1106 1107 # HG CM
+1022 2 1107 1108 # CM CM
+1023 3 1108 1109 # CM CM
+1024 4 1109 1110 # CM CM
+1025 5 1110 1111 # CM CM
+1026 6 1111 1112 # CM CM
+1027 7 1112 1113 # CM CM
+1028 8 1113 1114 # CM CM
+1029 9 1114 1115 # CM CM
+1030 10 1115 1116 # CM CM
+1031 11 1116 1117 # CM CM
+1032 12 1117 1118 # CM CT
+1033 1 1119 1120 # HG CM
+1034 2 1120 1121 # CM CM
+1035 3 1121 1122 # CM CM
+1036 4 1122 1123 # CM CM
+1037 5 1123 1124 # CM CM
+1038 6 1124 1125 # CM CM
+1039 7 1125 1126 # CM CM
+1040 8 1126 1127 # CM CM
+1041 9 1127 1128 # CM CM
+1042 10 1128 1129 # CM CM
+1043 11 1129 1130 # CM CM
+1044 12 1130 1131 # CM CT
+1045 1 1132 1133 # HG CM
+1046 2 1133 1134 # CM CM
+1047 3 1134 1135 # CM CM
+1048 4 1135 1136 # CM CM
+1049 5 1136 1137 # CM CM
+1050 6 1137 1138 # CM CM
+1051 7 1138 1139 # CM CM
+1052 8 1139 1140 # CM CM
+1053 9 1140 1141 # CM CM
+1054 10 1141 1142 # CM CM
+1055 11 1142 1143 # CM CM
+1056 12 1143 1144 # CM CT
+1057 1 1145 1146 # HG CM
+1058 2 1146 1147 # CM CM
+1059 3 1147 1148 # CM CM
+1060 4 1148 1149 # CM CM
+1061 5 1149 1150 # CM CM
+1062 6 1150 1151 # CM CM
+1063 7 1151 1152 # CM CM
+1064 8 1152 1153 # CM CM
+1065 9 1153 1154 # CM CM
+1066 10 1154 1155 # CM CM
+1067 11 1155 1156 # CM CM
+1068 12 1156 1157 # CM CT
+1069 1 1158 1159 # HG CM
+1070 2 1159 1160 # CM CM
+1071 3 1160 1161 # CM CM
+1072 4 1161 1162 # CM CM
+1073 5 1162 1163 # CM CM
+1074 6 1163 1164 # CM CM
+1075 7 1164 1165 # CM CM
+1076 8 1165 1166 # CM CM
+1077 9 1166 1167 # CM CM
+1078 10 1167 1168 # CM CM
+1079 11 1168 1169 # CM CM
+1080 12 1169 1170 # CM CT
+1081 1 1171 1172 # HG CM
+1082 2 1172 1173 # CM CM
+1083 3 1173 1174 # CM CM
+1084 4 1174 1175 # CM CM
+1085 5 1175 1176 # CM CM
+1086 6 1176 1177 # CM CM
+1087 7 1177 1178 # CM CM
+1088 8 1178 1179 # CM CM
+1089 9 1179 1180 # CM CM
+1090 10 1180 1181 # CM CM
+1091 11 1181 1182 # CM CM
+1092 12 1182 1183 # CM CT
+1093 1 1184 1185 # HG CM
+1094 2 1185 1186 # CM CM
+1095 3 1186 1187 # CM CM
+1096 4 1187 1188 # CM CM
+1097 5 1188 1189 # CM CM
+1098 6 1189 1190 # CM CM
+1099 7 1190 1191 # CM CM
+1100 8 1191 1192 # CM CM
+1101 9 1192 1193 # CM CM
+1102 10 1193 1194 # CM CM
+1103 11 1194 1195 # CM CM
+1104 12 1195 1196 # CM CT
+1105 1 1197 1198 # HG CM
+1106 2 1198 1199 # CM CM
+1107 3 1199 1200 # CM CM
+1108 4 1200 1201 # CM CM
+1109 5 1201 1202 # CM CM
+1110 6 1202 1203 # CM CM
+1111 7 1203 1204 # CM CM
+1112 8 1204 1205 # CM CM
+1113 9 1205 1206 # CM CM
+1114 10 1206 1207 # CM CM
+1115 11 1207 1208 # CM CM
+1116 12 1208 1209 # CM CT
+1117 1 1210 1211 # HG CM
+1118 2 1211 1212 # CM CM
+1119 3 1212 1213 # CM CM
+1120 4 1213 1214 # CM CM
+1121 5 1214 1215 # CM CM
+1122 6 1215 1216 # CM CM
+1123 7 1216 1217 # CM CM
+1124 8 1217 1218 # CM CM
+1125 9 1218 1219 # CM CM
+1126 10 1219 1220 # CM CM
+1127 11 1220 1221 # CM CM
+1128 12 1221 1222 # CM CT
+1129 1 1223 1224 # HG CM
+1130 2 1224 1225 # CM CM
+1131 3 1225 1226 # CM CM
+1132 4 1226 1227 # CM CM
+1133 5 1227 1228 # CM CM
+1134 6 1228 1229 # CM CM
+1135 7 1229 1230 # CM CM
+1136 8 1230 1231 # CM CM
+1137 9 1231 1232 # CM CM
+1138 10 1232 1233 # CM CM
+1139 11 1233 1234 # CM CM
+1140 12 1234 1235 # CM CT
+1141 1 1236 1237 # HG CM
+1142 2 1237 1238 # CM CM
+1143 3 1238 1239 # CM CM
+1144 4 1239 1240 # CM CM
+1145 5 1240 1241 # CM CM
+1146 6 1241 1242 # CM CM
+1147 7 1242 1243 # CM CM
+1148 8 1243 1244 # CM CM
+1149 9 1244 1245 # CM CM
+1150 10 1245 1246 # CM CM
+1151 11 1246 1247 # CM CM
+1152 12 1247 1248 # CM CT
+1153 1 1249 1250 # HG CM
+1154 2 1250 1251 # CM CM
+1155 3 1251 1252 # CM CM
+1156 4 1252 1253 # CM CM
+1157 5 1253 1254 # CM CM
+1158 6 1254 1255 # CM CM
+1159 7 1255 1256 # CM CM
+1160 8 1256 1257 # CM CM
+1161 9 1257 1258 # CM CM
+1162 10 1258 1259 # CM CM
+1163 11 1259 1260 # CM CM
+1164 12 1260 1261 # CM CT
+1165 1 1262 1263 # HG CM
+1166 2 1263 1264 # CM CM
+1167 3 1264 1265 # CM CM
+1168 4 1265 1266 # CM CM
+1169 5 1266 1267 # CM CM
+1170 6 1267 1268 # CM CM
+1171 7 1268 1269 # CM CM
+1172 8 1269 1270 # CM CM
+1173 9 1270 1271 # CM CM
+1174 10 1271 1272 # CM CM
+1175 11 1272 1273 # CM CM
+1176 12 1273 1274 # CM CT
+1177 1 1275 1276 # HG CM
+1178 2 1276 1277 # CM CM
+1179 3 1277 1278 # CM CM
+1180 4 1278 1279 # CM CM
+1181 5 1279 1280 # CM CM
+1182 6 1280 1281 # CM CM
+1183 7 1281 1282 # CM CM
+1184 8 1282 1283 # CM CM
+1185 9 1283 1284 # CM CM
+1186 10 1284 1285 # CM CM
+1187 11 1285 1286 # CM CM
+1188 12 1286 1287 # CM CT
+1189 1 1288 1289 # HG CM
+1190 2 1289 1290 # CM CM
+1191 3 1290 1291 # CM CM
+1192 4 1291 1292 # CM CM
+1193 5 1292 1293 # CM CM
+1194 6 1293 1294 # CM CM
+1195 7 1294 1295 # CM CM
+1196 8 1295 1296 # CM CM
+1197 9 1296 1297 # CM CM
+1198 10 1297 1298 # CM CM
+1199 11 1298 1299 # CM CM
+1200 12 1299 1300 # CM CT
+1201 1 1301 1302 # HG CM
+1202 2 1302 1303 # CM CM
+1203 3 1303 1304 # CM CM
+1204 4 1304 1305 # CM CM
+1205 5 1305 1306 # CM CM
+1206 6 1306 1307 # CM CM
+1207 7 1307 1308 # CM CM
+1208 8 1308 1309 # CM CM
+1209 9 1309 1310 # CM CM
+1210 10 1310 1311 # CM CM
+1211 11 1311 1312 # CM CM
+1212 12 1312 1313 # CM CT
+1213 1 1314 1315 # HG CM
+1214 2 1315 1316 # CM CM
+1215 3 1316 1317 # CM CM
+1216 4 1317 1318 # CM CM
+1217 5 1318 1319 # CM CM
+1218 6 1319 1320 # CM CM
+1219 7 1320 1321 # CM CM
+1220 8 1321 1322 # CM CM
+1221 9 1322 1323 # CM CM
+1222 10 1323 1324 # CM CM
+1223 11 1324 1325 # CM CM
+1224 12 1325 1326 # CM CT
+1225 1 1327 1328 # HG CM
+1226 2 1328 1329 # CM CM
+1227 3 1329 1330 # CM CM
+1228 4 1330 1331 # CM CM
+1229 5 1331 1332 # CM CM
+1230 6 1332 1333 # CM CM
+1231 7 1333 1334 # CM CM
+1232 8 1334 1335 # CM CM
+1233 9 1335 1336 # CM CM
+1234 10 1336 1337 # CM CM
+1235 11 1337 1338 # CM CM
+1236 12 1338 1339 # CM CT
+1237 1 1340 1341 # HG CM
+1238 2 1341 1342 # CM CM
+1239 3 1342 1343 # CM CM
+1240 4 1343 1344 # CM CM
+1241 5 1344 1345 # CM CM
+1242 6 1345 1346 # CM CM
+1243 7 1346 1347 # CM CM
+1244 8 1347 1348 # CM CM
+1245 9 1348 1349 # CM CM
+1246 10 1349 1350 # CM CM
+1247 11 1350 1351 # CM CM
+1248 12 1351 1352 # CM CT
+1249 1 1353 1354 # HG CM
+1250 2 1354 1355 # CM CM
+1251 3 1355 1356 # CM CM
+1252 4 1356 1357 # CM CM
+1253 5 1357 1358 # CM CM
+1254 6 1358 1359 # CM CM
+1255 7 1359 1360 # CM CM
+1256 8 1360 1361 # CM CM
+1257 9 1361 1362 # CM CM
+1258 10 1362 1363 # CM CM
+1259 11 1363 1364 # CM CM
+1260 12 1364 1365 # CM CT
+1261 1 1366 1367 # HG CM
+1262 2 1367 1368 # CM CM
+1263 3 1368 1369 # CM CM
+1264 4 1369 1370 # CM CM
+1265 5 1370 1371 # CM CM
+1266 6 1371 1372 # CM CM
+1267 7 1372 1373 # CM CM
+1268 8 1373 1374 # CM CM
+1269 9 1374 1375 # CM CM
+1270 10 1375 1376 # CM CM
+1271 11 1376 1377 # CM CM
+1272 12 1377 1378 # CM CT
+1273 1 1379 1380 # HG CM
+1274 2 1380 1381 # CM CM
+1275 3 1381 1382 # CM CM
+1276 4 1382 1383 # CM CM
+1277 5 1383 1384 # CM CM
+1278 6 1384 1385 # CM CM
+1279 7 1385 1386 # CM CM
+1280 8 1386 1387 # CM CM
+1281 9 1387 1388 # CM CM
+1282 10 1388 1389 # CM CM
+1283 11 1389 1390 # CM CM
+1284 12 1390 1391 # CM CT
+1285 1 1392 1393 # HG CM
+1286 2 1393 1394 # CM CM
+1287 3 1394 1395 # CM CM
+1288 4 1395 1396 # CM CM
+1289 5 1396 1397 # CM CM
+1290 6 1397 1398 # CM CM
+1291 7 1398 1399 # CM CM
+1292 8 1399 1400 # CM CM
+1293 9 1400 1401 # CM CM
+1294 10 1401 1402 # CM CM
+1295 11 1402 1403 # CM CM
+1296 12 1403 1404 # CM CT
+1297 1 1405 1406 # HG CM
+1298 2 1406 1407 # CM CM
+1299 3 1407 1408 # CM CM
+1300 4 1408 1409 # CM CM
+1301 5 1409 1410 # CM CM
+1302 6 1410 1411 # CM CM
+1303 7 1411 1412 # CM CM
+1304 8 1412 1413 # CM CM
+1305 9 1413 1414 # CM CM
+1306 10 1414 1415 # CM CM
+1307 11 1415 1416 # CM CM
+1308 12 1416 1417 # CM CT
+1309 1 1418 1419 # HG CM
+1310 2 1419 1420 # CM CM
+1311 3 1420 1421 # CM CM
+1312 4 1421 1422 # CM CM
+1313 5 1422 1423 # CM CM
+1314 6 1423 1424 # CM CM
+1315 7 1424 1425 # CM CM
+1316 8 1425 1426 # CM CM
+1317 9 1426 1427 # CM CM
+1318 10 1427 1428 # CM CM
+1319 11 1428 1429 # CM CM
+1320 12 1429 1430 # CM CT
+1321 1 1431 1432 # HG CM
+1322 2 1432 1433 # CM CM
+1323 3 1433 1434 # CM CM
+1324 4 1434 1435 # CM CM
+1325 5 1435 1436 # CM CM
+1326 6 1436 1437 # CM CM
+1327 7 1437 1438 # CM CM
+1328 8 1438 1439 # CM CM
+1329 9 1439 1440 # CM CM
+1330 10 1440 1441 # CM CM
+1331 11 1441 1442 # CM CM
+1332 12 1442 1443 # CM CT
+1333 1 1444 1445 # HG CM
+1334 2 1445 1446 # CM CM
+1335 3 1446 1447 # CM CM
+1336 4 1447 1448 # CM CM
+1337 5 1448 1449 # CM CM
+1338 6 1449 1450 # CM CM
+1339 7 1450 1451 # CM CM
+1340 8 1451 1452 # CM CM
+1341 9 1452 1453 # CM CM
+1342 10 1453 1454 # CM CM
+1343 11 1454 1455 # CM CM
+1344 12 1455 1456 # CM CT
+1345 1 1457 1458 # HG CM
+1346 2 1458 1459 # CM CM
+1347 3 1459 1460 # CM CM
+1348 4 1460 1461 # CM CM
+1349 5 1461 1462 # CM CM
+1350 6 1462 1463 # CM CM
+1351 7 1463 1464 # CM CM
+1352 8 1464 1465 # CM CM
+1353 9 1465 1466 # CM CM
+1354 10 1466 1467 # CM CM
+1355 11 1467 1468 # CM CM
+1356 12 1468 1469 # CM CT
+1357 1 1470 1471 # HG CM
+1358 2 1471 1472 # CM CM
+1359 3 1472 1473 # CM CM
+1360 4 1473 1474 # CM CM
+1361 5 1474 1475 # CM CM
+1362 6 1475 1476 # CM CM
+1363 7 1476 1477 # CM CM
+1364 8 1477 1478 # CM CM
+1365 9 1478 1479 # CM CM
+1366 10 1479 1480 # CM CM
+1367 11 1480 1481 # CM CM
+1368 12 1481 1482 # CM CT
+1369 1 1483 1484 # HG CM
+1370 2 1484 1485 # CM CM
+1371 3 1485 1486 # CM CM
+1372 4 1486 1487 # CM CM
+1373 5 1487 1488 # CM CM
+1374 6 1488 1489 # CM CM
+1375 7 1489 1490 # CM CM
+1376 8 1490 1491 # CM CM
+1377 9 1491 1492 # CM CM
+1378 10 1492 1493 # CM CM
+1379 11 1493 1494 # CM CM
+1380 12 1494 1495 # CM CT
+1381 1 1496 1497 # HG CM
+1382 2 1497 1498 # CM CM
+1383 3 1498 1499 # CM CM
+1384 4 1499 1500 # CM CM
+1385 5 1500 1501 # CM CM
+1386 6 1501 1502 # CM CM
+1387 7 1502 1503 # CM CM
+1388 8 1503 1504 # CM CM
+1389 9 1504 1505 # CM CM
+1390 10 1505 1506 # CM CM
+1391 11 1506 1507 # CM CM
+1392 12 1507 1508 # CM CT
+1393 1 1509 1510 # HG CM
+1394 2 1510 1511 # CM CM
+1395 3 1511 1512 # CM CM
+1396 4 1512 1513 # CM CM
+1397 5 1513 1514 # CM CM
+1398 6 1514 1515 # CM CM
+1399 7 1515 1516 # CM CM
+1400 8 1516 1517 # CM CM
+1401 9 1517 1518 # CM CM
+1402 10 1518 1519 # CM CM
+1403 11 1519 1520 # CM CM
+1404 12 1520 1521 # CM CT
+1405 1 1522 1523 # HG CM
+1406 2 1523 1524 # CM CM
+1407 3 1524 1525 # CM CM
+1408 4 1525 1526 # CM CM
+1409 5 1526 1527 # CM CM
+1410 6 1527 1528 # CM CM
+1411 7 1528 1529 # CM CM
+1412 8 1529 1530 # CM CM
+1413 9 1530 1531 # CM CM
+1414 10 1531 1532 # CM CM
+1415 11 1532 1533 # CM CM
+1416 12 1533 1534 # CM CT
+1417 1 1535 1536 # HG CM
+1418 2 1536 1537 # CM CM
+1419 3 1537 1538 # CM CM
+1420 4 1538 1539 # CM CM
+1421 5 1539 1540 # CM CM
+1422 6 1540 1541 # CM CM
+1423 7 1541 1542 # CM CM
+1424 8 1542 1543 # CM CM
+1425 9 1543 1544 # CM CM
+1426 10 1544 1545 # CM CM
+1427 11 1545 1546 # CM CM
+1428 12 1546 1547 # CM CT
+1429 1 1548 1549 # HG CM
+1430 2 1549 1550 # CM CM
+1431 3 1550 1551 # CM CM
+1432 4 1551 1552 # CM CM
+1433 5 1552 1553 # CM CM
+1434 6 1553 1554 # CM CM
+1435 7 1554 1555 # CM CM
+1436 8 1555 1556 # CM CM
+1437 9 1556 1557 # CM CM
+1438 10 1557 1558 # CM CM
+1439 11 1558 1559 # CM CM
+1440 12 1559 1560 # CM CT
+1441 1 1561 1562 # HG CM
+1442 2 1562 1563 # CM CM
+1443 3 1563 1564 # CM CM
+1444 4 1564 1565 # CM CM
+1445 5 1565 1566 # CM CM
+1446 6 1566 1567 # CM CM
+1447 7 1567 1568 # CM CM
+1448 8 1568 1569 # CM CM
+1449 9 1569 1570 # CM CM
+1450 10 1570 1571 # CM CM
+1451 11 1571 1572 # CM CM
+1452 12 1572 1573 # CM CT
+1453 1 1574 1575 # HG CM
+1454 2 1575 1576 # CM CM
+1455 3 1576 1577 # CM CM
+1456 4 1577 1578 # CM CM
+1457 5 1578 1579 # CM CM
+1458 6 1579 1580 # CM CM
+1459 7 1580 1581 # CM CM
+1460 8 1581 1582 # CM CM
+1461 9 1582 1583 # CM CM
+1462 10 1583 1584 # CM CM
+1463 11 1584 1585 # CM CM
+1464 12 1585 1586 # CM CT
+1465 1 1587 1588 # HG CM
+1466 2 1588 1589 # CM CM
+1467 3 1589 1590 # CM CM
+1468 4 1590 1591 # CM CM
+1469 5 1591 1592 # CM CM
+1470 6 1592 1593 # CM CM
+1471 7 1593 1594 # CM CM
+1472 8 1594 1595 # CM CM
+1473 9 1595 1596 # CM CM
+1474 10 1596 1597 # CM CM
+1475 11 1597 1598 # CM CM
+1476 12 1598 1599 # CM CT
+1477 1 1600 1601 # HG CM
+1478 2 1601 1602 # CM CM
+1479 3 1602 1603 # CM CM
+1480 4 1603 1604 # CM CM
+1481 5 1604 1605 # CM CM
+1482 6 1605 1606 # CM CM
+1483 7 1606 1607 # CM CM
+1484 8 1607 1608 # CM CM
+1485 9 1608 1609 # CM CM
+1486 10 1609 1610 # CM CM
+1487 11 1610 1611 # CM CM
+1488 12 1611 1612 # CM CT
+1489 1 1613 1614 # HG CM
+1490 2 1614 1615 # CM CM
+1491 3 1615 1616 # CM CM
+1492 4 1616 1617 # CM CM
+1493 5 1617 1618 # CM CM
+1494 6 1618 1619 # CM CM
+1495 7 1619 1620 # CM CM
+1496 8 1620 1621 # CM CM
+1497 9 1621 1622 # CM CM
+1498 10 1622 1623 # CM CM
+1499 11 1623 1624 # CM CM
+1500 12 1624 1625 # CM CT
+1501 1 1626 1627 # HG CM
+1502 2 1627 1628 # CM CM
+1503 3 1628 1629 # CM CM
+1504 4 1629 1630 # CM CM
+1505 5 1630 1631 # CM CM
+1506 6 1631 1632 # CM CM
+1507 7 1632 1633 # CM CM
+1508 8 1633 1634 # CM CM
+1509 9 1634 1635 # CM CM
+1510 10 1635 1636 # CM CM
+1511 11 1636 1637 # CM CM
+1512 12 1637 1638 # CM CT
+1513 1 1639 1640 # HG CM
+1514 2 1640 1641 # CM CM
+1515 3 1641 1642 # CM CM
+1516 4 1642 1643 # CM CM
+1517 5 1643 1644 # CM CM
+1518 6 1644 1645 # CM CM
+1519 7 1645 1646 # CM CM
+1520 8 1646 1647 # CM CM
+1521 9 1647 1648 # CM CM
+1522 10 1648 1649 # CM CM
+1523 11 1649 1650 # CM CM
+1524 12 1650 1651 # CM CT
+1525 1 1652 1653 # HG CM
+1526 2 1653 1654 # CM CM
+1527 3 1654 1655 # CM CM
+1528 4 1655 1656 # CM CM
+1529 5 1656 1657 # CM CM
+1530 6 1657 1658 # CM CM
+1531 7 1658 1659 # CM CM
+1532 8 1659 1660 # CM CM
+1533 9 1660 1661 # CM CM
+1534 10 1661 1662 # CM CM
+1535 11 1662 1663 # CM CM
+1536 12 1663 1664 # CM CT
+1537 1 1665 1666 # HG CM
+1538 2 1666 1667 # CM CM
+1539 3 1667 1668 # CM CM
+1540 4 1668 1669 # CM CM
+1541 5 1669 1670 # CM CM
+1542 6 1670 1671 # CM CM
+1543 7 1671 1672 # CM CM
+1544 8 1672 1673 # CM CM
+1545 9 1673 1674 # CM CM
+1546 10 1674 1675 # CM CM
+1547 11 1675 1676 # CM CM
+1548 12 1676 1677 # CM CT
+1549 1 1678 1679 # HG CM
+1550 2 1679 1680 # CM CM
+1551 3 1680 1681 # CM CM
+1552 4 1681 1682 # CM CM
+1553 5 1682 1683 # CM CM
+1554 6 1683 1684 # CM CM
+1555 7 1684 1685 # CM CM
+1556 8 1685 1686 # CM CM
+1557 9 1686 1687 # CM CM
+1558 10 1687 1688 # CM CM
+1559 11 1688 1689 # CM CM
+1560 12 1689 1690 # CM CT
+1561 1 1691 1692 # HG CM
+1562 2 1692 1693 # CM CM
+1563 3 1693 1694 # CM CM
+1564 4 1694 1695 # CM CM
+1565 5 1695 1696 # CM CM
+1566 6 1696 1697 # CM CM
+1567 7 1697 1698 # CM CM
+1568 8 1698 1699 # CM CM
+1569 9 1699 1700 # CM CM
+1570 10 1700 1701 # CM CM
+1571 11 1701 1702 # CM CM
+1572 12 1702 1703 # CM CT
+1573 1 1704 1705 # HG CM
+1574 2 1705 1706 # CM CM
+1575 3 1706 1707 # CM CM
+1576 4 1707 1708 # CM CM
+1577 5 1708 1709 # CM CM
+1578 6 1709 1710 # CM CM
+1579 7 1710 1711 # CM CM
+1580 8 1711 1712 # CM CM
+1581 9 1712 1713 # CM CM
+1582 10 1713 1714 # CM CM
+1583 11 1714 1715 # CM CM
+1584 12 1715 1716 # CM CT
+1585 1 1717 1718 # HG CM
+1586 2 1718 1719 # CM CM
+1587 3 1719 1720 # CM CM
+1588 4 1720 1721 # CM CM
+1589 5 1721 1722 # CM CM
+1590 6 1722 1723 # CM CM
+1591 7 1723 1724 # CM CM
+1592 8 1724 1725 # CM CM
+1593 9 1725 1726 # CM CM
+1594 10 1726 1727 # CM CM
+1595 11 1727 1728 # CM CM
+1596 12 1728 1729 # CM CT
+1597 1 1730 1731 # HG CM
+1598 2 1731 1732 # CM CM
+1599 3 1732 1733 # CM CM
+1600 4 1733 1734 # CM CM
+1601 5 1734 1735 # CM CM
+1602 6 1735 1736 # CM CM
+1603 7 1736 1737 # CM CM
+1604 8 1737 1738 # CM CM
+1605 9 1738 1739 # CM CM
+1606 10 1739 1740 # CM CM
+1607 11 1740 1741 # CM CM
+1608 12 1741 1742 # CM CT
+1609 1 1743 1744 # HG CM
+1610 2 1744 1745 # CM CM
+1611 3 1745 1746 # CM CM
+1612 4 1746 1747 # CM CM
+1613 5 1747 1748 # CM CM
+1614 6 1748 1749 # CM CM
+1615 7 1749 1750 # CM CM
+1616 8 1750 1751 # CM CM
+1617 9 1751 1752 # CM CM
+1618 10 1752 1753 # CM CM
+1619 11 1753 1754 # CM CM
+1620 12 1754 1755 # CM CT
+1621 1 1756 1757 # HG CM
+1622 2 1757 1758 # CM CM
+1623 3 1758 1759 # CM CM
+1624 4 1759 1760 # CM CM
+1625 5 1760 1761 # CM CM
+1626 6 1761 1762 # CM CM
+1627 7 1762 1763 # CM CM
+1628 8 1763 1764 # CM CM
+1629 9 1764 1765 # CM CM
+1630 10 1765 1766 # CM CM
+1631 11 1766 1767 # CM CM
+1632 12 1767 1768 # CM CT
+1633 1 1769 1770 # HG CM
+1634 2 1770 1771 # CM CM
+1635 3 1771 1772 # CM CM
+1636 4 1772 1773 # CM CM
+1637 5 1773 1774 # CM CM
+1638 6 1774 1775 # CM CM
+1639 7 1775 1776 # CM CM
+1640 8 1776 1777 # CM CM
+1641 9 1777 1778 # CM CM
+1642 10 1778 1779 # CM CM
+1643 11 1779 1780 # CM CM
+1644 12 1780 1781 # CM CT
+1645 1 1782 1783 # HG CM
+1646 2 1783 1784 # CM CM
+1647 3 1784 1785 # CM CM
+1648 4 1785 1786 # CM CM
+1649 5 1786 1787 # CM CM
+1650 6 1787 1788 # CM CM
+1651 7 1788 1789 # CM CM
+1652 8 1789 1790 # CM CM
+1653 9 1790 1791 # CM CM
+1654 10 1791 1792 # CM CM
+1655 11 1792 1793 # CM CM
+1656 12 1793 1794 # CM CT
+1657 1 1795 1796 # HG CM
+1658 2 1796 1797 # CM CM
+1659 3 1797 1798 # CM CM
+1660 4 1798 1799 # CM CM
+1661 5 1799 1800 # CM CM
+1662 6 1800 1801 # CM CM
+1663 7 1801 1802 # CM CM
+1664 8 1802 1803 # CM CM
+1665 9 1803 1804 # CM CM
+1666 10 1804 1805 # CM CM
+1667 11 1805 1806 # CM CM
+1668 12 1806 1807 # CM CT
+1669 1 1808 1809 # HG CM
+1670 2 1809 1810 # CM CM
+1671 3 1810 1811 # CM CM
+1672 4 1811 1812 # CM CM
+1673 5 1812 1813 # CM CM
+1674 6 1813 1814 # CM CM
+1675 7 1814 1815 # CM CM
+1676 8 1815 1816 # CM CM
+1677 9 1816 1817 # CM CM
+1678 10 1817 1818 # CM CM
+1679 11 1818 1819 # CM CM
+1680 12 1819 1820 # CM CT
+1681 1 1821 1822 # HG CM
+1682 2 1822 1823 # CM CM
+1683 3 1823 1824 # CM CM
+1684 4 1824 1825 # CM CM
+1685 5 1825 1826 # CM CM
+1686 6 1826 1827 # CM CM
+1687 7 1827 1828 # CM CM
+1688 8 1828 1829 # CM CM
+1689 9 1829 1830 # CM CM
+1690 10 1830 1831 # CM CM
+1691 11 1831 1832 # CM CM
+1692 12 1832 1833 # CM CT
+1693 1 1834 1835 # HG CM
+1694 2 1835 1836 # CM CM
+1695 3 1836 1837 # CM CM
+1696 4 1837 1838 # CM CM
+1697 5 1838 1839 # CM CM
+1698 6 1839 1840 # CM CM
+1699 7 1840 1841 # CM CM
+1700 8 1841 1842 # CM CM
+1701 9 1842 1843 # CM CM
+1702 10 1843 1844 # CM CM
+1703 11 1844 1845 # CM CM
+1704 12 1845 1846 # CM CT
+1705 1 1847 1848 # HG CM
+1706 2 1848 1849 # CM CM
+1707 3 1849 1850 # CM CM
+1708 4 1850 1851 # CM CM
+1709 5 1851 1852 # CM CM
+1710 6 1852 1853 # CM CM
+1711 7 1853 1854 # CM CM
+1712 8 1854 1855 # CM CM
+1713 9 1855 1856 # CM CM
+1714 10 1856 1857 # CM CM
+1715 11 1857 1858 # CM CM
+1716 12 1858 1859 # CM CT
+1717 1 1860 1861 # HG CM
+1718 2 1861 1862 # CM CM
+1719 3 1862 1863 # CM CM
+1720 4 1863 1864 # CM CM
+1721 5 1864 1865 # CM CM
+1722 6 1865 1866 # CM CM
+1723 7 1866 1867 # CM CM
+1724 8 1867 1868 # CM CM
+1725 9 1868 1869 # CM CM
+1726 10 1869 1870 # CM CM
+1727 11 1870 1871 # CM CM
+1728 12 1871 1872 # CM CT
+1729 1 1873 1874 # HG CM
+1730 2 1874 1875 # CM CM
+1731 3 1875 1876 # CM CM
+1732 4 1876 1877 # CM CM
+1733 5 1877 1878 # CM CM
+1734 6 1878 1879 # CM CM
+1735 7 1879 1880 # CM CM
+1736 8 1880 1881 # CM CM
+1737 9 1881 1882 # CM CM
+1738 10 1882 1883 # CM CM
+1739 11 1883 1884 # CM CM
+1740 12 1884 1885 # CM CT
+1741 1 1886 1887 # HG CM
+1742 2 1887 1888 # CM CM
+1743 3 1888 1889 # CM CM
+1744 4 1889 1890 # CM CM
+1745 5 1890 1891 # CM CM
+1746 6 1891 1892 # CM CM
+1747 7 1892 1893 # CM CM
+1748 8 1893 1894 # CM CM
+1749 9 1894 1895 # CM CM
+1750 10 1895 1896 # CM CM
+1751 11 1896 1897 # CM CM
+1752 12 1897 1898 # CM CT
+1753 1 1899 1900 # HG CM
+1754 2 1900 1901 # CM CM
+1755 3 1901 1902 # CM CM
+1756 4 1902 1903 # CM CM
+1757 5 1903 1904 # CM CM
+1758 6 1904 1905 # CM CM
+1759 7 1905 1906 # CM CM
+1760 8 1906 1907 # CM CM
+1761 9 1907 1908 # CM CM
+1762 10 1908 1909 # CM CM
+1763 11 1909 1910 # CM CM
+1764 12 1910 1911 # CM CT
+1765 1 1912 1913 # HG CM
+1766 2 1913 1914 # CM CM
+1767 3 1914 1915 # CM CM
+1768 4 1915 1916 # CM CM
+1769 5 1916 1917 # CM CM
+1770 6 1917 1918 # CM CM
+1771 7 1918 1919 # CM CM
+1772 8 1919 1920 # CM CM
+1773 9 1920 1921 # CM CM
+1774 10 1921 1922 # CM CM
+1775 11 1922 1923 # CM CM
+1776 12 1923 1924 # CM CT
+1777 1 1925 1926 # HG CM
+1778 2 1926 1927 # CM CM
+1779 3 1927 1928 # CM CM
+1780 4 1928 1929 # CM CM
+1781 5 1929 1930 # CM CM
+1782 6 1930 1931 # CM CM
+1783 7 1931 1932 # CM CM
+1784 8 1932 1933 # CM CM
+1785 9 1933 1934 # CM CM
+1786 10 1934 1935 # CM CM
+1787 11 1935 1936 # CM CM
+1788 12 1936 1937 # CM CT
+1789 1 1938 1939 # HG CM
+1790 2 1939 1940 # CM CM
+1791 3 1940 1941 # CM CM
+1792 4 1941 1942 # CM CM
+1793 5 1942 1943 # CM CM
+1794 6 1943 1944 # CM CM
+1795 7 1944 1945 # CM CM
+1796 8 1945 1946 # CM CM
+1797 9 1946 1947 # CM CM
+1798 10 1947 1948 # CM CM
+1799 11 1948 1949 # CM CM
+1800 12 1949 1950 # CM CT
+1801 1 1951 1952 # HG CM
+1802 2 1952 1953 # CM CM
+1803 3 1953 1954 # CM CM
+1804 4 1954 1955 # CM CM
+1805 5 1955 1956 # CM CM
+1806 6 1956 1957 # CM CM
+1807 7 1957 1958 # CM CM
+1808 8 1958 1959 # CM CM
+1809 9 1959 1960 # CM CM
+1810 10 1960 1961 # CM CM
+1811 11 1961 1962 # CM CM
+1812 12 1962 1963 # CM CT
+1813 1 1964 1965 # HG CM
+1814 2 1965 1966 # CM CM
+1815 3 1966 1967 # CM CM
+1816 4 1967 1968 # CM CM
+1817 5 1968 1969 # CM CM
+1818 6 1969 1970 # CM CM
+1819 7 1970 1971 # CM CM
+1820 8 1971 1972 # CM CM
+1821 9 1972 1973 # CM CM
+1822 10 1973 1974 # CM CM
+1823 11 1974 1975 # CM CM
+1824 12 1975 1976 # CM CT
+1825 1 1977 1978 # HG CM
+1826 2 1978 1979 # CM CM
+1827 3 1979 1980 # CM CM
+1828 4 1980 1981 # CM CM
+1829 5 1981 1982 # CM CM
+1830 6 1982 1983 # CM CM
+1831 7 1983 1984 # CM CM
+1832 8 1984 1985 # CM CM
+1833 9 1985 1986 # CM CM
+1834 10 1986 1987 # CM CM
+1835 11 1987 1988 # CM CM
+1836 12 1988 1989 # CM CT
+1837 1 1990 1991 # HG CM
+1838 2 1991 1992 # CM CM
+1839 3 1992 1993 # CM CM
+1840 4 1993 1994 # CM CM
+1841 5 1994 1995 # CM CM
+1842 6 1995 1996 # CM CM
+1843 7 1996 1997 # CM CM
+1844 8 1997 1998 # CM CM
+1845 9 1998 1999 # CM CM
+1846 10 1999 2000 # CM CM
+1847 11 2000 2001 # CM CM
+1848 12 2001 2002 # CM CT
+1849 1 2003 2004 # HG CM
+1850 2 2004 2005 # CM CM
+1851 3 2005 2006 # CM CM
+1852 4 2006 2007 # CM CM
+1853 5 2007 2008 # CM CM
+1854 6 2008 2009 # CM CM
+1855 7 2009 2010 # CM CM
+1856 8 2010 2011 # CM CM
+1857 9 2011 2012 # CM CM
+1858 10 2012 2013 # CM CM
+1859 11 2013 2014 # CM CM
+1860 12 2014 2015 # CM CT
+1861 1 2016 2017 # HG CM
+1862 2 2017 2018 # CM CM
+1863 3 2018 2019 # CM CM
+1864 4 2019 2020 # CM CM
+1865 5 2020 2021 # CM CM
+1866 6 2021 2022 # CM CM
+1867 7 2022 2023 # CM CM
+1868 8 2023 2024 # CM CM
+1869 9 2024 2025 # CM CM
+1870 10 2025 2026 # CM CM
+1871 11 2026 2027 # CM CM
+1872 12 2027 2028 # CM CT
+1873 1 2029 2030 # HG CM
+1874 2 2030 2031 # CM CM
+1875 3 2031 2032 # CM CM
+1876 4 2032 2033 # CM CM
+1877 5 2033 2034 # CM CM
+1878 6 2034 2035 # CM CM
+1879 7 2035 2036 # CM CM
+1880 8 2036 2037 # CM CM
+1881 9 2037 2038 # CM CM
+1882 10 2038 2039 # CM CM
+1883 11 2039 2040 # CM CM
+1884 12 2040 2041 # CM CT
+1885 1 2042 2043 # HG CM
+1886 2 2043 2044 # CM CM
+1887 3 2044 2045 # CM CM
+1888 4 2045 2046 # CM CM
+1889 5 2046 2047 # CM CM
+1890 6 2047 2048 # CM CM
+1891 7 2048 2049 # CM CM
+1892 8 2049 2050 # CM CM
+1893 9 2050 2051 # CM CM
+1894 10 2051 2052 # CM CM
+1895 11 2052 2053 # CM CM
+1896 12 2053 2054 # CM CT
+1897 1 2055 2056 # HG CM
+1898 2 2056 2057 # CM CM
+1899 3 2057 2058 # CM CM
+1900 4 2058 2059 # CM CM
+1901 5 2059 2060 # CM CM
+1902 6 2060 2061 # CM CM
+1903 7 2061 2062 # CM CM
+1904 8 2062 2063 # CM CM
+1905 9 2063 2064 # CM CM
+1906 10 2064 2065 # CM CM
+1907 11 2065 2066 # CM CM
+1908 12 2066 2067 # CM CT
+1909 1 2068 2069 # HG CM
+1910 2 2069 2070 # CM CM
+1911 3 2070 2071 # CM CM
+1912 4 2071 2072 # CM CM
+1913 5 2072 2073 # CM CM
+1914 6 2073 2074 # CM CM
+1915 7 2074 2075 # CM CM
+1916 8 2075 2076 # CM CM
+1917 9 2076 2077 # CM CM
+1918 10 2077 2078 # CM CM
+1919 11 2078 2079 # CM CM
+1920 12 2079 2080 # CM CT
+1921 1 2081 2082 # HG CM
+1922 2 2082 2083 # CM CM
+1923 3 2083 2084 # CM CM
+1924 4 2084 2085 # CM CM
+1925 5 2085 2086 # CM CM
+1926 6 2086 2087 # CM CM
+1927 7 2087 2088 # CM CM
+1928 8 2088 2089 # CM CM
+1929 9 2089 2090 # CM CM
+1930 10 2090 2091 # CM CM
+1931 11 2091 2092 # CM CM
+1932 12 2092 2093 # CM CT
+1933 1 2094 2095 # HG CM
+1934 2 2095 2096 # CM CM
+1935 3 2096 2097 # CM CM
+1936 4 2097 2098 # CM CM
+1937 5 2098 2099 # CM CM
+1938 6 2099 2100 # CM CM
+1939 7 2100 2101 # CM CM
+1940 8 2101 2102 # CM CM
+1941 9 2102 2103 # CM CM
+1942 10 2103 2104 # CM CM
+1943 11 2104 2105 # CM CM
+1944 12 2105 2106 # CM CT
+1945 1 2107 2108 # HG CM
+1946 2 2108 2109 # CM CM
+1947 3 2109 2110 # CM CM
+1948 4 2110 2111 # CM CM
+1949 5 2111 2112 # CM CM
+1950 6 2112 2113 # CM CM
+1951 7 2113 2114 # CM CM
+1952 8 2114 2115 # CM CM
+1953 9 2115 2116 # CM CM
+1954 10 2116 2117 # CM CM
+1955 11 2117 2118 # CM CM
+1956 12 2118 2119 # CM CT
+1957 1 2120 2121 # HG CM
+1958 2 2121 2122 # CM CM
+1959 3 2122 2123 # CM CM
+1960 4 2123 2124 # CM CM
+1961 5 2124 2125 # CM CM
+1962 6 2125 2126 # CM CM
+1963 7 2126 2127 # CM CM
+1964 8 2127 2128 # CM CM
+1965 9 2128 2129 # CM CM
+1966 10 2129 2130 # CM CM
+1967 11 2130 2131 # CM CM
+1968 12 2131 2132 # CM CT
+1969 1 2133 2134 # HG CM
+1970 2 2134 2135 # CM CM
+1971 3 2135 2136 # CM CM
+1972 4 2136 2137 # CM CM
+1973 5 2137 2138 # CM CM
+1974 6 2138 2139 # CM CM
+1975 7 2139 2140 # CM CM
+1976 8 2140 2141 # CM CM
+1977 9 2141 2142 # CM CM
+1978 10 2142 2143 # CM CM
+1979 11 2143 2144 # CM CM
+1980 12 2144 2145 # CM CT
+1981 1 2146 2147 # HG CM
+1982 2 2147 2148 # CM CM
+1983 3 2148 2149 # CM CM
+1984 4 2149 2150 # CM CM
+1985 5 2150 2151 # CM CM
+1986 6 2151 2152 # CM CM
+1987 7 2152 2153 # CM CM
+1988 8 2153 2154 # CM CM
+1989 9 2154 2155 # CM CM
+1990 10 2155 2156 # CM CM
+1991 11 2156 2157 # CM CM
+1992 12 2157 2158 # CM CT
+1993 1 2159 2160 # HG CM
+1994 2 2160 2161 # CM CM
+1995 3 2161 2162 # CM CM
+1996 4 2162 2163 # CM CM
+1997 5 2163 2164 # CM CM
+1998 6 2164 2165 # CM CM
+1999 7 2165 2166 # CM CM
+2000 8 2166 2167 # CM CM
+2001 9 2167 2168 # CM CM
+2002 10 2168 2169 # CM CM
+2003 11 2169 2170 # CM CM
+2004 12 2170 2171 # CM CT
+2005 1 2172 2173 # HG CM
+2006 2 2173 2174 # CM CM
+2007 3 2174 2175 # CM CM
+2008 4 2175 2176 # CM CM
+2009 5 2176 2177 # CM CM
+2010 6 2177 2178 # CM CM
+2011 7 2178 2179 # CM CM
+2012 8 2179 2180 # CM CM
+2013 9 2180 2181 # CM CM
+2014 10 2181 2182 # CM CM
+2015 11 2182 2183 # CM CM
+2016 12 2183 2184 # CM CT
+2017 1 2185 2186 # HG CM
+2018 2 2186 2187 # CM CM
+2019 3 2187 2188 # CM CM
+2020 4 2188 2189 # CM CM
+2021 5 2189 2190 # CM CM
+2022 6 2190 2191 # CM CM
+2023 7 2191 2192 # CM CM
+2024 8 2192 2193 # CM CM
+2025 9 2193 2194 # CM CM
+2026 10 2194 2195 # CM CM
+2027 11 2195 2196 # CM CM
+2028 12 2196 2197 # CM CT
+2029 1 2198 2199 # HG CM
+2030 2 2199 2200 # CM CM
+2031 3 2200 2201 # CM CM
+2032 4 2201 2202 # CM CM
+2033 5 2202 2203 # CM CM
+2034 6 2203 2204 # CM CM
+2035 7 2204 2205 # CM CM
+2036 8 2205 2206 # CM CM
+2037 9 2206 2207 # CM CM
+2038 10 2207 2208 # CM CM
+2039 11 2208 2209 # CM CM
+2040 12 2209 2210 # CM CT
+2041 1 2211 2212 # HG CM
+2042 2 2212 2213 # CM CM
+2043 3 2213 2214 # CM CM
+2044 4 2214 2215 # CM CM
+2045 5 2215 2216 # CM CM
+2046 6 2216 2217 # CM CM
+2047 7 2217 2218 # CM CM
+2048 8 2218 2219 # CM CM
+2049 9 2219 2220 # CM CM
+2050 10 2220 2221 # CM CM
+2051 11 2221 2222 # CM CM
+2052 12 2222 2223 # CM CT
+2053 1 2224 2225 # HG CM
+2054 2 2225 2226 # CM CM
+2055 3 2226 2227 # CM CM
+2056 4 2227 2228 # CM CM
+2057 5 2228 2229 # CM CM
+2058 6 2229 2230 # CM CM
+2059 7 2230 2231 # CM CM
+2060 8 2231 2232 # CM CM
+2061 9 2232 2233 # CM CM
+2062 10 2233 2234 # CM CM
+2063 11 2234 2235 # CM CM
+2064 12 2235 2236 # CM CT
+2065 1 2237 2238 # HG CM
+2066 2 2238 2239 # CM CM
+2067 3 2239 2240 # CM CM
+2068 4 2240 2241 # CM CM
+2069 5 2241 2242 # CM CM
+2070 6 2242 2243 # CM CM
+2071 7 2243 2244 # CM CM
+2072 8 2244 2245 # CM CM
+2073 9 2245 2246 # CM CM
+2074 10 2246 2247 # CM CM
+2075 11 2247 2248 # CM CM
+2076 12 2248 2249 # CM CT
+2077 1 2250 2251 # HG CM
+2078 2 2251 2252 # CM CM
+2079 3 2252 2253 # CM CM
+2080 4 2253 2254 # CM CM
+2081 5 2254 2255 # CM CM
+2082 6 2255 2256 # CM CM
+2083 7 2256 2257 # CM CM
+2084 8 2257 2258 # CM CM
+2085 9 2258 2259 # CM CM
+2086 10 2259 2260 # CM CM
+2087 11 2260 2261 # CM CM
+2088 12 2261 2262 # CM CT
+2089 1 2263 2264 # HG CM
+2090 2 2264 2265 # CM CM
+2091 3 2265 2266 # CM CM
+2092 4 2266 2267 # CM CM
+2093 5 2267 2268 # CM CM
+2094 6 2268 2269 # CM CM
+2095 7 2269 2270 # CM CM
+2096 8 2270 2271 # CM CM
+2097 9 2271 2272 # CM CM
+2098 10 2272 2273 # CM CM
+2099 11 2273 2274 # CM CM
+2100 12 2274 2275 # CM CT
+2101 1 2276 2277 # HG CM
+2102 2 2277 2278 # CM CM
+2103 3 2278 2279 # CM CM
+2104 4 2279 2280 # CM CM
+2105 5 2280 2281 # CM CM
+2106 6 2281 2282 # CM CM
+2107 7 2282 2283 # CM CM
+2108 8 2283 2284 # CM CM
+2109 9 2284 2285 # CM CM
+2110 10 2285 2286 # CM CM
+2111 11 2286 2287 # CM CM
+2112 12 2287 2288 # CM CT
+2113 1 2289 2290 # HG CM
+2114 2 2290 2291 # CM CM
+2115 3 2291 2292 # CM CM
+2116 4 2292 2293 # CM CM
+2117 5 2293 2294 # CM CM
+2118 6 2294 2295 # CM CM
+2119 7 2295 2296 # CM CM
+2120 8 2296 2297 # CM CM
+2121 9 2297 2298 # CM CM
+2122 10 2298 2299 # CM CM
+2123 11 2299 2300 # CM CM
+2124 12 2300 2301 # CM CT
+2125 1 2302 2303 # HG CM
+2126 2 2303 2304 # CM CM
+2127 3 2304 2305 # CM CM
+2128 4 2305 2306 # CM CM
+2129 5 2306 2307 # CM CM
+2130 6 2307 2308 # CM CM
+2131 7 2308 2309 # CM CM
+2132 8 2309 2310 # CM CM
+2133 9 2310 2311 # CM CM
+2134 10 2311 2312 # CM CM
+2135 11 2312 2313 # CM CM
+2136 12 2313 2314 # CM CT
+2137 1 2315 2316 # HG CM
+2138 2 2316 2317 # CM CM
+2139 3 2317 2318 # CM CM
+2140 4 2318 2319 # CM CM
+2141 5 2319 2320 # CM CM
+2142 6 2320 2321 # CM CM
+2143 7 2321 2322 # CM CM
+2144 8 2322 2323 # CM CM
+2145 9 2323 2324 # CM CM
+2146 10 2324 2325 # CM CM
+2147 11 2325 2326 # CM CM
+2148 12 2326 2327 # CM CT
+2149 1 2328 2329 # HG CM
+2150 2 2329 2330 # CM CM
+2151 3 2330 2331 # CM CM
+2152 4 2331 2332 # CM CM
+2153 5 2332 2333 # CM CM
+2154 6 2333 2334 # CM CM
+2155 7 2334 2335 # CM CM
+2156 8 2335 2336 # CM CM
+2157 9 2336 2337 # CM CM
+2158 10 2337 2338 # CM CM
+2159 11 2338 2339 # CM CM
+2160 12 2339 2340 # CM CT
+2161 1 2341 2342 # HG CM
+2162 2 2342 2343 # CM CM
+2163 3 2343 2344 # CM CM
+2164 4 2344 2345 # CM CM
+2165 5 2345 2346 # CM CM
+2166 6 2346 2347 # CM CM
+2167 7 2347 2348 # CM CM
+2168 8 2348 2349 # CM CM
+2169 9 2349 2350 # CM CM
+2170 10 2350 2351 # CM CM
+2171 11 2351 2352 # CM CM
+2172 12 2352 2353 # CM CT
+2173 1 2354 2355 # HG CM
+2174 2 2355 2356 # CM CM
+2175 3 2356 2357 # CM CM
+2176 4 2357 2358 # CM CM
+2177 5 2358 2359 # CM CM
+2178 6 2359 2360 # CM CM
+2179 7 2360 2361 # CM CM
+2180 8 2361 2362 # CM CM
+2181 9 2362 2363 # CM CM
+2182 10 2363 2364 # CM CM
+2183 11 2364 2365 # CM CM
+2184 12 2365 2366 # CM CT
+2185 1 2367 2368 # HG CM
+2186 2 2368 2369 # CM CM
+2187 3 2369 2370 # CM CM
+2188 4 2370 2371 # CM CM
+2189 5 2371 2372 # CM CM
+2190 6 2372 2373 # CM CM
+2191 7 2373 2374 # CM CM
+2192 8 2374 2375 # CM CM
+2193 9 2375 2376 # CM CM
+2194 10 2376 2377 # CM CM
+2195 11 2377 2378 # CM CM
+2196 12 2378 2379 # CM CT
+2197 1 2380 2381 # HG CM
+2198 2 2381 2382 # CM CM
+2199 3 2382 2383 # CM CM
+2200 4 2383 2384 # CM CM
+2201 5 2384 2385 # CM CM
+2202 6 2385 2386 # CM CM
+2203 7 2386 2387 # CM CM
+2204 8 2387 2388 # CM CM
+2205 9 2388 2389 # CM CM
+2206 10 2389 2390 # CM CM
+2207 11 2390 2391 # CM CM
+2208 12 2391 2392 # CM CT
+2209 1 2393 2394 # HG CM
+2210 2 2394 2395 # CM CM
+2211 3 2395 2396 # CM CM
+2212 4 2396 2397 # CM CM
+2213 5 2397 2398 # CM CM
+2214 6 2398 2399 # CM CM
+2215 7 2399 2400 # CM CM
+2216 8 2400 2401 # CM CM
+2217 9 2401 2402 # CM CM
+2218 10 2402 2403 # CM CM
+2219 11 2403 2404 # CM CM
+2220 12 2404 2405 # CM CT
+2221 1 2406 2407 # HG CM
+2222 2 2407 2408 # CM CM
+2223 3 2408 2409 # CM CM
+2224 4 2409 2410 # CM CM
+2225 5 2410 2411 # CM CM
+2226 6 2411 2412 # CM CM
+2227 7 2412 2413 # CM CM
+2228 8 2413 2414 # CM CM
+2229 9 2414 2415 # CM CM
+2230 10 2415 2416 # CM CM
+2231 11 2416 2417 # CM CM
+2232 12 2417 2418 # CM CT
+2233 1 2419 2420 # HG CM
+2234 2 2420 2421 # CM CM
+2235 3 2421 2422 # CM CM
+2236 4 2422 2423 # CM CM
+2237 5 2423 2424 # CM CM
+2238 6 2424 2425 # CM CM
+2239 7 2425 2426 # CM CM
+2240 8 2426 2427 # CM CM
+2241 9 2427 2428 # CM CM
+2242 10 2428 2429 # CM CM
+2243 11 2429 2430 # CM CM
+2244 12 2430 2431 # CM CT
+2245 1 2432 2433 # HG CM
+2246 2 2433 2434 # CM CM
+2247 3 2434 2435 # CM CM
+2248 4 2435 2436 # CM CM
+2249 5 2436 2437 # CM CM
+2250 6 2437 2438 # CM CM
+2251 7 2438 2439 # CM CM
+2252 8 2439 2440 # CM CM
+2253 9 2440 2441 # CM CM
+2254 10 2441 2442 # CM CM
+2255 11 2442 2443 # CM CM
+2256 12 2443 2444 # CM CT
+2257 1 2445 2446 # HG CM
+2258 2 2446 2447 # CM CM
+2259 3 2447 2448 # CM CM
+2260 4 2448 2449 # CM CM
+2261 5 2449 2450 # CM CM
+2262 6 2450 2451 # CM CM
+2263 7 2451 2452 # CM CM
+2264 8 2452 2453 # CM CM
+2265 9 2453 2454 # CM CM
+2266 10 2454 2455 # CM CM
+2267 11 2455 2456 # CM CM
+2268 12 2456 2457 # CM CT
+2269 1 2458 2459 # HG CM
+2270 2 2459 2460 # CM CM
+2271 3 2460 2461 # CM CM
+2272 4 2461 2462 # CM CM
+2273 5 2462 2463 # CM CM
+2274 6 2463 2464 # CM CM
+2275 7 2464 2465 # CM CM
+2276 8 2465 2466 # CM CM
+2277 9 2466 2467 # CM CM
+2278 10 2467 2468 # CM CM
+2279 11 2468 2469 # CM CM
+2280 12 2469 2470 # CM CT
+2281 1 2471 2472 # HG CM
+2282 2 2472 2473 # CM CM
+2283 3 2473 2474 # CM CM
+2284 4 2474 2475 # CM CM
+2285 5 2475 2476 # CM CM
+2286 6 2476 2477 # CM CM
+2287 7 2477 2478 # CM CM
+2288 8 2478 2479 # CM CM
+2289 9 2479 2480 # CM CM
+2290 10 2480 2481 # CM CM
+2291 11 2481 2482 # CM CM
+2292 12 2482 2483 # CM CT
+2293 1 2484 2485 # HG CM
+2294 2 2485 2486 # CM CM
+2295 3 2486 2487 # CM CM
+2296 4 2487 2488 # CM CM
+2297 5 2488 2489 # CM CM
+2298 6 2489 2490 # CM CM
+2299 7 2490 2491 # CM CM
+2300 8 2491 2492 # CM CM
+2301 9 2492 2493 # CM CM
+2302 10 2493 2494 # CM CM
+2303 11 2494 2495 # CM CM
+2304 12 2495 2496 # CM CT
+2305 1 2497 2498 # HG CM
+2306 2 2498 2499 # CM CM
+2307 3 2499 2500 # CM CM
+2308 4 2500 2501 # CM CM
+2309 5 2501 2502 # CM CM
+2310 6 2502 2503 # CM CM
+2311 7 2503 2504 # CM CM
+2312 8 2504 2505 # CM CM
+2313 9 2505 2506 # CM CM
+2314 10 2506 2507 # CM CM
+2315 11 2507 2508 # CM CM
+2316 12 2508 2509 # CM CT
+2317 1 2510 2511 # HG CM
+2318 2 2511 2512 # CM CM
+2319 3 2512 2513 # CM CM
+2320 4 2513 2514 # CM CM
+2321 5 2514 2515 # CM CM
+2322 6 2515 2516 # CM CM
+2323 7 2516 2517 # CM CM
+2324 8 2517 2518 # CM CM
+2325 9 2518 2519 # CM CM
+2326 10 2519 2520 # CM CM
+2327 11 2520 2521 # CM CM
+2328 12 2521 2522 # CM CT
+2329 1 2523 2524 # HG CM
+2330 2 2524 2525 # CM CM
+2331 3 2525 2526 # CM CM
+2332 4 2526 2527 # CM CM
+2333 5 2527 2528 # CM CM
+2334 6 2528 2529 # CM CM
+2335 7 2529 2530 # CM CM
+2336 8 2530 2531 # CM CM
+2337 9 2531 2532 # CM CM
+2338 10 2532 2533 # CM CM
+2339 11 2533 2534 # CM CM
+2340 12 2534 2535 # CM CT
+2341 1 2536 2537 # HG CM
+2342 2 2537 2538 # CM CM
+2343 3 2538 2539 # CM CM
+2344 4 2539 2540 # CM CM
+2345 5 2540 2541 # CM CM
+2346 6 2541 2542 # CM CM
+2347 7 2542 2543 # CM CM
+2348 8 2543 2544 # CM CM
+2349 9 2544 2545 # CM CM
+2350 10 2545 2546 # CM CM
+2351 11 2546 2547 # CM CM
+2352 12 2547 2548 # CM CT
+2353 1 2549 2550 # HG CM
+2354 2 2550 2551 # CM CM
+2355 3 2551 2552 # CM CM
+2356 4 2552 2553 # CM CM
+2357 5 2553 2554 # CM CM
+2358 6 2554 2555 # CM CM
+2359 7 2555 2556 # CM CM
+2360 8 2556 2557 # CM CM
+2361 9 2557 2558 # CM CM
+2362 10 2558 2559 # CM CM
+2363 11 2559 2560 # CM CM
+2364 12 2560 2561 # CM CT
+2365 1 2562 2563 # HG CM
+2366 2 2563 2564 # CM CM
+2367 3 2564 2565 # CM CM
+2368 4 2565 2566 # CM CM
+2369 5 2566 2567 # CM CM
+2370 6 2567 2568 # CM CM
+2371 7 2568 2569 # CM CM
+2372 8 2569 2570 # CM CM
+2373 9 2570 2571 # CM CM
+2374 10 2571 2572 # CM CM
+2375 11 2572 2573 # CM CM
+2376 12 2573 2574 # CM CT
+2377 1 2575 2576 # HG CM
+2378 2 2576 2577 # CM CM
+2379 3 2577 2578 # CM CM
+2380 4 2578 2579 # CM CM
+2381 5 2579 2580 # CM CM
+2382 6 2580 2581 # CM CM
+2383 7 2581 2582 # CM CM
+2384 8 2582 2583 # CM CM
+2385 9 2583 2584 # CM CM
+2386 10 2584 2585 # CM CM
+2387 11 2585 2586 # CM CM
+2388 12 2586 2587 # CM CT
+2389 1 2588 2589 # HG CM
+2390 2 2589 2590 # CM CM
+2391 3 2590 2591 # CM CM
+2392 4 2591 2592 # CM CM
+2393 5 2592 2593 # CM CM
+2394 6 2593 2594 # CM CM
+2395 7 2594 2595 # CM CM
+2396 8 2595 2596 # CM CM
+2397 9 2596 2597 # CM CM
+2398 10 2597 2598 # CM CM
+2399 11 2598 2599 # CM CM
+2400 12 2599 2600 # CM CT
+2401 1 2601 2602 # HG CM
+2402 2 2602 2603 # CM CM
+2403 3 2603 2604 # CM CM
+2404 4 2604 2605 # CM CM
+2405 5 2605 2606 # CM CM
+2406 6 2606 2607 # CM CM
+2407 7 2607 2608 # CM CM
+2408 8 2608 2609 # CM CM
+2409 9 2609 2610 # CM CM
+2410 10 2610 2611 # CM CM
+2411 11 2611 2612 # CM CM
+2412 12 2612 2613 # CM CT
+2413 1 2614 2615 # HG CM
+2414 2 2615 2616 # CM CM
+2415 3 2616 2617 # CM CM
+2416 4 2617 2618 # CM CM
+2417 5 2618 2619 # CM CM
+2418 6 2619 2620 # CM CM
+2419 7 2620 2621 # CM CM
+2420 8 2621 2622 # CM CM
+2421 9 2622 2623 # CM CM
+2422 10 2623 2624 # CM CM
+2423 11 2624 2625 # CM CM
+2424 12 2625 2626 # CM CT
+2425 1 2627 2628 # HG CM
+2426 2 2628 2629 # CM CM
+2427 3 2629 2630 # CM CM
+2428 4 2630 2631 # CM CM
+2429 5 2631 2632 # CM CM
+2430 6 2632 2633 # CM CM
+2431 7 2633 2634 # CM CM
+2432 8 2634 2635 # CM CM
+2433 9 2635 2636 # CM CM
+2434 10 2636 2637 # CM CM
+2435 11 2637 2638 # CM CM
+2436 12 2638 2639 # CM CT
+2437 1 2640 2641 # HG CM
+2438 2 2641 2642 # CM CM
+2439 3 2642 2643 # CM CM
+2440 4 2643 2644 # CM CM
+2441 5 2644 2645 # CM CM
+2442 6 2645 2646 # CM CM
+2443 7 2646 2647 # CM CM
+2444 8 2647 2648 # CM CM
+2445 9 2648 2649 # CM CM
+2446 10 2649 2650 # CM CM
+2447 11 2650 2651 # CM CM
+2448 12 2651 2652 # CM CT
+2449 1 2653 2654 # HG CM
+2450 2 2654 2655 # CM CM
+2451 3 2655 2656 # CM CM
+2452 4 2656 2657 # CM CM
+2453 5 2657 2658 # CM CM
+2454 6 2658 2659 # CM CM
+2455 7 2659 2660 # CM CM
+2456 8 2660 2661 # CM CM
+2457 9 2661 2662 # CM CM
+2458 10 2662 2663 # CM CM
+2459 11 2663 2664 # CM CM
+2460 12 2664 2665 # CM CT
+2461 1 2666 2667 # HG CM
+2462 2 2667 2668 # CM CM
+2463 3 2668 2669 # CM CM
+2464 4 2669 2670 # CM CM
+2465 5 2670 2671 # CM CM
+2466 6 2671 2672 # CM CM
+2467 7 2672 2673 # CM CM
+2468 8 2673 2674 # CM CM
+2469 9 2674 2675 # CM CM
+2470 10 2675 2676 # CM CM
+2471 11 2676 2677 # CM CM
+2472 12 2677 2678 # CM CT
+2473 1 2679 2680 # HG CM
+2474 2 2680 2681 # CM CM
+2475 3 2681 2682 # CM CM
+2476 4 2682 2683 # CM CM
+2477 5 2683 2684 # CM CM
+2478 6 2684 2685 # CM CM
+2479 7 2685 2686 # CM CM
+2480 8 2686 2687 # CM CM
+2481 9 2687 2688 # CM CM
+2482 10 2688 2689 # CM CM
+2483 11 2689 2690 # CM CM
+2484 12 2690 2691 # CM CT
+2485 1 2692 2693 # HG CM
+2486 2 2693 2694 # CM CM
+2487 3 2694 2695 # CM CM
+2488 4 2695 2696 # CM CM
+2489 5 2696 2697 # CM CM
+2490 6 2697 2698 # CM CM
+2491 7 2698 2699 # CM CM
+2492 8 2699 2700 # CM CM
+2493 9 2700 2701 # CM CM
+2494 10 2701 2702 # CM CM
+2495 11 2702 2703 # CM CM
+2496 12 2703 2704 # CM CT
+2497 1 2705 2706 # HG CM
+2498 2 2706 2707 # CM CM
+2499 3 2707 2708 # CM CM
+2500 4 2708 2709 # CM CM
+2501 5 2709 2710 # CM CM
+2502 6 2710 2711 # CM CM
+2503 7 2711 2712 # CM CM
+2504 8 2712 2713 # CM CM
+2505 9 2713 2714 # CM CM
+2506 10 2714 2715 # CM CM
+2507 11 2715 2716 # CM CM
+2508 12 2716 2717 # CM CT
+2509 1 2718 2719 # HG CM
+2510 2 2719 2720 # CM CM
+2511 3 2720 2721 # CM CM
+2512 4 2721 2722 # CM CM
+2513 5 2722 2723 # CM CM
+2514 6 2723 2724 # CM CM
+2515 7 2724 2725 # CM CM
+2516 8 2725 2726 # CM CM
+2517 9 2726 2727 # CM CM
+2518 10 2727 2728 # CM CM
+2519 11 2728 2729 # CM CM
+2520 12 2729 2730 # CM CT
+2521 1 2731 2732 # HG CM
+2522 2 2732 2733 # CM CM
+2523 3 2733 2734 # CM CM
+2524 4 2734 2735 # CM CM
+2525 5 2735 2736 # CM CM
+2526 6 2736 2737 # CM CM
+2527 7 2737 2738 # CM CM
+2528 8 2738 2739 # CM CM
+2529 9 2739 2740 # CM CM
+2530 10 2740 2741 # CM CM
+2531 11 2741 2742 # CM CM
+2532 12 2742 2743 # CM CT
+2533 1 2744 2745 # HG CM
+2534 2 2745 2746 # CM CM
+2535 3 2746 2747 # CM CM
+2536 4 2747 2748 # CM CM
+2537 5 2748 2749 # CM CM
+2538 6 2749 2750 # CM CM
+2539 7 2750 2751 # CM CM
+2540 8 2751 2752 # CM CM
+2541 9 2752 2753 # CM CM
+2542 10 2753 2754 # CM CM
+2543 11 2754 2755 # CM CM
+2544 12 2755 2756 # CM CT
+2545 1 2757 2758 # HG CM
+2546 2 2758 2759 # CM CM
+2547 3 2759 2760 # CM CM
+2548 4 2760 2761 # CM CM
+2549 5 2761 2762 # CM CM
+2550 6 2762 2763 # CM CM
+2551 7 2763 2764 # CM CM
+2552 8 2764 2765 # CM CM
+2553 9 2765 2766 # CM CM
+2554 10 2766 2767 # CM CM
+2555 11 2767 2768 # CM CM
+2556 12 2768 2769 # CM CT
+2557 1 2770 2771 # HG CM
+2558 2 2771 2772 # CM CM
+2559 3 2772 2773 # CM CM
+2560 4 2773 2774 # CM CM
+2561 5 2774 2775 # CM CM
+2562 6 2775 2776 # CM CM
+2563 7 2776 2777 # CM CM
+2564 8 2777 2778 # CM CM
+2565 9 2778 2779 # CM CM
+2566 10 2779 2780 # CM CM
+2567 11 2780 2781 # CM CM
+2568 12 2781 2782 # CM CT
+2569 1 2783 2784 # HG CM
+2570 2 2784 2785 # CM CM
+2571 3 2785 2786 # CM CM
+2572 4 2786 2787 # CM CM
+2573 5 2787 2788 # CM CM
+2574 6 2788 2789 # CM CM
+2575 7 2789 2790 # CM CM
+2576 8 2790 2791 # CM CM
+2577 9 2791 2792 # CM CM
+2578 10 2792 2793 # CM CM
+2579 11 2793 2794 # CM CM
+2580 12 2794 2795 # CM CT
+2581 1 2796 2797 # HG CM
+2582 2 2797 2798 # CM CM
+2583 3 2798 2799 # CM CM
+2584 4 2799 2800 # CM CM
+2585 5 2800 2801 # CM CM
+2586 6 2801 2802 # CM CM
+2587 7 2802 2803 # CM CM
+2588 8 2803 2804 # CM CM
+2589 9 2804 2805 # CM CM
+2590 10 2805 2806 # CM CM
+2591 11 2806 2807 # CM CM
+2592 12 2807 2808 # CM CT
+2593 1 2809 2810 # HG CM
+2594 2 2810 2811 # CM CM
+2595 3 2811 2812 # CM CM
+2596 4 2812 2813 # CM CM
+2597 5 2813 2814 # CM CM
+2598 6 2814 2815 # CM CM
+2599 7 2815 2816 # CM CM
+2600 8 2816 2817 # CM CM
+2601 9 2817 2818 # CM CM
+2602 10 2818 2819 # CM CM
+2603 11 2819 2820 # CM CM
+2604 12 2820 2821 # CM CT
+2605 1 2822 2823 # HG CM
+2606 2 2823 2824 # CM CM
+2607 3 2824 2825 # CM CM
+2608 4 2825 2826 # CM CM
+2609 5 2826 2827 # CM CM
+2610 6 2827 2828 # CM CM
+2611 7 2828 2829 # CM CM
+2612 8 2829 2830 # CM CM
+2613 9 2830 2831 # CM CM
+2614 10 2831 2832 # CM CM
+2615 11 2832 2833 # CM CM
+2616 12 2833 2834 # CM CT
+2617 1 2835 2836 # HG CM
+2618 2 2836 2837 # CM CM
+2619 3 2837 2838 # CM CM
+2620 4 2838 2839 # CM CM
+2621 5 2839 2840 # CM CM
+2622 6 2840 2841 # CM CM
+2623 7 2841 2842 # CM CM
+2624 8 2842 2843 # CM CM
+2625 9 2843 2844 # CM CM
+2626 10 2844 2845 # CM CM
+2627 11 2845 2846 # CM CM
+2628 12 2846 2847 # CM CT
+2629 1 2848 2849 # HG CM
+2630 2 2849 2850 # CM CM
+2631 3 2850 2851 # CM CM
+2632 4 2851 2852 # CM CM
+2633 5 2852 2853 # CM CM
+2634 6 2853 2854 # CM CM
+2635 7 2854 2855 # CM CM
+2636 8 2855 2856 # CM CM
+2637 9 2856 2857 # CM CM
+2638 10 2857 2858 # CM CM
+2639 11 2858 2859 # CM CM
+2640 12 2859 2860 # CM CT
+2641 1 2861 2862 # HG CM
+2642 2 2862 2863 # CM CM
+2643 3 2863 2864 # CM CM
+2644 4 2864 2865 # CM CM
+2645 5 2865 2866 # CM CM
+2646 6 2866 2867 # CM CM
+2647 7 2867 2868 # CM CM
+2648 8 2868 2869 # CM CM
+2649 9 2869 2870 # CM CM
+2650 10 2870 2871 # CM CM
+2651 11 2871 2872 # CM CM
+2652 12 2872 2873 # CM CT
+2653 1 2874 2875 # HG CM
+2654 2 2875 2876 # CM CM
+2655 3 2876 2877 # CM CM
+2656 4 2877 2878 # CM CM
+2657 5 2878 2879 # CM CM
+2658 6 2879 2880 # CM CM
+2659 7 2880 2881 # CM CM
+2660 8 2881 2882 # CM CM
+2661 9 2882 2883 # CM CM
+2662 10 2883 2884 # CM CM
+2663 11 2884 2885 # CM CM
+2664 12 2885 2886 # CM CT
+2665 1 2887 2888 # HG CM
+2666 2 2888 2889 # CM CM
+2667 3 2889 2890 # CM CM
+2668 4 2890 2891 # CM CM
+2669 5 2891 2892 # CM CM
+2670 6 2892 2893 # CM CM
+2671 7 2893 2894 # CM CM
+2672 8 2894 2895 # CM CM
+2673 9 2895 2896 # CM CM
+2674 10 2896 2897 # CM CM
+2675 11 2897 2898 # CM CM
+2676 12 2898 2899 # CM CT
+2677 1 2900 2901 # HG CM
+2678 2 2901 2902 # CM CM
+2679 3 2902 2903 # CM CM
+2680 4 2903 2904 # CM CM
+2681 5 2904 2905 # CM CM
+2682 6 2905 2906 # CM CM
+2683 7 2906 2907 # CM CM
+2684 8 2907 2908 # CM CM
+2685 9 2908 2909 # CM CM
+2686 10 2909 2910 # CM CM
+2687 11 2910 2911 # CM CM
+2688 12 2911 2912 # CM CT
+2689 1 2913 2914 # HG CM
+2690 2 2914 2915 # CM CM
+2691 3 2915 2916 # CM CM
+2692 4 2916 2917 # CM CM
+2693 5 2917 2918 # CM CM
+2694 6 2918 2919 # CM CM
+2695 7 2919 2920 # CM CM
+2696 8 2920 2921 # CM CM
+2697 9 2921 2922 # CM CM
+2698 10 2922 2923 # CM CM
+2699 11 2923 2924 # CM CM
+2700 12 2924 2925 # CM CT
+2701 1 2926 2927 # HG CM
+2702 2 2927 2928 # CM CM
+2703 3 2928 2929 # CM CM
+2704 4 2929 2930 # CM CM
+2705 5 2930 2931 # CM CM
+2706 6 2931 2932 # CM CM
+2707 7 2932 2933 # CM CM
+2708 8 2933 2934 # CM CM
+2709 9 2934 2935 # CM CM
+2710 10 2935 2936 # CM CM
+2711 11 2936 2937 # CM CM
+2712 12 2937 2938 # CM CT
+2713 1 2939 2940 # HG CM
+2714 2 2940 2941 # CM CM
+2715 3 2941 2942 # CM CM
+2716 4 2942 2943 # CM CM
+2717 5 2943 2944 # CM CM
+2718 6 2944 2945 # CM CM
+2719 7 2945 2946 # CM CM
+2720 8 2946 2947 # CM CM
+2721 9 2947 2948 # CM CM
+2722 10 2948 2949 # CM CM
+2723 11 2949 2950 # CM CM
+2724 12 2950 2951 # CM CT
+2725 1 2952 2953 # HG CM
+2726 2 2953 2954 # CM CM
+2727 3 2954 2955 # CM CM
+2728 4 2955 2956 # CM CM
+2729 5 2956 2957 # CM CM
+2730 6 2957 2958 # CM CM
+2731 7 2958 2959 # CM CM
+2732 8 2959 2960 # CM CM
+2733 9 2960 2961 # CM CM
+2734 10 2961 2962 # CM CM
+2735 11 2962 2963 # CM CM
+2736 12 2963 2964 # CM CT
+2737 1 2965 2966 # HG CM
+2738 2 2966 2967 # CM CM
+2739 3 2967 2968 # CM CM
+2740 4 2968 2969 # CM CM
+2741 5 2969 2970 # CM CM
+2742 6 2970 2971 # CM CM
+2743 7 2971 2972 # CM CM
+2744 8 2972 2973 # CM CM
+2745 9 2973 2974 # CM CM
+2746 10 2974 2975 # CM CM
+2747 11 2975 2976 # CM CM
+2748 12 2976 2977 # CM CT
+2749 1 2978 2979 # HG CM
+2750 2 2979 2980 # CM CM
+2751 3 2980 2981 # CM CM
+2752 4 2981 2982 # CM CM
+2753 5 2982 2983 # CM CM
+2754 6 2983 2984 # CM CM
+2755 7 2984 2985 # CM CM
+2756 8 2985 2986 # CM CM
+2757 9 2986 2987 # CM CM
+2758 10 2987 2988 # CM CM
+2759 11 2988 2989 # CM CM
+2760 12 2989 2990 # CM CT
+2761 1 2991 2992 # HG CM
+2762 2 2992 2993 # CM CM
+2763 3 2993 2994 # CM CM
+2764 4 2994 2995 # CM CM
+2765 5 2995 2996 # CM CM
+2766 6 2996 2997 # CM CM
+2767 7 2997 2998 # CM CM
+2768 8 2998 2999 # CM CM
+2769 9 2999 3000 # CM CM
+2770 10 3000 3001 # CM CM
+2771 11 3001 3002 # CM CM
+2772 12 3002 3003 # CM CT
+2773 1 3004 3005 # HG CM
+2774 2 3005 3006 # CM CM
+2775 3 3006 3007 # CM CM
+2776 4 3007 3008 # CM CM
+2777 5 3008 3009 # CM CM
+2778 6 3009 3010 # CM CM
+2779 7 3010 3011 # CM CM
+2780 8 3011 3012 # CM CM
+2781 9 3012 3013 # CM CM
+2782 10 3013 3014 # CM CM
+2783 11 3014 3015 # CM CM
+2784 12 3015 3016 # CM CT
+2785 1 3017 3018 # HG CM
+2786 2 3018 3019 # CM CM
+2787 3 3019 3020 # CM CM
+2788 4 3020 3021 # CM CM
+2789 5 3021 3022 # CM CM
+2790 6 3022 3023 # CM CM
+2791 7 3023 3024 # CM CM
+2792 8 3024 3025 # CM CM
+2793 9 3025 3026 # CM CM
+2794 10 3026 3027 # CM CM
+2795 11 3027 3028 # CM CM
+2796 12 3028 3029 # CM CT
+2797 1 3030 3031 # HG CM
+2798 2 3031 3032 # CM CM
+2799 3 3032 3033 # CM CM
+2800 4 3033 3034 # CM CM
+2801 5 3034 3035 # CM CM
+2802 6 3035 3036 # CM CM
+2803 7 3036 3037 # CM CM
+2804 8 3037 3038 # CM CM
+2805 9 3038 3039 # CM CM
+2806 10 3039 3040 # CM CM
+2807 11 3040 3041 # CM CM
+2808 12 3041 3042 # CM CT
+2809 1 3043 3044 # HG CM
+2810 2 3044 3045 # CM CM
+2811 3 3045 3046 # CM CM
+2812 4 3046 3047 # CM CM
+2813 5 3047 3048 # CM CM
+2814 6 3048 3049 # CM CM
+2815 7 3049 3050 # CM CM
+2816 8 3050 3051 # CM CM
+2817 9 3051 3052 # CM CM
+2818 10 3052 3053 # CM CM
+2819 11 3053 3054 # CM CM
+2820 12 3054 3055 # CM CT
+2821 1 3056 3057 # HG CM
+2822 2 3057 3058 # CM CM
+2823 3 3058 3059 # CM CM
+2824 4 3059 3060 # CM CM
+2825 5 3060 3061 # CM CM
+2826 6 3061 3062 # CM CM
+2827 7 3062 3063 # CM CM
+2828 8 3063 3064 # CM CM
+2829 9 3064 3065 # CM CM
+2830 10 3065 3066 # CM CM
+2831 11 3066 3067 # CM CM
+2832 12 3067 3068 # CM CT
+2833 1 3069 3070 # HG CM
+2834 2 3070 3071 # CM CM
+2835 3 3071 3072 # CM CM
+2836 4 3072 3073 # CM CM
+2837 5 3073 3074 # CM CM
+2838 6 3074 3075 # CM CM
+2839 7 3075 3076 # CM CM
+2840 8 3076 3077 # CM CM
+2841 9 3077 3078 # CM CM
+2842 10 3078 3079 # CM CM
+2843 11 3079 3080 # CM CM
+2844 12 3080 3081 # CM CT
+2845 1 3082 3083 # HG CM
+2846 2 3083 3084 # CM CM
+2847 3 3084 3085 # CM CM
+2848 4 3085 3086 # CM CM
+2849 5 3086 3087 # CM CM
+2850 6 3087 3088 # CM CM
+2851 7 3088 3089 # CM CM
+2852 8 3089 3090 # CM CM
+2853 9 3090 3091 # CM CM
+2854 10 3091 3092 # CM CM
+2855 11 3092 3093 # CM CM
+2856 12 3093 3094 # CM CT
+2857 1 3095 3096 # HG CM
+2858 2 3096 3097 # CM CM
+2859 3 3097 3098 # CM CM
+2860 4 3098 3099 # CM CM
+2861 5 3099 3100 # CM CM
+2862 6 3100 3101 # CM CM
+2863 7 3101 3102 # CM CM
+2864 8 3102 3103 # CM CM
+2865 9 3103 3104 # CM CM
+2866 10 3104 3105 # CM CM
+2867 11 3105 3106 # CM CM
+2868 12 3106 3107 # CM CT
+2869 1 3108 3109 # HG CM
+2870 2 3109 3110 # CM CM
+2871 3 3110 3111 # CM CM
+2872 4 3111 3112 # CM CM
+2873 5 3112 3113 # CM CM
+2874 6 3113 3114 # CM CM
+2875 7 3114 3115 # CM CM
+2876 8 3115 3116 # CM CM
+2877 9 3116 3117 # CM CM
+2878 10 3117 3118 # CM CM
+2879 11 3118 3119 # CM CM
+2880 12 3119 3120 # CM CT
+2881 1 3121 3122 # HG CM
+2882 2 3122 3123 # CM CM
+2883 3 3123 3124 # CM CM
+2884 4 3124 3125 # CM CM
+2885 5 3125 3126 # CM CM
+2886 6 3126 3127 # CM CM
+2887 7 3127 3128 # CM CM
+2888 8 3128 3129 # CM CM
+2889 9 3129 3130 # CM CM
+2890 10 3130 3131 # CM CM
+2891 11 3131 3132 # CM CM
+2892 12 3132 3133 # CM CT
+2893 1 3134 3135 # HG CM
+2894 2 3135 3136 # CM CM
+2895 3 3136 3137 # CM CM
+2896 4 3137 3138 # CM CM
+2897 5 3138 3139 # CM CM
+2898 6 3139 3140 # CM CM
+2899 7 3140 3141 # CM CM
+2900 8 3141 3142 # CM CM
+2901 9 3142 3143 # CM CM
+2902 10 3143 3144 # CM CM
+2903 11 3144 3145 # CM CM
+2904 12 3145 3146 # CM CT
+2905 1 3147 3148 # HG CM
+2906 2 3148 3149 # CM CM
+2907 3 3149 3150 # CM CM
+2908 4 3150 3151 # CM CM
+2909 5 3151 3152 # CM CM
+2910 6 3152 3153 # CM CM
+2911 7 3153 3154 # CM CM
+2912 8 3154 3155 # CM CM
+2913 9 3155 3156 # CM CM
+2914 10 3156 3157 # CM CM
+2915 11 3157 3158 # CM CM
+2916 12 3158 3159 # CM CT
+2917 1 3160 3161 # HG CM
+2918 2 3161 3162 # CM CM
+2919 3 3162 3163 # CM CM
+2920 4 3163 3164 # CM CM
+2921 5 3164 3165 # CM CM
+2922 6 3165 3166 # CM CM
+2923 7 3166 3167 # CM CM
+2924 8 3167 3168 # CM CM
+2925 9 3168 3169 # CM CM
+2926 10 3169 3170 # CM CM
+2927 11 3170 3171 # CM CM
+2928 12 3171 3172 # CM CT
+2929 1 3173 3174 # HG CM
+2930 2 3174 3175 # CM CM
+2931 3 3175 3176 # CM CM
+2932 4 3176 3177 # CM CM
+2933 5 3177 3178 # CM CM
+2934 6 3178 3179 # CM CM
+2935 7 3179 3180 # CM CM
+2936 8 3180 3181 # CM CM
+2937 9 3181 3182 # CM CM
+2938 10 3182 3183 # CM CM
+2939 11 3183 3184 # CM CM
+2940 12 3184 3185 # CM CT
+2941 1 3186 3187 # HG CM
+2942 2 3187 3188 # CM CM
+2943 3 3188 3189 # CM CM
+2944 4 3189 3190 # CM CM
+2945 5 3190 3191 # CM CM
+2946 6 3191 3192 # CM CM
+2947 7 3192 3193 # CM CM
+2948 8 3193 3194 # CM CM
+2949 9 3194 3195 # CM CM
+2950 10 3195 3196 # CM CM
+2951 11 3196 3197 # CM CM
+2952 12 3197 3198 # CM CT
+2953 1 3199 3200 # HG CM
+2954 2 3200 3201 # CM CM
+2955 3 3201 3202 # CM CM
+2956 4 3202 3203 # CM CM
+2957 5 3203 3204 # CM CM
+2958 6 3204 3205 # CM CM
+2959 7 3205 3206 # CM CM
+2960 8 3206 3207 # CM CM
+2961 9 3207 3208 # CM CM
+2962 10 3208 3209 # CM CM
+2963 11 3209 3210 # CM CM
+2964 12 3210 3211 # CM CT
+2965 1 3212 3213 # HG CM
+2966 2 3213 3214 # CM CM
+2967 3 3214 3215 # CM CM
+2968 4 3215 3216 # CM CM
+2969 5 3216 3217 # CM CM
+2970 6 3217 3218 # CM CM
+2971 7 3218 3219 # CM CM
+2972 8 3219 3220 # CM CM
+2973 9 3220 3221 # CM CM
+2974 10 3221 3222 # CM CM
+2975 11 3222 3223 # CM CM
+2976 12 3223 3224 # CM CT
+2977 1 3225 3226 # HG CM
+2978 2 3226 3227 # CM CM
+2979 3 3227 3228 # CM CM
+2980 4 3228 3229 # CM CM
+2981 5 3229 3230 # CM CM
+2982 6 3230 3231 # CM CM
+2983 7 3231 3232 # CM CM
+2984 8 3232 3233 # CM CM
+2985 9 3233 3234 # CM CM
+2986 10 3234 3235 # CM CM
+2987 11 3235 3236 # CM CM
+2988 12 3236 3237 # CM CT
+2989 1 3238 3239 # HG CM
+2990 2 3239 3240 # CM CM
+2991 3 3240 3241 # CM CM
+2992 4 3241 3242 # CM CM
+2993 5 3242 3243 # CM CM
+2994 6 3243 3244 # CM CM
+2995 7 3244 3245 # CM CM
+2996 8 3245 3246 # CM CM
+2997 9 3246 3247 # CM CM
+2998 10 3247 3248 # CM CM
+2999 11 3248 3249 # CM CM
+3000 12 3249 3250 # CM CT
+3001 1 3251 3252 # HG CM
+3002 2 3252 3253 # CM CM
+3003 3 3253 3254 # CM CM
+3004 4 3254 3255 # CM CM
+3005 5 3255 3256 # CM CM
+3006 6 3256 3257 # CM CM
+3007 7 3257 3258 # CM CM
+3008 8 3258 3259 # CM CM
+3009 9 3259 3260 # CM CM
+3010 10 3260 3261 # CM CM
+3011 11 3261 3262 # CM CM
+3012 12 3262 3263 # CM CT
+3013 1 3264 3265 # HG CM
+3014 2 3265 3266 # CM CM
+3015 3 3266 3267 # CM CM
+3016 4 3267 3268 # CM CM
+3017 5 3268 3269 # CM CM
+3018 6 3269 3270 # CM CM
+3019 7 3270 3271 # CM CM
+3020 8 3271 3272 # CM CM
+3021 9 3272 3273 # CM CM
+3022 10 3273 3274 # CM CM
+3023 11 3274 3275 # CM CM
+3024 12 3275 3276 # CM CT
+3025 1 3277 3278 # HG CM
+3026 2 3278 3279 # CM CM
+3027 3 3279 3280 # CM CM
+3028 4 3280 3281 # CM CM
+3029 5 3281 3282 # CM CM
+3030 6 3282 3283 # CM CM
+3031 7 3283 3284 # CM CM
+3032 8 3284 3285 # CM CM
+3033 9 3285 3286 # CM CM
+3034 10 3286 3287 # CM CM
+3035 11 3287 3288 # CM CM
+3036 12 3288 3289 # CM CT
+3037 1 3290 3291 # HG CM
+3038 2 3291 3292 # CM CM
+3039 3 3292 3293 # CM CM
+3040 4 3293 3294 # CM CM
+3041 5 3294 3295 # CM CM
+3042 6 3295 3296 # CM CM
+3043 7 3296 3297 # CM CM
+3044 8 3297 3298 # CM CM
+3045 9 3298 3299 # CM CM
+3046 10 3299 3300 # CM CM
+3047 11 3300 3301 # CM CM
+3048 12 3301 3302 # CM CT
+3049 1 3303 3304 # HG CM
+3050 2 3304 3305 # CM CM
+3051 3 3305 3306 # CM CM
+3052 4 3306 3307 # CM CM
+3053 5 3307 3308 # CM CM
+3054 6 3308 3309 # CM CM
+3055 7 3309 3310 # CM CM
+3056 8 3310 3311 # CM CM
+3057 9 3311 3312 # CM CM
+3058 10 3312 3313 # CM CM
+3059 11 3313 3314 # CM CM
+3060 12 3314 3315 # CM CT
+3061 1 3316 3317 # HG CM
+3062 2 3317 3318 # CM CM
+3063 3 3318 3319 # CM CM
+3064 4 3319 3320 # CM CM
+3065 5 3320 3321 # CM CM
+3066 6 3321 3322 # CM CM
+3067 7 3322 3323 # CM CM
+3068 8 3323 3324 # CM CM
+3069 9 3324 3325 # CM CM
+3070 10 3325 3326 # CM CM
+3071 11 3326 3327 # CM CM
+3072 12 3327 3328 # CM CT
+3073 1 3329 3330 # HG CM
+3074 2 3330 3331 # CM CM
+3075 3 3331 3332 # CM CM
+3076 4 3332 3333 # CM CM
+3077 5 3333 3334 # CM CM
+3078 6 3334 3335 # CM CM
+3079 7 3335 3336 # CM CM
+3080 8 3336 3337 # CM CM
+3081 9 3337 3338 # CM CM
+3082 10 3338 3339 # CM CM
+3083 11 3339 3340 # CM CM
+3084 12 3340 3341 # CM CT
+3085 1 3342 3343 # HG CM
+3086 2 3343 3344 # CM CM
+3087 3 3344 3345 # CM CM
+3088 4 3345 3346 # CM CM
+3089 5 3346 3347 # CM CM
+3090 6 3347 3348 # CM CM
+3091 7 3348 3349 # CM CM
+3092 8 3349 3350 # CM CM
+3093 9 3350 3351 # CM CM
+3094 10 3351 3352 # CM CM
+3095 11 3352 3353 # CM CM
+3096 12 3353 3354 # CM CT
+3097 1 3355 3356 # HG CM
+3098 2 3356 3357 # CM CM
+3099 3 3357 3358 # CM CM
+3100 4 3358 3359 # CM CM
+3101 5 3359 3360 # CM CM
+3102 6 3360 3361 # CM CM
+3103 7 3361 3362 # CM CM
+3104 8 3362 3363 # CM CM
+3105 9 3363 3364 # CM CM
+3106 10 3364 3365 # CM CM
+3107 11 3365 3366 # CM CM
+3108 12 3366 3367 # CM CT
+3109 1 3368 3369 # HG CM
+3110 2 3369 3370 # CM CM
+3111 3 3370 3371 # CM CM
+3112 4 3371 3372 # CM CM
+3113 5 3372 3373 # CM CM
+3114 6 3373 3374 # CM CM
+3115 7 3374 3375 # CM CM
+3116 8 3375 3376 # CM CM
+3117 9 3376 3377 # CM CM
+3118 10 3377 3378 # CM CM
+3119 11 3378 3379 # CM CM
+3120 12 3379 3380 # CM CT
+3121 1 3381 3382 # HG CM
+3122 2 3382 3383 # CM CM
+3123 3 3383 3384 # CM CM
+3124 4 3384 3385 # CM CM
+3125 5 3385 3386 # CM CM
+3126 6 3386 3387 # CM CM
+3127 7 3387 3388 # CM CM
+3128 8 3388 3389 # CM CM
+3129 9 3389 3390 # CM CM
+3130 10 3390 3391 # CM CM
+3131 11 3391 3392 # CM CM
+3132 12 3392 3393 # CM CT
+3133 1 3394 3395 # HG CM
+3134 2 3395 3396 # CM CM
+3135 3 3396 3397 # CM CM
+3136 4 3397 3398 # CM CM
+3137 5 3398 3399 # CM CM
+3138 6 3399 3400 # CM CM
+3139 7 3400 3401 # CM CM
+3140 8 3401 3402 # CM CM
+3141 9 3402 3403 # CM CM
+3142 10 3403 3404 # CM CM
+3143 11 3404 3405 # CM CM
+3144 12 3405 3406 # CM CT
+3145 1 3407 3408 # HG CM
+3146 2 3408 3409 # CM CM
+3147 3 3409 3410 # CM CM
+3148 4 3410 3411 # CM CM
+3149 5 3411 3412 # CM CM
+3150 6 3412 3413 # CM CM
+3151 7 3413 3414 # CM CM
+3152 8 3414 3415 # CM CM
+3153 9 3415 3416 # CM CM
+3154 10 3416 3417 # CM CM
+3155 11 3417 3418 # CM CM
+3156 12 3418 3419 # CM CT
+3157 1 3420 3421 # HG CM
+3158 2 3421 3422 # CM CM
+3159 3 3422 3423 # CM CM
+3160 4 3423 3424 # CM CM
+3161 5 3424 3425 # CM CM
+3162 6 3425 3426 # CM CM
+3163 7 3426 3427 # CM CM
+3164 8 3427 3428 # CM CM
+3165 9 3428 3429 # CM CM
+3166 10 3429 3430 # CM CM
+3167 11 3430 3431 # CM CM
+3168 12 3431 3432 # CM CT
+3169 1 3433 3434 # HG CM
+3170 2 3434 3435 # CM CM
+3171 3 3435 3436 # CM CM
+3172 4 3436 3437 # CM CM
+3173 5 3437 3438 # CM CM
+3174 6 3438 3439 # CM CM
+3175 7 3439 3440 # CM CM
+3176 8 3440 3441 # CM CM
+3177 9 3441 3442 # CM CM
+3178 10 3442 3443 # CM CM
+3179 11 3443 3444 # CM CM
+3180 12 3444 3445 # CM CT
+3181 1 3446 3447 # HG CM
+3182 2 3447 3448 # CM CM
+3183 3 3448 3449 # CM CM
+3184 4 3449 3450 # CM CM
+3185 5 3450 3451 # CM CM
+3186 6 3451 3452 # CM CM
+3187 7 3452 3453 # CM CM
+3188 8 3453 3454 # CM CM
+3189 9 3454 3455 # CM CM
+3190 10 3455 3456 # CM CM
+3191 11 3456 3457 # CM CM
+3192 12 3457 3458 # CM CT
+3193 1 3459 3460 # HG CM
+3194 2 3460 3461 # CM CM
+3195 3 3461 3462 # CM CM
+3196 4 3462 3463 # CM CM
+3197 5 3463 3464 # CM CM
+3198 6 3464 3465 # CM CM
+3199 7 3465 3466 # CM CM
+3200 8 3466 3467 # CM CM
+3201 9 3467 3468 # CM CM
+3202 10 3468 3469 # CM CM
+3203 11 3469 3470 # CM CM
+3204 12 3470 3471 # CM CT
+3205 1 3472 3473 # HG CM
+3206 2 3473 3474 # CM CM
+3207 3 3474 3475 # CM CM
+3208 4 3475 3476 # CM CM
+3209 5 3476 3477 # CM CM
+3210 6 3477 3478 # CM CM
+3211 7 3478 3479 # CM CM
+3212 8 3479 3480 # CM CM
+3213 9 3480 3481 # CM CM
+3214 10 3481 3482 # CM CM
+3215 11 3482 3483 # CM CM
+3216 12 3483 3484 # CM CT
+3217 1 3485 3486 # HG CM
+3218 2 3486 3487 # CM CM
+3219 3 3487 3488 # CM CM
+3220 4 3488 3489 # CM CM
+3221 5 3489 3490 # CM CM
+3222 6 3490 3491 # CM CM
+3223 7 3491 3492 # CM CM
+3224 8 3492 3493 # CM CM
+3225 9 3493 3494 # CM CM
+3226 10 3494 3495 # CM CM
+3227 11 3495 3496 # CM CM
+3228 12 3496 3497 # CM CT
+3229 1 3498 3499 # HG CM
+3230 2 3499 3500 # CM CM
+3231 3 3500 3501 # CM CM
+3232 4 3501 3502 # CM CM
+3233 5 3502 3503 # CM CM
+3234 6 3503 3504 # CM CM
+3235 7 3504 3505 # CM CM
+3236 8 3505 3506 # CM CM
+3237 9 3506 3507 # CM CM
+3238 10 3507 3508 # CM CM
+3239 11 3508 3509 # CM CM
+3240 12 3509 3510 # CM CT
+3241 1 3511 3512 # HG CM
+3242 2 3512 3513 # CM CM
+3243 3 3513 3514 # CM CM
+3244 4 3514 3515 # CM CM
+3245 5 3515 3516 # CM CM
+3246 6 3516 3517 # CM CM
+3247 7 3517 3518 # CM CM
+3248 8 3518 3519 # CM CM
+3249 9 3519 3520 # CM CM
+3250 10 3520 3521 # CM CM
+3251 11 3521 3522 # CM CM
+3252 12 3522 3523 # CM CT
+3253 1 3524 3525 # HG CM
+3254 2 3525 3526 # CM CM
+3255 3 3526 3527 # CM CM
+3256 4 3527 3528 # CM CM
+3257 5 3528 3529 # CM CM
+3258 6 3529 3530 # CM CM
+3259 7 3530 3531 # CM CM
+3260 8 3531 3532 # CM CM
+3261 9 3532 3533 # CM CM
+3262 10 3533 3534 # CM CM
+3263 11 3534 3535 # CM CM
+3264 12 3535 3536 # CM CT
+3265 1 3537 3538 # HG CM
+3266 2 3538 3539 # CM CM
+3267 3 3539 3540 # CM CM
+3268 4 3540 3541 # CM CM
+3269 5 3541 3542 # CM CM
+3270 6 3542 3543 # CM CM
+3271 7 3543 3544 # CM CM
+3272 8 3544 3545 # CM CM
+3273 9 3545 3546 # CM CM
+3274 10 3546 3547 # CM CM
+3275 11 3547 3548 # CM CM
+3276 12 3548 3549 # CM CT
+3277 1 3550 3551 # HG CM
+3278 2 3551 3552 # CM CM
+3279 3 3552 3553 # CM CM
+3280 4 3553 3554 # CM CM
+3281 5 3554 3555 # CM CM
+3282 6 3555 3556 # CM CM
+3283 7 3556 3557 # CM CM
+3284 8 3557 3558 # CM CM
+3285 9 3558 3559 # CM CM
+3286 10 3559 3560 # CM CM
+3287 11 3560 3561 # CM CM
+3288 12 3561 3562 # CM CT
+3289 1 3563 3564 # HG CM
+3290 2 3564 3565 # CM CM
+3291 3 3565 3566 # CM CM
+3292 4 3566 3567 # CM CM
+3293 5 3567 3568 # CM CM
+3294 6 3568 3569 # CM CM
+3295 7 3569 3570 # CM CM
+3296 8 3570 3571 # CM CM
+3297 9 3571 3572 # CM CM
+3298 10 3572 3573 # CM CM
+3299 11 3573 3574 # CM CM
+3300 12 3574 3575 # CM CT
+3301 1 3576 3577 # HG CM
+3302 2 3577 3578 # CM CM
+3303 3 3578 3579 # CM CM
+3304 4 3579 3580 # CM CM
+3305 5 3580 3581 # CM CM
+3306 6 3581 3582 # CM CM
+3307 7 3582 3583 # CM CM
+3308 8 3583 3584 # CM CM
+3309 9 3584 3585 # CM CM
+3310 10 3585 3586 # CM CM
+3311 11 3586 3587 # CM CM
+3312 12 3587 3588 # CM CT
+3313 1 3589 3590 # HG CM
+3314 2 3590 3591 # CM CM
+3315 3 3591 3592 # CM CM
+3316 4 3592 3593 # CM CM
+3317 5 3593 3594 # CM CM
+3318 6 3594 3595 # CM CM
+3319 7 3595 3596 # CM CM
+3320 8 3596 3597 # CM CM
+3321 9 3597 3598 # CM CM
+3322 10 3598 3599 # CM CM
+3323 11 3599 3600 # CM CM
+3324 12 3600 3601 # CM CT
+3325 1 3602 3603 # HG CM
+3326 2 3603 3604 # CM CM
+3327 3 3604 3605 # CM CM
+3328 4 3605 3606 # CM CM
+3329 5 3606 3607 # CM CM
+3330 6 3607 3608 # CM CM
+3331 7 3608 3609 # CM CM
+3332 8 3609 3610 # CM CM
+3333 9 3610 3611 # CM CM
+3334 10 3611 3612 # CM CM
+3335 11 3612 3613 # CM CM
+3336 12 3613 3614 # CM CT
+3337 1 3615 3616 # HG CM
+3338 2 3616 3617 # CM CM
+3339 3 3617 3618 # CM CM
+3340 4 3618 3619 # CM CM
+3341 5 3619 3620 # CM CM
+3342 6 3620 3621 # CM CM
+3343 7 3621 3622 # CM CM
+3344 8 3622 3623 # CM CM
+3345 9 3623 3624 # CM CM
+3346 10 3624 3625 # CM CM
+3347 11 3625 3626 # CM CM
+3348 12 3626 3627 # CM CT
+3349 1 3628 3629 # HG CM
+3350 2 3629 3630 # CM CM
+3351 3 3630 3631 # CM CM
+3352 4 3631 3632 # CM CM
+3353 5 3632 3633 # CM CM
+3354 6 3633 3634 # CM CM
+3355 7 3634 3635 # CM CM
+3356 8 3635 3636 # CM CM
+3357 9 3636 3637 # CM CM
+3358 10 3637 3638 # CM CM
+3359 11 3638 3639 # CM CM
+3360 12 3639 3640 # CM CT
+3361 1 3641 3642 # HG CM
+3362 2 3642 3643 # CM CM
+3363 3 3643 3644 # CM CM
+3364 4 3644 3645 # CM CM
+3365 5 3645 3646 # CM CM
+3366 6 3646 3647 # CM CM
+3367 7 3647 3648 # CM CM
+3368 8 3648 3649 # CM CM
+3369 9 3649 3650 # CM CM
+3370 10 3650 3651 # CM CM
+3371 11 3651 3652 # CM CM
+3372 12 3652 3653 # CM CT
+3373 1 3654 3655 # HG CM
+3374 2 3655 3656 # CM CM
+3375 3 3656 3657 # CM CM
+3376 4 3657 3658 # CM CM
+3377 5 3658 3659 # CM CM
+3378 6 3659 3660 # CM CM
+3379 7 3660 3661 # CM CM
+3380 8 3661 3662 # CM CM
+3381 9 3662 3663 # CM CM
+3382 10 3663 3664 # CM CM
+3383 11 3664 3665 # CM CM
+3384 12 3665 3666 # CM CT
+3385 1 3667 3668 # HG CM
+3386 2 3668 3669 # CM CM
+3387 3 3669 3670 # CM CM
+3388 4 3670 3671 # CM CM
+3389 5 3671 3672 # CM CM
+3390 6 3672 3673 # CM CM
+3391 7 3673 3674 # CM CM
+3392 8 3674 3675 # CM CM
+3393 9 3675 3676 # CM CM
+3394 10 3676 3677 # CM CM
+3395 11 3677 3678 # CM CM
+3396 12 3678 3679 # CM CT
+3397 1 3680 3681 # HG CM
+3398 2 3681 3682 # CM CM
+3399 3 3682 3683 # CM CM
+3400 4 3683 3684 # CM CM
+3401 5 3684 3685 # CM CM
+3402 6 3685 3686 # CM CM
+3403 7 3686 3687 # CM CM
+3404 8 3687 3688 # CM CM
+3405 9 3688 3689 # CM CM
+3406 10 3689 3690 # CM CM
+3407 11 3690 3691 # CM CM
+3408 12 3691 3692 # CM CT
+3409 1 3693 3694 # HG CM
+3410 2 3694 3695 # CM CM
+3411 3 3695 3696 # CM CM
+3412 4 3696 3697 # CM CM
+3413 5 3697 3698 # CM CM
+3414 6 3698 3699 # CM CM
+3415 7 3699 3700 # CM CM
+3416 8 3700 3701 # CM CM
+3417 9 3701 3702 # CM CM
+3418 10 3702 3703 # CM CM
+3419 11 3703 3704 # CM CM
+3420 12 3704 3705 # CM CT
+3421 1 3706 3707 # HG CM
+3422 2 3707 3708 # CM CM
+3423 3 3708 3709 # CM CM
+3424 4 3709 3710 # CM CM
+3425 5 3710 3711 # CM CM
+3426 6 3711 3712 # CM CM
+3427 7 3712 3713 # CM CM
+3428 8 3713 3714 # CM CM
+3429 9 3714 3715 # CM CM
+3430 10 3715 3716 # CM CM
+3431 11 3716 3717 # CM CM
+3432 12 3717 3718 # CM CT
+3433 1 3719 3720 # HG CM
+3434 2 3720 3721 # CM CM
+3435 3 3721 3722 # CM CM
+3436 4 3722 3723 # CM CM
+3437 5 3723 3724 # CM CM
+3438 6 3724 3725 # CM CM
+3439 7 3725 3726 # CM CM
+3440 8 3726 3727 # CM CM
+3441 9 3727 3728 # CM CM
+3442 10 3728 3729 # CM CM
+3443 11 3729 3730 # CM CM
+3444 12 3730 3731 # CM CT
+3445 1 3732 3733 # HG CM
+3446 2 3733 3734 # CM CM
+3447 3 3734 3735 # CM CM
+3448 4 3735 3736 # CM CM
+3449 5 3736 3737 # CM CM
+3450 6 3737 3738 # CM CM
+3451 7 3738 3739 # CM CM
+3452 8 3739 3740 # CM CM
+3453 9 3740 3741 # CM CM
+3454 10 3741 3742 # CM CM
+3455 11 3742 3743 # CM CM
+3456 12 3743 3744 # CM CT
+3457 1 3745 3746 # HG CM
+3458 2 3746 3747 # CM CM
+3459 3 3747 3748 # CM CM
+3460 4 3748 3749 # CM CM
+3461 5 3749 3750 # CM CM
+3462 6 3750 3751 # CM CM
+3463 7 3751 3752 # CM CM
+3464 8 3752 3753 # CM CM
+3465 9 3753 3754 # CM CM
+3466 10 3754 3755 # CM CM
+3467 11 3755 3756 # CM CM
+3468 12 3756 3757 # CM CT
+3469 1 3758 3759 # HG CM
+3470 2 3759 3760 # CM CM
+3471 3 3760 3761 # CM CM
+3472 4 3761 3762 # CM CM
+3473 5 3762 3763 # CM CM
+3474 6 3763 3764 # CM CM
+3475 7 3764 3765 # CM CM
+3476 8 3765 3766 # CM CM
+3477 9 3766 3767 # CM CM
+3478 10 3767 3768 # CM CM
+3479 11 3768 3769 # CM CM
+3480 12 3769 3770 # CM CT
+3481 1 3771 3772 # HG CM
+3482 2 3772 3773 # CM CM
+3483 3 3773 3774 # CM CM
+3484 4 3774 3775 # CM CM
+3485 5 3775 3776 # CM CM
+3486 6 3776 3777 # CM CM
+3487 7 3777 3778 # CM CM
+3488 8 3778 3779 # CM CM
+3489 9 3779 3780 # CM CM
+3490 10 3780 3781 # CM CM
+3491 11 3781 3782 # CM CM
+3492 12 3782 3783 # CM CT
+3493 1 3784 3785 # HG CM
+3494 2 3785 3786 # CM CM
+3495 3 3786 3787 # CM CM
+3496 4 3787 3788 # CM CM
+3497 5 3788 3789 # CM CM
+3498 6 3789 3790 # CM CM
+3499 7 3790 3791 # CM CM
+3500 8 3791 3792 # CM CM
+3501 9 3792 3793 # CM CM
+3502 10 3793 3794 # CM CM
+3503 11 3794 3795 # CM CM
+3504 12 3795 3796 # CM CT
+3505 1 3797 3798 # HG CM
+3506 2 3798 3799 # CM CM
+3507 3 3799 3800 # CM CM
+3508 4 3800 3801 # CM CM
+3509 5 3801 3802 # CM CM
+3510 6 3802 3803 # CM CM
+3511 7 3803 3804 # CM CM
+3512 8 3804 3805 # CM CM
+3513 9 3805 3806 # CM CM
+3514 10 3806 3807 # CM CM
+3515 11 3807 3808 # CM CM
+3516 12 3808 3809 # CM CT
+3517 1 3810 3811 # HG CM
+3518 2 3811 3812 # CM CM
+3519 3 3812 3813 # CM CM
+3520 4 3813 3814 # CM CM
+3521 5 3814 3815 # CM CM
+3522 6 3815 3816 # CM CM
+3523 7 3816 3817 # CM CM
+3524 8 3817 3818 # CM CM
+3525 9 3818 3819 # CM CM
+3526 10 3819 3820 # CM CM
+3527 11 3820 3821 # CM CM
+3528 12 3821 3822 # CM CT
+3529 1 3823 3824 # HG CM
+3530 2 3824 3825 # CM CM
+3531 3 3825 3826 # CM CM
+3532 4 3826 3827 # CM CM
+3533 5 3827 3828 # CM CM
+3534 6 3828 3829 # CM CM
+3535 7 3829 3830 # CM CM
+3536 8 3830 3831 # CM CM
+3537 9 3831 3832 # CM CM
+3538 10 3832 3833 # CM CM
+3539 11 3833 3834 # CM CM
+3540 12 3834 3835 # CM CT
+3541 1 3836 3837 # HG CM
+3542 2 3837 3838 # CM CM
+3543 3 3838 3839 # CM CM
+3544 4 3839 3840 # CM CM
+3545 5 3840 3841 # CM CM
+3546 6 3841 3842 # CM CM
+3547 7 3842 3843 # CM CM
+3548 8 3843 3844 # CM CM
+3549 9 3844 3845 # CM CM
+3550 10 3845 3846 # CM CM
+3551 11 3846 3847 # CM CM
+3552 12 3847 3848 # CM CT
+3553 1 3849 3850 # HG CM
+3554 2 3850 3851 # CM CM
+3555 3 3851 3852 # CM CM
+3556 4 3852 3853 # CM CM
+3557 5 3853 3854 # CM CM
+3558 6 3854 3855 # CM CM
+3559 7 3855 3856 # CM CM
+3560 8 3856 3857 # CM CM
+3561 9 3857 3858 # CM CM
+3562 10 3858 3859 # CM CM
+3563 11 3859 3860 # CM CM
+3564 12 3860 3861 # CM CT
+3565 1 3862 3863 # HG CM
+3566 2 3863 3864 # CM CM
+3567 3 3864 3865 # CM CM
+3568 4 3865 3866 # CM CM
+3569 5 3866 3867 # CM CM
+3570 6 3867 3868 # CM CM
+3571 7 3868 3869 # CM CM
+3572 8 3869 3870 # CM CM
+3573 9 3870 3871 # CM CM
+3574 10 3871 3872 # CM CM
+3575 11 3872 3873 # CM CM
+3576 12 3873 3874 # CM CT
+3577 1 3875 3876 # HG CM
+3578 2 3876 3877 # CM CM
+3579 3 3877 3878 # CM CM
+3580 4 3878 3879 # CM CM
+3581 5 3879 3880 # CM CM
+3582 6 3880 3881 # CM CM
+3583 7 3881 3882 # CM CM
+3584 8 3882 3883 # CM CM
+3585 9 3883 3884 # CM CM
+3586 10 3884 3885 # CM CM
+3587 11 3885 3886 # CM CM
+3588 12 3886 3887 # CM CT
+3589 1 3888 3889 # HG CM
+3590 2 3889 3890 # CM CM
+3591 3 3890 3891 # CM CM
+3592 4 3891 3892 # CM CM
+3593 5 3892 3893 # CM CM
+3594 6 3893 3894 # CM CM
+3595 7 3894 3895 # CM CM
+3596 8 3895 3896 # CM CM
+3597 9 3896 3897 # CM CM
+3598 10 3897 3898 # CM CM
+3599 11 3898 3899 # CM CM
+3600 12 3899 3900 # CM CT
+
+Angles
+
+1 1 1 2 3 # HG CM CM
+2 2 2 3 4 # CM CM CM
+3 3 3 4 5 # CM CM CM
+4 4 4 5 6 # CM CM CM
+5 5 5 6 7 # CM CM CM
+6 6 6 7 8 # CM CM CM
+7 7 7 8 9 # CM CM CM
+8 8 8 9 10 # CM CM CM
+9 9 9 10 11 # CM CM CM
+10 10 10 11 12 # CM CM CM
+11 11 11 12 13 # CM CM CT
+12 1 14 15 16 # HG CM CM
+13 2 15 16 17 # CM CM CM
+14 3 16 17 18 # CM CM CM
+15 4 17 18 19 # CM CM CM
+16 5 18 19 20 # CM CM CM
+17 6 19 20 21 # CM CM CM
+18 7 20 21 22 # CM CM CM
+19 8 21 22 23 # CM CM CM
+20 9 22 23 24 # CM CM CM
+21 10 23 24 25 # CM CM CM
+22 11 24 25 26 # CM CM CT
+23 1 27 28 29 # HG CM CM
+24 2 28 29 30 # CM CM CM
+25 3 29 30 31 # CM CM CM
+26 4 30 31 32 # CM CM CM
+27 5 31 32 33 # CM CM CM
+28 6 32 33 34 # CM CM CM
+29 7 33 34 35 # CM CM CM
+30 8 34 35 36 # CM CM CM
+31 9 35 36 37 # CM CM CM
+32 10 36 37 38 # CM CM CM
+33 11 37 38 39 # CM CM CT
+34 1 40 41 42 # HG CM CM
+35 2 41 42 43 # CM CM CM
+36 3 42 43 44 # CM CM CM
+37 4 43 44 45 # CM CM CM
+38 5 44 45 46 # CM CM CM
+39 6 45 46 47 # CM CM CM
+40 7 46 47 48 # CM CM CM
+41 8 47 48 49 # CM CM CM
+42 9 48 49 50 # CM CM CM
+43 10 49 50 51 # CM CM CM
+44 11 50 51 52 # CM CM CT
+45 1 53 54 55 # HG CM CM
+46 2 54 55 56 # CM CM CM
+47 3 55 56 57 # CM CM CM
+48 4 56 57 58 # CM CM CM
+49 5 57 58 59 # CM CM CM
+50 6 58 59 60 # CM CM CM
+51 7 59 60 61 # CM CM CM
+52 8 60 61 62 # CM CM CM
+53 9 61 62 63 # CM CM CM
+54 10 62 63 64 # CM CM CM
+55 11 63 64 65 # CM CM CT
+56 1 66 67 68 # HG CM CM
+57 2 67 68 69 # CM CM CM
+58 3 68 69 70 # CM CM CM
+59 4 69 70 71 # CM CM CM
+60 5 70 71 72 # CM CM CM
+61 6 71 72 73 # CM CM CM
+62 7 72 73 74 # CM CM CM
+63 8 73 74 75 # CM CM CM
+64 9 74 75 76 # CM CM CM
+65 10 75 76 77 # CM CM CM
+66 11 76 77 78 # CM CM CT
+67 1 79 80 81 # HG CM CM
+68 2 80 81 82 # CM CM CM
+69 3 81 82 83 # CM CM CM
+70 4 82 83 84 # CM CM CM
+71 5 83 84 85 # CM CM CM
+72 6 84 85 86 # CM CM CM
+73 7 85 86 87 # CM CM CM
+74 8 86 87 88 # CM CM CM
+75 9 87 88 89 # CM CM CM
+76 10 88 89 90 # CM CM CM
+77 11 89 90 91 # CM CM CT
+78 1 92 93 94 # HG CM CM
+79 2 93 94 95 # CM CM CM
+80 3 94 95 96 # CM CM CM
+81 4 95 96 97 # CM CM CM
+82 5 96 97 98 # CM CM CM
+83 6 97 98 99 # CM CM CM
+84 7 98 99 100 # CM CM CM
+85 8 99 100 101 # CM CM CM
+86 9 100 101 102 # CM CM CM
+87 10 101 102 103 # CM CM CM
+88 11 102 103 104 # CM CM CT
+89 1 105 106 107 # HG CM CM
+90 2 106 107 108 # CM CM CM
+91 3 107 108 109 # CM CM CM
+92 4 108 109 110 # CM CM CM
+93 5 109 110 111 # CM CM CM
+94 6 110 111 112 # CM CM CM
+95 7 111 112 113 # CM CM CM
+96 8 112 113 114 # CM CM CM
+97 9 113 114 115 # CM CM CM
+98 10 114 115 116 # CM CM CM
+99 11 115 116 117 # CM CM CT
+100 1 118 119 120 # HG CM CM
+101 2 119 120 121 # CM CM CM
+102 3 120 121 122 # CM CM CM
+103 4 121 122 123 # CM CM CM
+104 5 122 123 124 # CM CM CM
+105 6 123 124 125 # CM CM CM
+106 7 124 125 126 # CM CM CM
+107 8 125 126 127 # CM CM CM
+108 9 126 127 128 # CM CM CM
+109 10 127 128 129 # CM CM CM
+110 11 128 129 130 # CM CM CT
+111 1 131 132 133 # HG CM CM
+112 2 132 133 134 # CM CM CM
+113 3 133 134 135 # CM CM CM
+114 4 134 135 136 # CM CM CM
+115 5 135 136 137 # CM CM CM
+116 6 136 137 138 # CM CM CM
+117 7 137 138 139 # CM CM CM
+118 8 138 139 140 # CM CM CM
+119 9 139 140 141 # CM CM CM
+120 10 140 141 142 # CM CM CM
+121 11 141 142 143 # CM CM CT
+122 1 144 145 146 # HG CM CM
+123 2 145 146 147 # CM CM CM
+124 3 146 147 148 # CM CM CM
+125 4 147 148 149 # CM CM CM
+126 5 148 149 150 # CM CM CM
+127 6 149 150 151 # CM CM CM
+128 7 150 151 152 # CM CM CM
+129 8 151 152 153 # CM CM CM
+130 9 152 153 154 # CM CM CM
+131 10 153 154 155 # CM CM CM
+132 11 154 155 156 # CM CM CT
+133 1 157 158 159 # HG CM CM
+134 2 158 159 160 # CM CM CM
+135 3 159 160 161 # CM CM CM
+136 4 160 161 162 # CM CM CM
+137 5 161 162 163 # CM CM CM
+138 6 162 163 164 # CM CM CM
+139 7 163 164 165 # CM CM CM
+140 8 164 165 166 # CM CM CM
+141 9 165 166 167 # CM CM CM
+142 10 166 167 168 # CM CM CM
+143 11 167 168 169 # CM CM CT
+144 1 170 171 172 # HG CM CM
+145 2 171 172 173 # CM CM CM
+146 3 172 173 174 # CM CM CM
+147 4 173 174 175 # CM CM CM
+148 5 174 175 176 # CM CM CM
+149 6 175 176 177 # CM CM CM
+150 7 176 177 178 # CM CM CM
+151 8 177 178 179 # CM CM CM
+152 9 178 179 180 # CM CM CM
+153 10 179 180 181 # CM CM CM
+154 11 180 181 182 # CM CM CT
+155 1 183 184 185 # HG CM CM
+156 2 184 185 186 # CM CM CM
+157 3 185 186 187 # CM CM CM
+158 4 186 187 188 # CM CM CM
+159 5 187 188 189 # CM CM CM
+160 6 188 189 190 # CM CM CM
+161 7 189 190 191 # CM CM CM
+162 8 190 191 192 # CM CM CM
+163 9 191 192 193 # CM CM CM
+164 10 192 193 194 # CM CM CM
+165 11 193 194 195 # CM CM CT
+166 1 196 197 198 # HG CM CM
+167 2 197 198 199 # CM CM CM
+168 3 198 199 200 # CM CM CM
+169 4 199 200 201 # CM CM CM
+170 5 200 201 202 # CM CM CM
+171 6 201 202 203 # CM CM CM
+172 7 202 203 204 # CM CM CM
+173 8 203 204 205 # CM CM CM
+174 9 204 205 206 # CM CM CM
+175 10 205 206 207 # CM CM CM
+176 11 206 207 208 # CM CM CT
+177 1 209 210 211 # HG CM CM
+178 2 210 211 212 # CM CM CM
+179 3 211 212 213 # CM CM CM
+180 4 212 213 214 # CM CM CM
+181 5 213 214 215 # CM CM CM
+182 6 214 215 216 # CM CM CM
+183 7 215 216 217 # CM CM CM
+184 8 216 217 218 # CM CM CM
+185 9 217 218 219 # CM CM CM
+186 10 218 219 220 # CM CM CM
+187 11 219 220 221 # CM CM CT
+188 1 222 223 224 # HG CM CM
+189 2 223 224 225 # CM CM CM
+190 3 224 225 226 # CM CM CM
+191 4 225 226 227 # CM CM CM
+192 5 226 227 228 # CM CM CM
+193 6 227 228 229 # CM CM CM
+194 7 228 229 230 # CM CM CM
+195 8 229 230 231 # CM CM CM
+196 9 230 231 232 # CM CM CM
+197 10 231 232 233 # CM CM CM
+198 11 232 233 234 # CM CM CT
+199 1 235 236 237 # HG CM CM
+200 2 236 237 238 # CM CM CM
+201 3 237 238 239 # CM CM CM
+202 4 238 239 240 # CM CM CM
+203 5 239 240 241 # CM CM CM
+204 6 240 241 242 # CM CM CM
+205 7 241 242 243 # CM CM CM
+206 8 242 243 244 # CM CM CM
+207 9 243 244 245 # CM CM CM
+208 10 244 245 246 # CM CM CM
+209 11 245 246 247 # CM CM CT
+210 1 248 249 250 # HG CM CM
+211 2 249 250 251 # CM CM CM
+212 3 250 251 252 # CM CM CM
+213 4 251 252 253 # CM CM CM
+214 5 252 253 254 # CM CM CM
+215 6 253 254 255 # CM CM CM
+216 7 254 255 256 # CM CM CM
+217 8 255 256 257 # CM CM CM
+218 9 256 257 258 # CM CM CM
+219 10 257 258 259 # CM CM CM
+220 11 258 259 260 # CM CM CT
+221 1 261 262 263 # HG CM CM
+222 2 262 263 264 # CM CM CM
+223 3 263 264 265 # CM CM CM
+224 4 264 265 266 # CM CM CM
+225 5 265 266 267 # CM CM CM
+226 6 266 267 268 # CM CM CM
+227 7 267 268 269 # CM CM CM
+228 8 268 269 270 # CM CM CM
+229 9 269 270 271 # CM CM CM
+230 10 270 271 272 # CM CM CM
+231 11 271 272 273 # CM CM CT
+232 1 274 275 276 # HG CM CM
+233 2 275 276 277 # CM CM CM
+234 3 276 277 278 # CM CM CM
+235 4 277 278 279 # CM CM CM
+236 5 278 279 280 # CM CM CM
+237 6 279 280 281 # CM CM CM
+238 7 280 281 282 # CM CM CM
+239 8 281 282 283 # CM CM CM
+240 9 282 283 284 # CM CM CM
+241 10 283 284 285 # CM CM CM
+242 11 284 285 286 # CM CM CT
+243 1 287 288 289 # HG CM CM
+244 2 288 289 290 # CM CM CM
+245 3 289 290 291 # CM CM CM
+246 4 290 291 292 # CM CM CM
+247 5 291 292 293 # CM CM CM
+248 6 292 293 294 # CM CM CM
+249 7 293 294 295 # CM CM CM
+250 8 294 295 296 # CM CM CM
+251 9 295 296 297 # CM CM CM
+252 10 296 297 298 # CM CM CM
+253 11 297 298 299 # CM CM CT
+254 1 300 301 302 # HG CM CM
+255 2 301 302 303 # CM CM CM
+256 3 302 303 304 # CM CM CM
+257 4 303 304 305 # CM CM CM
+258 5 304 305 306 # CM CM CM
+259 6 305 306 307 # CM CM CM
+260 7 306 307 308 # CM CM CM
+261 8 307 308 309 # CM CM CM
+262 9 308 309 310 # CM CM CM
+263 10 309 310 311 # CM CM CM
+264 11 310 311 312 # CM CM CT
+265 1 313 314 315 # HG CM CM
+266 2 314 315 316 # CM CM CM
+267 3 315 316 317 # CM CM CM
+268 4 316 317 318 # CM CM CM
+269 5 317 318 319 # CM CM CM
+270 6 318 319 320 # CM CM CM
+271 7 319 320 321 # CM CM CM
+272 8 320 321 322 # CM CM CM
+273 9 321 322 323 # CM CM CM
+274 10 322 323 324 # CM CM CM
+275 11 323 324 325 # CM CM CT
+276 1 326 327 328 # HG CM CM
+277 2 327 328 329 # CM CM CM
+278 3 328 329 330 # CM CM CM
+279 4 329 330 331 # CM CM CM
+280 5 330 331 332 # CM CM CM
+281 6 331 332 333 # CM CM CM
+282 7 332 333 334 # CM CM CM
+283 8 333 334 335 # CM CM CM
+284 9 334 335 336 # CM CM CM
+285 10 335 336 337 # CM CM CM
+286 11 336 337 338 # CM CM CT
+287 1 339 340 341 # HG CM CM
+288 2 340 341 342 # CM CM CM
+289 3 341 342 343 # CM CM CM
+290 4 342 343 344 # CM CM CM
+291 5 343 344 345 # CM CM CM
+292 6 344 345 346 # CM CM CM
+293 7 345 346 347 # CM CM CM
+294 8 346 347 348 # CM CM CM
+295 9 347 348 349 # CM CM CM
+296 10 348 349 350 # CM CM CM
+297 11 349 350 351 # CM CM CT
+298 1 352 353 354 # HG CM CM
+299 2 353 354 355 # CM CM CM
+300 3 354 355 356 # CM CM CM
+301 4 355 356 357 # CM CM CM
+302 5 356 357 358 # CM CM CM
+303 6 357 358 359 # CM CM CM
+304 7 358 359 360 # CM CM CM
+305 8 359 360 361 # CM CM CM
+306 9 360 361 362 # CM CM CM
+307 10 361 362 363 # CM CM CM
+308 11 362 363 364 # CM CM CT
+309 1 365 366 367 # HG CM CM
+310 2 366 367 368 # CM CM CM
+311 3 367 368 369 # CM CM CM
+312 4 368 369 370 # CM CM CM
+313 5 369 370 371 # CM CM CM
+314 6 370 371 372 # CM CM CM
+315 7 371 372 373 # CM CM CM
+316 8 372 373 374 # CM CM CM
+317 9 373 374 375 # CM CM CM
+318 10 374 375 376 # CM CM CM
+319 11 375 376 377 # CM CM CT
+320 1 378 379 380 # HG CM CM
+321 2 379 380 381 # CM CM CM
+322 3 380 381 382 # CM CM CM
+323 4 381 382 383 # CM CM CM
+324 5 382 383 384 # CM CM CM
+325 6 383 384 385 # CM CM CM
+326 7 384 385 386 # CM CM CM
+327 8 385 386 387 # CM CM CM
+328 9 386 387 388 # CM CM CM
+329 10 387 388 389 # CM CM CM
+330 11 388 389 390 # CM CM CT
+331 1 391 392 393 # HG CM CM
+332 2 392 393 394 # CM CM CM
+333 3 393 394 395 # CM CM CM
+334 4 394 395 396 # CM CM CM
+335 5 395 396 397 # CM CM CM
+336 6 396 397 398 # CM CM CM
+337 7 397 398 399 # CM CM CM
+338 8 398 399 400 # CM CM CM
+339 9 399 400 401 # CM CM CM
+340 10 400 401 402 # CM CM CM
+341 11 401 402 403 # CM CM CT
+342 1 404 405 406 # HG CM CM
+343 2 405 406 407 # CM CM CM
+344 3 406 407 408 # CM CM CM
+345 4 407 408 409 # CM CM CM
+346 5 408 409 410 # CM CM CM
+347 6 409 410 411 # CM CM CM
+348 7 410 411 412 # CM CM CM
+349 8 411 412 413 # CM CM CM
+350 9 412 413 414 # CM CM CM
+351 10 413 414 415 # CM CM CM
+352 11 414 415 416 # CM CM CT
+353 1 417 418 419 # HG CM CM
+354 2 418 419 420 # CM CM CM
+355 3 419 420 421 # CM CM CM
+356 4 420 421 422 # CM CM CM
+357 5 421 422 423 # CM CM CM
+358 6 422 423 424 # CM CM CM
+359 7 423 424 425 # CM CM CM
+360 8 424 425 426 # CM CM CM
+361 9 425 426 427 # CM CM CM
+362 10 426 427 428 # CM CM CM
+363 11 427 428 429 # CM CM CT
+364 1 430 431 432 # HG CM CM
+365 2 431 432 433 # CM CM CM
+366 3 432 433 434 # CM CM CM
+367 4 433 434 435 # CM CM CM
+368 5 434 435 436 # CM CM CM
+369 6 435 436 437 # CM CM CM
+370 7 436 437 438 # CM CM CM
+371 8 437 438 439 # CM CM CM
+372 9 438 439 440 # CM CM CM
+373 10 439 440 441 # CM CM CM
+374 11 440 441 442 # CM CM CT
+375 1 443 444 445 # HG CM CM
+376 2 444 445 446 # CM CM CM
+377 3 445 446 447 # CM CM CM
+378 4 446 447 448 # CM CM CM
+379 5 447 448 449 # CM CM CM
+380 6 448 449 450 # CM CM CM
+381 7 449 450 451 # CM CM CM
+382 8 450 451 452 # CM CM CM
+383 9 451 452 453 # CM CM CM
+384 10 452 453 454 # CM CM CM
+385 11 453 454 455 # CM CM CT
+386 1 456 457 458 # HG CM CM
+387 2 457 458 459 # CM CM CM
+388 3 458 459 460 # CM CM CM
+389 4 459 460 461 # CM CM CM
+390 5 460 461 462 # CM CM CM
+391 6 461 462 463 # CM CM CM
+392 7 462 463 464 # CM CM CM
+393 8 463 464 465 # CM CM CM
+394 9 464 465 466 # CM CM CM
+395 10 465 466 467 # CM CM CM
+396 11 466 467 468 # CM CM CT
+397 1 469 470 471 # HG CM CM
+398 2 470 471 472 # CM CM CM
+399 3 471 472 473 # CM CM CM
+400 4 472 473 474 # CM CM CM
+401 5 473 474 475 # CM CM CM
+402 6 474 475 476 # CM CM CM
+403 7 475 476 477 # CM CM CM
+404 8 476 477 478 # CM CM CM
+405 9 477 478 479 # CM CM CM
+406 10 478 479 480 # CM CM CM
+407 11 479 480 481 # CM CM CT
+408 1 482 483 484 # HG CM CM
+409 2 483 484 485 # CM CM CM
+410 3 484 485 486 # CM CM CM
+411 4 485 486 487 # CM CM CM
+412 5 486 487 488 # CM CM CM
+413 6 487 488 489 # CM CM CM
+414 7 488 489 490 # CM CM CM
+415 8 489 490 491 # CM CM CM
+416 9 490 491 492 # CM CM CM
+417 10 491 492 493 # CM CM CM
+418 11 492 493 494 # CM CM CT
+419 1 495 496 497 # HG CM CM
+420 2 496 497 498 # CM CM CM
+421 3 497 498 499 # CM CM CM
+422 4 498 499 500 # CM CM CM
+423 5 499 500 501 # CM CM CM
+424 6 500 501 502 # CM CM CM
+425 7 501 502 503 # CM CM CM
+426 8 502 503 504 # CM CM CM
+427 9 503 504 505 # CM CM CM
+428 10 504 505 506 # CM CM CM
+429 11 505 506 507 # CM CM CT
+430 1 508 509 510 # HG CM CM
+431 2 509 510 511 # CM CM CM
+432 3 510 511 512 # CM CM CM
+433 4 511 512 513 # CM CM CM
+434 5 512 513 514 # CM CM CM
+435 6 513 514 515 # CM CM CM
+436 7 514 515 516 # CM CM CM
+437 8 515 516 517 # CM CM CM
+438 9 516 517 518 # CM CM CM
+439 10 517 518 519 # CM CM CM
+440 11 518 519 520 # CM CM CT
+441 1 521 522 523 # HG CM CM
+442 2 522 523 524 # CM CM CM
+443 3 523 524 525 # CM CM CM
+444 4 524 525 526 # CM CM CM
+445 5 525 526 527 # CM CM CM
+446 6 526 527 528 # CM CM CM
+447 7 527 528 529 # CM CM CM
+448 8 528 529 530 # CM CM CM
+449 9 529 530 531 # CM CM CM
+450 10 530 531 532 # CM CM CM
+451 11 531 532 533 # CM CM CT
+452 1 534 535 536 # HG CM CM
+453 2 535 536 537 # CM CM CM
+454 3 536 537 538 # CM CM CM
+455 4 537 538 539 # CM CM CM
+456 5 538 539 540 # CM CM CM
+457 6 539 540 541 # CM CM CM
+458 7 540 541 542 # CM CM CM
+459 8 541 542 543 # CM CM CM
+460 9 542 543 544 # CM CM CM
+461 10 543 544 545 # CM CM CM
+462 11 544 545 546 # CM CM CT
+463 1 547 548 549 # HG CM CM
+464 2 548 549 550 # CM CM CM
+465 3 549 550 551 # CM CM CM
+466 4 550 551 552 # CM CM CM
+467 5 551 552 553 # CM CM CM
+468 6 552 553 554 # CM CM CM
+469 7 553 554 555 # CM CM CM
+470 8 554 555 556 # CM CM CM
+471 9 555 556 557 # CM CM CM
+472 10 556 557 558 # CM CM CM
+473 11 557 558 559 # CM CM CT
+474 1 560 561 562 # HG CM CM
+475 2 561 562 563 # CM CM CM
+476 3 562 563 564 # CM CM CM
+477 4 563 564 565 # CM CM CM
+478 5 564 565 566 # CM CM CM
+479 6 565 566 567 # CM CM CM
+480 7 566 567 568 # CM CM CM
+481 8 567 568 569 # CM CM CM
+482 9 568 569 570 # CM CM CM
+483 10 569 570 571 # CM CM CM
+484 11 570 571 572 # CM CM CT
+485 1 573 574 575 # HG CM CM
+486 2 574 575 576 # CM CM CM
+487 3 575 576 577 # CM CM CM
+488 4 576 577 578 # CM CM CM
+489 5 577 578 579 # CM CM CM
+490 6 578 579 580 # CM CM CM
+491 7 579 580 581 # CM CM CM
+492 8 580 581 582 # CM CM CM
+493 9 581 582 583 # CM CM CM
+494 10 582 583 584 # CM CM CM
+495 11 583 584 585 # CM CM CT
+496 1 586 587 588 # HG CM CM
+497 2 587 588 589 # CM CM CM
+498 3 588 589 590 # CM CM CM
+499 4 589 590 591 # CM CM CM
+500 5 590 591 592 # CM CM CM
+501 6 591 592 593 # CM CM CM
+502 7 592 593 594 # CM CM CM
+503 8 593 594 595 # CM CM CM
+504 9 594 595 596 # CM CM CM
+505 10 595 596 597 # CM CM CM
+506 11 596 597 598 # CM CM CT
+507 1 599 600 601 # HG CM CM
+508 2 600 601 602 # CM CM CM
+509 3 601 602 603 # CM CM CM
+510 4 602 603 604 # CM CM CM
+511 5 603 604 605 # CM CM CM
+512 6 604 605 606 # CM CM CM
+513 7 605 606 607 # CM CM CM
+514 8 606 607 608 # CM CM CM
+515 9 607 608 609 # CM CM CM
+516 10 608 609 610 # CM CM CM
+517 11 609 610 611 # CM CM CT
+518 1 612 613 614 # HG CM CM
+519 2 613 614 615 # CM CM CM
+520 3 614 615 616 # CM CM CM
+521 4 615 616 617 # CM CM CM
+522 5 616 617 618 # CM CM CM
+523 6 617 618 619 # CM CM CM
+524 7 618 619 620 # CM CM CM
+525 8 619 620 621 # CM CM CM
+526 9 620 621 622 # CM CM CM
+527 10 621 622 623 # CM CM CM
+528 11 622 623 624 # CM CM CT
+529 1 625 626 627 # HG CM CM
+530 2 626 627 628 # CM CM CM
+531 3 627 628 629 # CM CM CM
+532 4 628 629 630 # CM CM CM
+533 5 629 630 631 # CM CM CM
+534 6 630 631 632 # CM CM CM
+535 7 631 632 633 # CM CM CM
+536 8 632 633 634 # CM CM CM
+537 9 633 634 635 # CM CM CM
+538 10 634 635 636 # CM CM CM
+539 11 635 636 637 # CM CM CT
+540 1 638 639 640 # HG CM CM
+541 2 639 640 641 # CM CM CM
+542 3 640 641 642 # CM CM CM
+543 4 641 642 643 # CM CM CM
+544 5 642 643 644 # CM CM CM
+545 6 643 644 645 # CM CM CM
+546 7 644 645 646 # CM CM CM
+547 8 645 646 647 # CM CM CM
+548 9 646 647 648 # CM CM CM
+549 10 647 648 649 # CM CM CM
+550 11 648 649 650 # CM CM CT
+551 1 651 652 653 # HG CM CM
+552 2 652 653 654 # CM CM CM
+553 3 653 654 655 # CM CM CM
+554 4 654 655 656 # CM CM CM
+555 5 655 656 657 # CM CM CM
+556 6 656 657 658 # CM CM CM
+557 7 657 658 659 # CM CM CM
+558 8 658 659 660 # CM CM CM
+559 9 659 660 661 # CM CM CM
+560 10 660 661 662 # CM CM CM
+561 11 661 662 663 # CM CM CT
+562 1 664 665 666 # HG CM CM
+563 2 665 666 667 # CM CM CM
+564 3 666 667 668 # CM CM CM
+565 4 667 668 669 # CM CM CM
+566 5 668 669 670 # CM CM CM
+567 6 669 670 671 # CM CM CM
+568 7 670 671 672 # CM CM CM
+569 8 671 672 673 # CM CM CM
+570 9 672 673 674 # CM CM CM
+571 10 673 674 675 # CM CM CM
+572 11 674 675 676 # CM CM CT
+573 1 677 678 679 # HG CM CM
+574 2 678 679 680 # CM CM CM
+575 3 679 680 681 # CM CM CM
+576 4 680 681 682 # CM CM CM
+577 5 681 682 683 # CM CM CM
+578 6 682 683 684 # CM CM CM
+579 7 683 684 685 # CM CM CM
+580 8 684 685 686 # CM CM CM
+581 9 685 686 687 # CM CM CM
+582 10 686 687 688 # CM CM CM
+583 11 687 688 689 # CM CM CT
+584 1 690 691 692 # HG CM CM
+585 2 691 692 693 # CM CM CM
+586 3 692 693 694 # CM CM CM
+587 4 693 694 695 # CM CM CM
+588 5 694 695 696 # CM CM CM
+589 6 695 696 697 # CM CM CM
+590 7 696 697 698 # CM CM CM
+591 8 697 698 699 # CM CM CM
+592 9 698 699 700 # CM CM CM
+593 10 699 700 701 # CM CM CM
+594 11 700 701 702 # CM CM CT
+595 1 703 704 705 # HG CM CM
+596 2 704 705 706 # CM CM CM
+597 3 705 706 707 # CM CM CM
+598 4 706 707 708 # CM CM CM
+599 5 707 708 709 # CM CM CM
+600 6 708 709 710 # CM CM CM
+601 7 709 710 711 # CM CM CM
+602 8 710 711 712 # CM CM CM
+603 9 711 712 713 # CM CM CM
+604 10 712 713 714 # CM CM CM
+605 11 713 714 715 # CM CM CT
+606 1 716 717 718 # HG CM CM
+607 2 717 718 719 # CM CM CM
+608 3 718 719 720 # CM CM CM
+609 4 719 720 721 # CM CM CM
+610 5 720 721 722 # CM CM CM
+611 6 721 722 723 # CM CM CM
+612 7 722 723 724 # CM CM CM
+613 8 723 724 725 # CM CM CM
+614 9 724 725 726 # CM CM CM
+615 10 725 726 727 # CM CM CM
+616 11 726 727 728 # CM CM CT
+617 1 729 730 731 # HG CM CM
+618 2 730 731 732 # CM CM CM
+619 3 731 732 733 # CM CM CM
+620 4 732 733 734 # CM CM CM
+621 5 733 734 735 # CM CM CM
+622 6 734 735 736 # CM CM CM
+623 7 735 736 737 # CM CM CM
+624 8 736 737 738 # CM CM CM
+625 9 737 738 739 # CM CM CM
+626 10 738 739 740 # CM CM CM
+627 11 739 740 741 # CM CM CT
+628 1 742 743 744 # HG CM CM
+629 2 743 744 745 # CM CM CM
+630 3 744 745 746 # CM CM CM
+631 4 745 746 747 # CM CM CM
+632 5 746 747 748 # CM CM CM
+633 6 747 748 749 # CM CM CM
+634 7 748 749 750 # CM CM CM
+635 8 749 750 751 # CM CM CM
+636 9 750 751 752 # CM CM CM
+637 10 751 752 753 # CM CM CM
+638 11 752 753 754 # CM CM CT
+639 1 755 756 757 # HG CM CM
+640 2 756 757 758 # CM CM CM
+641 3 757 758 759 # CM CM CM
+642 4 758 759 760 # CM CM CM
+643 5 759 760 761 # CM CM CM
+644 6 760 761 762 # CM CM CM
+645 7 761 762 763 # CM CM CM
+646 8 762 763 764 # CM CM CM
+647 9 763 764 765 # CM CM CM
+648 10 764 765 766 # CM CM CM
+649 11 765 766 767 # CM CM CT
+650 1 768 769 770 # HG CM CM
+651 2 769 770 771 # CM CM CM
+652 3 770 771 772 # CM CM CM
+653 4 771 772 773 # CM CM CM
+654 5 772 773 774 # CM CM CM
+655 6 773 774 775 # CM CM CM
+656 7 774 775 776 # CM CM CM
+657 8 775 776 777 # CM CM CM
+658 9 776 777 778 # CM CM CM
+659 10 777 778 779 # CM CM CM
+660 11 778 779 780 # CM CM CT
+661 1 781 782 783 # HG CM CM
+662 2 782 783 784 # CM CM CM
+663 3 783 784 785 # CM CM CM
+664 4 784 785 786 # CM CM CM
+665 5 785 786 787 # CM CM CM
+666 6 786 787 788 # CM CM CM
+667 7 787 788 789 # CM CM CM
+668 8 788 789 790 # CM CM CM
+669 9 789 790 791 # CM CM CM
+670 10 790 791 792 # CM CM CM
+671 11 791 792 793 # CM CM CT
+672 1 794 795 796 # HG CM CM
+673 2 795 796 797 # CM CM CM
+674 3 796 797 798 # CM CM CM
+675 4 797 798 799 # CM CM CM
+676 5 798 799 800 # CM CM CM
+677 6 799 800 801 # CM CM CM
+678 7 800 801 802 # CM CM CM
+679 8 801 802 803 # CM CM CM
+680 9 802 803 804 # CM CM CM
+681 10 803 804 805 # CM CM CM
+682 11 804 805 806 # CM CM CT
+683 1 807 808 809 # HG CM CM
+684 2 808 809 810 # CM CM CM
+685 3 809 810 811 # CM CM CM
+686 4 810 811 812 # CM CM CM
+687 5 811 812 813 # CM CM CM
+688 6 812 813 814 # CM CM CM
+689 7 813 814 815 # CM CM CM
+690 8 814 815 816 # CM CM CM
+691 9 815 816 817 # CM CM CM
+692 10 816 817 818 # CM CM CM
+693 11 817 818 819 # CM CM CT
+694 1 820 821 822 # HG CM CM
+695 2 821 822 823 # CM CM CM
+696 3 822 823 824 # CM CM CM
+697 4 823 824 825 # CM CM CM
+698 5 824 825 826 # CM CM CM
+699 6 825 826 827 # CM CM CM
+700 7 826 827 828 # CM CM CM
+701 8 827 828 829 # CM CM CM
+702 9 828 829 830 # CM CM CM
+703 10 829 830 831 # CM CM CM
+704 11 830 831 832 # CM CM CT
+705 1 833 834 835 # HG CM CM
+706 2 834 835 836 # CM CM CM
+707 3 835 836 837 # CM CM CM
+708 4 836 837 838 # CM CM CM
+709 5 837 838 839 # CM CM CM
+710 6 838 839 840 # CM CM CM
+711 7 839 840 841 # CM CM CM
+712 8 840 841 842 # CM CM CM
+713 9 841 842 843 # CM CM CM
+714 10 842 843 844 # CM CM CM
+715 11 843 844 845 # CM CM CT
+716 1 846 847 848 # HG CM CM
+717 2 847 848 849 # CM CM CM
+718 3 848 849 850 # CM CM CM
+719 4 849 850 851 # CM CM CM
+720 5 850 851 852 # CM CM CM
+721 6 851 852 853 # CM CM CM
+722 7 852 853 854 # CM CM CM
+723 8 853 854 855 # CM CM CM
+724 9 854 855 856 # CM CM CM
+725 10 855 856 857 # CM CM CM
+726 11 856 857 858 # CM CM CT
+727 1 859 860 861 # HG CM CM
+728 2 860 861 862 # CM CM CM
+729 3 861 862 863 # CM CM CM
+730 4 862 863 864 # CM CM CM
+731 5 863 864 865 # CM CM CM
+732 6 864 865 866 # CM CM CM
+733 7 865 866 867 # CM CM CM
+734 8 866 867 868 # CM CM CM
+735 9 867 868 869 # CM CM CM
+736 10 868 869 870 # CM CM CM
+737 11 869 870 871 # CM CM CT
+738 1 872 873 874 # HG CM CM
+739 2 873 874 875 # CM CM CM
+740 3 874 875 876 # CM CM CM
+741 4 875 876 877 # CM CM CM
+742 5 876 877 878 # CM CM CM
+743 6 877 878 879 # CM CM CM
+744 7 878 879 880 # CM CM CM
+745 8 879 880 881 # CM CM CM
+746 9 880 881 882 # CM CM CM
+747 10 881 882 883 # CM CM CM
+748 11 882 883 884 # CM CM CT
+749 1 885 886 887 # HG CM CM
+750 2 886 887 888 # CM CM CM
+751 3 887 888 889 # CM CM CM
+752 4 888 889 890 # CM CM CM
+753 5 889 890 891 # CM CM CM
+754 6 890 891 892 # CM CM CM
+755 7 891 892 893 # CM CM CM
+756 8 892 893 894 # CM CM CM
+757 9 893 894 895 # CM CM CM
+758 10 894 895 896 # CM CM CM
+759 11 895 896 897 # CM CM CT
+760 1 898 899 900 # HG CM CM
+761 2 899 900 901 # CM CM CM
+762 3 900 901 902 # CM CM CM
+763 4 901 902 903 # CM CM CM
+764 5 902 903 904 # CM CM CM
+765 6 903 904 905 # CM CM CM
+766 7 904 905 906 # CM CM CM
+767 8 905 906 907 # CM CM CM
+768 9 906 907 908 # CM CM CM
+769 10 907 908 909 # CM CM CM
+770 11 908 909 910 # CM CM CT
+771 1 911 912 913 # HG CM CM
+772 2 912 913 914 # CM CM CM
+773 3 913 914 915 # CM CM CM
+774 4 914 915 916 # CM CM CM
+775 5 915 916 917 # CM CM CM
+776 6 916 917 918 # CM CM CM
+777 7 917 918 919 # CM CM CM
+778 8 918 919 920 # CM CM CM
+779 9 919 920 921 # CM CM CM
+780 10 920 921 922 # CM CM CM
+781 11 921 922 923 # CM CM CT
+782 1 924 925 926 # HG CM CM
+783 2 925 926 927 # CM CM CM
+784 3 926 927 928 # CM CM CM
+785 4 927 928 929 # CM CM CM
+786 5 928 929 930 # CM CM CM
+787 6 929 930 931 # CM CM CM
+788 7 930 931 932 # CM CM CM
+789 8 931 932 933 # CM CM CM
+790 9 932 933 934 # CM CM CM
+791 10 933 934 935 # CM CM CM
+792 11 934 935 936 # CM CM CT
+793 1 937 938 939 # HG CM CM
+794 2 938 939 940 # CM CM CM
+795 3 939 940 941 # CM CM CM
+796 4 940 941 942 # CM CM CM
+797 5 941 942 943 # CM CM CM
+798 6 942 943 944 # CM CM CM
+799 7 943 944 945 # CM CM CM
+800 8 944 945 946 # CM CM CM
+801 9 945 946 947 # CM CM CM
+802 10 946 947 948 # CM CM CM
+803 11 947 948 949 # CM CM CT
+804 1 950 951 952 # HG CM CM
+805 2 951 952 953 # CM CM CM
+806 3 952 953 954 # CM CM CM
+807 4 953 954 955 # CM CM CM
+808 5 954 955 956 # CM CM CM
+809 6 955 956 957 # CM CM CM
+810 7 956 957 958 # CM CM CM
+811 8 957 958 959 # CM CM CM
+812 9 958 959 960 # CM CM CM
+813 10 959 960 961 # CM CM CM
+814 11 960 961 962 # CM CM CT
+815 1 963 964 965 # HG CM CM
+816 2 964 965 966 # CM CM CM
+817 3 965 966 967 # CM CM CM
+818 4 966 967 968 # CM CM CM
+819 5 967 968 969 # CM CM CM
+820 6 968 969 970 # CM CM CM
+821 7 969 970 971 # CM CM CM
+822 8 970 971 972 # CM CM CM
+823 9 971 972 973 # CM CM CM
+824 10 972 973 974 # CM CM CM
+825 11 973 974 975 # CM CM CT
+826 1 976 977 978 # HG CM CM
+827 2 977 978 979 # CM CM CM
+828 3 978 979 980 # CM CM CM
+829 4 979 980 981 # CM CM CM
+830 5 980 981 982 # CM CM CM
+831 6 981 982 983 # CM CM CM
+832 7 982 983 984 # CM CM CM
+833 8 983 984 985 # CM CM CM
+834 9 984 985 986 # CM CM CM
+835 10 985 986 987 # CM CM CM
+836 11 986 987 988 # CM CM CT
+837 1 989 990 991 # HG CM CM
+838 2 990 991 992 # CM CM CM
+839 3 991 992 993 # CM CM CM
+840 4 992 993 994 # CM CM CM
+841 5 993 994 995 # CM CM CM
+842 6 994 995 996 # CM CM CM
+843 7 995 996 997 # CM CM CM
+844 8 996 997 998 # CM CM CM
+845 9 997 998 999 # CM CM CM
+846 10 998 999 1000 # CM CM CM
+847 11 999 1000 1001 # CM CM CT
+848 1 1002 1003 1004 # HG CM CM
+849 2 1003 1004 1005 # CM CM CM
+850 3 1004 1005 1006 # CM CM CM
+851 4 1005 1006 1007 # CM CM CM
+852 5 1006 1007 1008 # CM CM CM
+853 6 1007 1008 1009 # CM CM CM
+854 7 1008 1009 1010 # CM CM CM
+855 8 1009 1010 1011 # CM CM CM
+856 9 1010 1011 1012 # CM CM CM
+857 10 1011 1012 1013 # CM CM CM
+858 11 1012 1013 1014 # CM CM CT
+859 1 1015 1016 1017 # HG CM CM
+860 2 1016 1017 1018 # CM CM CM
+861 3 1017 1018 1019 # CM CM CM
+862 4 1018 1019 1020 # CM CM CM
+863 5 1019 1020 1021 # CM CM CM
+864 6 1020 1021 1022 # CM CM CM
+865 7 1021 1022 1023 # CM CM CM
+866 8 1022 1023 1024 # CM CM CM
+867 9 1023 1024 1025 # CM CM CM
+868 10 1024 1025 1026 # CM CM CM
+869 11 1025 1026 1027 # CM CM CT
+870 1 1028 1029 1030 # HG CM CM
+871 2 1029 1030 1031 # CM CM CM
+872 3 1030 1031 1032 # CM CM CM
+873 4 1031 1032 1033 # CM CM CM
+874 5 1032 1033 1034 # CM CM CM
+875 6 1033 1034 1035 # CM CM CM
+876 7 1034 1035 1036 # CM CM CM
+877 8 1035 1036 1037 # CM CM CM
+878 9 1036 1037 1038 # CM CM CM
+879 10 1037 1038 1039 # CM CM CM
+880 11 1038 1039 1040 # CM CM CT
+881 1 1041 1042 1043 # HG CM CM
+882 2 1042 1043 1044 # CM CM CM
+883 3 1043 1044 1045 # CM CM CM
+884 4 1044 1045 1046 # CM CM CM
+885 5 1045 1046 1047 # CM CM CM
+886 6 1046 1047 1048 # CM CM CM
+887 7 1047 1048 1049 # CM CM CM
+888 8 1048 1049 1050 # CM CM CM
+889 9 1049 1050 1051 # CM CM CM
+890 10 1050 1051 1052 # CM CM CM
+891 11 1051 1052 1053 # CM CM CT
+892 1 1054 1055 1056 # HG CM CM
+893 2 1055 1056 1057 # CM CM CM
+894 3 1056 1057 1058 # CM CM CM
+895 4 1057 1058 1059 # CM CM CM
+896 5 1058 1059 1060 # CM CM CM
+897 6 1059 1060 1061 # CM CM CM
+898 7 1060 1061 1062 # CM CM CM
+899 8 1061 1062 1063 # CM CM CM
+900 9 1062 1063 1064 # CM CM CM
+901 10 1063 1064 1065 # CM CM CM
+902 11 1064 1065 1066 # CM CM CT
+903 1 1067 1068 1069 # HG CM CM
+904 2 1068 1069 1070 # CM CM CM
+905 3 1069 1070 1071 # CM CM CM
+906 4 1070 1071 1072 # CM CM CM
+907 5 1071 1072 1073 # CM CM CM
+908 6 1072 1073 1074 # CM CM CM
+909 7 1073 1074 1075 # CM CM CM
+910 8 1074 1075 1076 # CM CM CM
+911 9 1075 1076 1077 # CM CM CM
+912 10 1076 1077 1078 # CM CM CM
+913 11 1077 1078 1079 # CM CM CT
+914 1 1080 1081 1082 # HG CM CM
+915 2 1081 1082 1083 # CM CM CM
+916 3 1082 1083 1084 # CM CM CM
+917 4 1083 1084 1085 # CM CM CM
+918 5 1084 1085 1086 # CM CM CM
+919 6 1085 1086 1087 # CM CM CM
+920 7 1086 1087 1088 # CM CM CM
+921 8 1087 1088 1089 # CM CM CM
+922 9 1088 1089 1090 # CM CM CM
+923 10 1089 1090 1091 # CM CM CM
+924 11 1090 1091 1092 # CM CM CT
+925 1 1093 1094 1095 # HG CM CM
+926 2 1094 1095 1096 # CM CM CM
+927 3 1095 1096 1097 # CM CM CM
+928 4 1096 1097 1098 # CM CM CM
+929 5 1097 1098 1099 # CM CM CM
+930 6 1098 1099 1100 # CM CM CM
+931 7 1099 1100 1101 # CM CM CM
+932 8 1100 1101 1102 # CM CM CM
+933 9 1101 1102 1103 # CM CM CM
+934 10 1102 1103 1104 # CM CM CM
+935 11 1103 1104 1105 # CM CM CT
+936 1 1106 1107 1108 # HG CM CM
+937 2 1107 1108 1109 # CM CM CM
+938 3 1108 1109 1110 # CM CM CM
+939 4 1109 1110 1111 # CM CM CM
+940 5 1110 1111 1112 # CM CM CM
+941 6 1111 1112 1113 # CM CM CM
+942 7 1112 1113 1114 # CM CM CM
+943 8 1113 1114 1115 # CM CM CM
+944 9 1114 1115 1116 # CM CM CM
+945 10 1115 1116 1117 # CM CM CM
+946 11 1116 1117 1118 # CM CM CT
+947 1 1119 1120 1121 # HG CM CM
+948 2 1120 1121 1122 # CM CM CM
+949 3 1121 1122 1123 # CM CM CM
+950 4 1122 1123 1124 # CM CM CM
+951 5 1123 1124 1125 # CM CM CM
+952 6 1124 1125 1126 # CM CM CM
+953 7 1125 1126 1127 # CM CM CM
+954 8 1126 1127 1128 # CM CM CM
+955 9 1127 1128 1129 # CM CM CM
+956 10 1128 1129 1130 # CM CM CM
+957 11 1129 1130 1131 # CM CM CT
+958 1 1132 1133 1134 # HG CM CM
+959 2 1133 1134 1135 # CM CM CM
+960 3 1134 1135 1136 # CM CM CM
+961 4 1135 1136 1137 # CM CM CM
+962 5 1136 1137 1138 # CM CM CM
+963 6 1137 1138 1139 # CM CM CM
+964 7 1138 1139 1140 # CM CM CM
+965 8 1139 1140 1141 # CM CM CM
+966 9 1140 1141 1142 # CM CM CM
+967 10 1141 1142 1143 # CM CM CM
+968 11 1142 1143 1144 # CM CM CT
+969 1 1145 1146 1147 # HG CM CM
+970 2 1146 1147 1148 # CM CM CM
+971 3 1147 1148 1149 # CM CM CM
+972 4 1148 1149 1150 # CM CM CM
+973 5 1149 1150 1151 # CM CM CM
+974 6 1150 1151 1152 # CM CM CM
+975 7 1151 1152 1153 # CM CM CM
+976 8 1152 1153 1154 # CM CM CM
+977 9 1153 1154 1155 # CM CM CM
+978 10 1154 1155 1156 # CM CM CM
+979 11 1155 1156 1157 # CM CM CT
+980 1 1158 1159 1160 # HG CM CM
+981 2 1159 1160 1161 # CM CM CM
+982 3 1160 1161 1162 # CM CM CM
+983 4 1161 1162 1163 # CM CM CM
+984 5 1162 1163 1164 # CM CM CM
+985 6 1163 1164 1165 # CM CM CM
+986 7 1164 1165 1166 # CM CM CM
+987 8 1165 1166 1167 # CM CM CM
+988 9 1166 1167 1168 # CM CM CM
+989 10 1167 1168 1169 # CM CM CM
+990 11 1168 1169 1170 # CM CM CT
+991 1 1171 1172 1173 # HG CM CM
+992 2 1172 1173 1174 # CM CM CM
+993 3 1173 1174 1175 # CM CM CM
+994 4 1174 1175 1176 # CM CM CM
+995 5 1175 1176 1177 # CM CM CM
+996 6 1176 1177 1178 # CM CM CM
+997 7 1177 1178 1179 # CM CM CM
+998 8 1178 1179 1180 # CM CM CM
+999 9 1179 1180 1181 # CM CM CM
+1000 10 1180 1181 1182 # CM CM CM
+1001 11 1181 1182 1183 # CM CM CT
+1002 1 1184 1185 1186 # HG CM CM
+1003 2 1185 1186 1187 # CM CM CM
+1004 3 1186 1187 1188 # CM CM CM
+1005 4 1187 1188 1189 # CM CM CM
+1006 5 1188 1189 1190 # CM CM CM
+1007 6 1189 1190 1191 # CM CM CM
+1008 7 1190 1191 1192 # CM CM CM
+1009 8 1191 1192 1193 # CM CM CM
+1010 9 1192 1193 1194 # CM CM CM
+1011 10 1193 1194 1195 # CM CM CM
+1012 11 1194 1195 1196 # CM CM CT
+1013 1 1197 1198 1199 # HG CM CM
+1014 2 1198 1199 1200 # CM CM CM
+1015 3 1199 1200 1201 # CM CM CM
+1016 4 1200 1201 1202 # CM CM CM
+1017 5 1201 1202 1203 # CM CM CM
+1018 6 1202 1203 1204 # CM CM CM
+1019 7 1203 1204 1205 # CM CM CM
+1020 8 1204 1205 1206 # CM CM CM
+1021 9 1205 1206 1207 # CM CM CM
+1022 10 1206 1207 1208 # CM CM CM
+1023 11 1207 1208 1209 # CM CM CT
+1024 1 1210 1211 1212 # HG CM CM
+1025 2 1211 1212 1213 # CM CM CM
+1026 3 1212 1213 1214 # CM CM CM
+1027 4 1213 1214 1215 # CM CM CM
+1028 5 1214 1215 1216 # CM CM CM
+1029 6 1215 1216 1217 # CM CM CM
+1030 7 1216 1217 1218 # CM CM CM
+1031 8 1217 1218 1219 # CM CM CM
+1032 9 1218 1219 1220 # CM CM CM
+1033 10 1219 1220 1221 # CM CM CM
+1034 11 1220 1221 1222 # CM CM CT
+1035 1 1223 1224 1225 # HG CM CM
+1036 2 1224 1225 1226 # CM CM CM
+1037 3 1225 1226 1227 # CM CM CM
+1038 4 1226 1227 1228 # CM CM CM
+1039 5 1227 1228 1229 # CM CM CM
+1040 6 1228 1229 1230 # CM CM CM
+1041 7 1229 1230 1231 # CM CM CM
+1042 8 1230 1231 1232 # CM CM CM
+1043 9 1231 1232 1233 # CM CM CM
+1044 10 1232 1233 1234 # CM CM CM
+1045 11 1233 1234 1235 # CM CM CT
+1046 1 1236 1237 1238 # HG CM CM
+1047 2 1237 1238 1239 # CM CM CM
+1048 3 1238 1239 1240 # CM CM CM
+1049 4 1239 1240 1241 # CM CM CM
+1050 5 1240 1241 1242 # CM CM CM
+1051 6 1241 1242 1243 # CM CM CM
+1052 7 1242 1243 1244 # CM CM CM
+1053 8 1243 1244 1245 # CM CM CM
+1054 9 1244 1245 1246 # CM CM CM
+1055 10 1245 1246 1247 # CM CM CM
+1056 11 1246 1247 1248 # CM CM CT
+1057 1 1249 1250 1251 # HG CM CM
+1058 2 1250 1251 1252 # CM CM CM
+1059 3 1251 1252 1253 # CM CM CM
+1060 4 1252 1253 1254 # CM CM CM
+1061 5 1253 1254 1255 # CM CM CM
+1062 6 1254 1255 1256 # CM CM CM
+1063 7 1255 1256 1257 # CM CM CM
+1064 8 1256 1257 1258 # CM CM CM
+1065 9 1257 1258 1259 # CM CM CM
+1066 10 1258 1259 1260 # CM CM CM
+1067 11 1259 1260 1261 # CM CM CT
+1068 1 1262 1263 1264 # HG CM CM
+1069 2 1263 1264 1265 # CM CM CM
+1070 3 1264 1265 1266 # CM CM CM
+1071 4 1265 1266 1267 # CM CM CM
+1072 5 1266 1267 1268 # CM CM CM
+1073 6 1267 1268 1269 # CM CM CM
+1074 7 1268 1269 1270 # CM CM CM
+1075 8 1269 1270 1271 # CM CM CM
+1076 9 1270 1271 1272 # CM CM CM
+1077 10 1271 1272 1273 # CM CM CM
+1078 11 1272 1273 1274 # CM CM CT
+1079 1 1275 1276 1277 # HG CM CM
+1080 2 1276 1277 1278 # CM CM CM
+1081 3 1277 1278 1279 # CM CM CM
+1082 4 1278 1279 1280 # CM CM CM
+1083 5 1279 1280 1281 # CM CM CM
+1084 6 1280 1281 1282 # CM CM CM
+1085 7 1281 1282 1283 # CM CM CM
+1086 8 1282 1283 1284 # CM CM CM
+1087 9 1283 1284 1285 # CM CM CM
+1088 10 1284 1285 1286 # CM CM CM
+1089 11 1285 1286 1287 # CM CM CT
+1090 1 1288 1289 1290 # HG CM CM
+1091 2 1289 1290 1291 # CM CM CM
+1092 3 1290 1291 1292 # CM CM CM
+1093 4 1291 1292 1293 # CM CM CM
+1094 5 1292 1293 1294 # CM CM CM
+1095 6 1293 1294 1295 # CM CM CM
+1096 7 1294 1295 1296 # CM CM CM
+1097 8 1295 1296 1297 # CM CM CM
+1098 9 1296 1297 1298 # CM CM CM
+1099 10 1297 1298 1299 # CM CM CM
+1100 11 1298 1299 1300 # CM CM CT
+1101 1 1301 1302 1303 # HG CM CM
+1102 2 1302 1303 1304 # CM CM CM
+1103 3 1303 1304 1305 # CM CM CM
+1104 4 1304 1305 1306 # CM CM CM
+1105 5 1305 1306 1307 # CM CM CM
+1106 6 1306 1307 1308 # CM CM CM
+1107 7 1307 1308 1309 # CM CM CM
+1108 8 1308 1309 1310 # CM CM CM
+1109 9 1309 1310 1311 # CM CM CM
+1110 10 1310 1311 1312 # CM CM CM
+1111 11 1311 1312 1313 # CM CM CT
+1112 1 1314 1315 1316 # HG CM CM
+1113 2 1315 1316 1317 # CM CM CM
+1114 3 1316 1317 1318 # CM CM CM
+1115 4 1317 1318 1319 # CM CM CM
+1116 5 1318 1319 1320 # CM CM CM
+1117 6 1319 1320 1321 # CM CM CM
+1118 7 1320 1321 1322 # CM CM CM
+1119 8 1321 1322 1323 # CM CM CM
+1120 9 1322 1323 1324 # CM CM CM
+1121 10 1323 1324 1325 # CM CM CM
+1122 11 1324 1325 1326 # CM CM CT
+1123 1 1327 1328 1329 # HG CM CM
+1124 2 1328 1329 1330 # CM CM CM
+1125 3 1329 1330 1331 # CM CM CM
+1126 4 1330 1331 1332 # CM CM CM
+1127 5 1331 1332 1333 # CM CM CM
+1128 6 1332 1333 1334 # CM CM CM
+1129 7 1333 1334 1335 # CM CM CM
+1130 8 1334 1335 1336 # CM CM CM
+1131 9 1335 1336 1337 # CM CM CM
+1132 10 1336 1337 1338 # CM CM CM
+1133 11 1337 1338 1339 # CM CM CT
+1134 1 1340 1341 1342 # HG CM CM
+1135 2 1341 1342 1343 # CM CM CM
+1136 3 1342 1343 1344 # CM CM CM
+1137 4 1343 1344 1345 # CM CM CM
+1138 5 1344 1345 1346 # CM CM CM
+1139 6 1345 1346 1347 # CM CM CM
+1140 7 1346 1347 1348 # CM CM CM
+1141 8 1347 1348 1349 # CM CM CM
+1142 9 1348 1349 1350 # CM CM CM
+1143 10 1349 1350 1351 # CM CM CM
+1144 11 1350 1351 1352 # CM CM CT
+1145 1 1353 1354 1355 # HG CM CM
+1146 2 1354 1355 1356 # CM CM CM
+1147 3 1355 1356 1357 # CM CM CM
+1148 4 1356 1357 1358 # CM CM CM
+1149 5 1357 1358 1359 # CM CM CM
+1150 6 1358 1359 1360 # CM CM CM
+1151 7 1359 1360 1361 # CM CM CM
+1152 8 1360 1361 1362 # CM CM CM
+1153 9 1361 1362 1363 # CM CM CM
+1154 10 1362 1363 1364 # CM CM CM
+1155 11 1363 1364 1365 # CM CM CT
+1156 1 1366 1367 1368 # HG CM CM
+1157 2 1367 1368 1369 # CM CM CM
+1158 3 1368 1369 1370 # CM CM CM
+1159 4 1369 1370 1371 # CM CM CM
+1160 5 1370 1371 1372 # CM CM CM
+1161 6 1371 1372 1373 # CM CM CM
+1162 7 1372 1373 1374 # CM CM CM
+1163 8 1373 1374 1375 # CM CM CM
+1164 9 1374 1375 1376 # CM CM CM
+1165 10 1375 1376 1377 # CM CM CM
+1166 11 1376 1377 1378 # CM CM CT
+1167 1 1379 1380 1381 # HG CM CM
+1168 2 1380 1381 1382 # CM CM CM
+1169 3 1381 1382 1383 # CM CM CM
+1170 4 1382 1383 1384 # CM CM CM
+1171 5 1383 1384 1385 # CM CM CM
+1172 6 1384 1385 1386 # CM CM CM
+1173 7 1385 1386 1387 # CM CM CM
+1174 8 1386 1387 1388 # CM CM CM
+1175 9 1387 1388 1389 # CM CM CM
+1176 10 1388 1389 1390 # CM CM CM
+1177 11 1389 1390 1391 # CM CM CT
+1178 1 1392 1393 1394 # HG CM CM
+1179 2 1393 1394 1395 # CM CM CM
+1180 3 1394 1395 1396 # CM CM CM
+1181 4 1395 1396 1397 # CM CM CM
+1182 5 1396 1397 1398 # CM CM CM
+1183 6 1397 1398 1399 # CM CM CM
+1184 7 1398 1399 1400 # CM CM CM
+1185 8 1399 1400 1401 # CM CM CM
+1186 9 1400 1401 1402 # CM CM CM
+1187 10 1401 1402 1403 # CM CM CM
+1188 11 1402 1403 1404 # CM CM CT
+1189 1 1405 1406 1407 # HG CM CM
+1190 2 1406 1407 1408 # CM CM CM
+1191 3 1407 1408 1409 # CM CM CM
+1192 4 1408 1409 1410 # CM CM CM
+1193 5 1409 1410 1411 # CM CM CM
+1194 6 1410 1411 1412 # CM CM CM
+1195 7 1411 1412 1413 # CM CM CM
+1196 8 1412 1413 1414 # CM CM CM
+1197 9 1413 1414 1415 # CM CM CM
+1198 10 1414 1415 1416 # CM CM CM
+1199 11 1415 1416 1417 # CM CM CT
+1200 1 1418 1419 1420 # HG CM CM
+1201 2 1419 1420 1421 # CM CM CM
+1202 3 1420 1421 1422 # CM CM CM
+1203 4 1421 1422 1423 # CM CM CM
+1204 5 1422 1423 1424 # CM CM CM
+1205 6 1423 1424 1425 # CM CM CM
+1206 7 1424 1425 1426 # CM CM CM
+1207 8 1425 1426 1427 # CM CM CM
+1208 9 1426 1427 1428 # CM CM CM
+1209 10 1427 1428 1429 # CM CM CM
+1210 11 1428 1429 1430 # CM CM CT
+1211 1 1431 1432 1433 # HG CM CM
+1212 2 1432 1433 1434 # CM CM CM
+1213 3 1433 1434 1435 # CM CM CM
+1214 4 1434 1435 1436 # CM CM CM
+1215 5 1435 1436 1437 # CM CM CM
+1216 6 1436 1437 1438 # CM CM CM
+1217 7 1437 1438 1439 # CM CM CM
+1218 8 1438 1439 1440 # CM CM CM
+1219 9 1439 1440 1441 # CM CM CM
+1220 10 1440 1441 1442 # CM CM CM
+1221 11 1441 1442 1443 # CM CM CT
+1222 1 1444 1445 1446 # HG CM CM
+1223 2 1445 1446 1447 # CM CM CM
+1224 3 1446 1447 1448 # CM CM CM
+1225 4 1447 1448 1449 # CM CM CM
+1226 5 1448 1449 1450 # CM CM CM
+1227 6 1449 1450 1451 # CM CM CM
+1228 7 1450 1451 1452 # CM CM CM
+1229 8 1451 1452 1453 # CM CM CM
+1230 9 1452 1453 1454 # CM CM CM
+1231 10 1453 1454 1455 # CM CM CM
+1232 11 1454 1455 1456 # CM CM CT
+1233 1 1457 1458 1459 # HG CM CM
+1234 2 1458 1459 1460 # CM CM CM
+1235 3 1459 1460 1461 # CM CM CM
+1236 4 1460 1461 1462 # CM CM CM
+1237 5 1461 1462 1463 # CM CM CM
+1238 6 1462 1463 1464 # CM CM CM
+1239 7 1463 1464 1465 # CM CM CM
+1240 8 1464 1465 1466 # CM CM CM
+1241 9 1465 1466 1467 # CM CM CM
+1242 10 1466 1467 1468 # CM CM CM
+1243 11 1467 1468 1469 # CM CM CT
+1244 1 1470 1471 1472 # HG CM CM
+1245 2 1471 1472 1473 # CM CM CM
+1246 3 1472 1473 1474 # CM CM CM
+1247 4 1473 1474 1475 # CM CM CM
+1248 5 1474 1475 1476 # CM CM CM
+1249 6 1475 1476 1477 # CM CM CM
+1250 7 1476 1477 1478 # CM CM CM
+1251 8 1477 1478 1479 # CM CM CM
+1252 9 1478 1479 1480 # CM CM CM
+1253 10 1479 1480 1481 # CM CM CM
+1254 11 1480 1481 1482 # CM CM CT
+1255 1 1483 1484 1485 # HG CM CM
+1256 2 1484 1485 1486 # CM CM CM
+1257 3 1485 1486 1487 # CM CM CM
+1258 4 1486 1487 1488 # CM CM CM
+1259 5 1487 1488 1489 # CM CM CM
+1260 6 1488 1489 1490 # CM CM CM
+1261 7 1489 1490 1491 # CM CM CM
+1262 8 1490 1491 1492 # CM CM CM
+1263 9 1491 1492 1493 # CM CM CM
+1264 10 1492 1493 1494 # CM CM CM
+1265 11 1493 1494 1495 # CM CM CT
+1266 1 1496 1497 1498 # HG CM CM
+1267 2 1497 1498 1499 # CM CM CM
+1268 3 1498 1499 1500 # CM CM CM
+1269 4 1499 1500 1501 # CM CM CM
+1270 5 1500 1501 1502 # CM CM CM
+1271 6 1501 1502 1503 # CM CM CM
+1272 7 1502 1503 1504 # CM CM CM
+1273 8 1503 1504 1505 # CM CM CM
+1274 9 1504 1505 1506 # CM CM CM
+1275 10 1505 1506 1507 # CM CM CM
+1276 11 1506 1507 1508 # CM CM CT
+1277 1 1509 1510 1511 # HG CM CM
+1278 2 1510 1511 1512 # CM CM CM
+1279 3 1511 1512 1513 # CM CM CM
+1280 4 1512 1513 1514 # CM CM CM
+1281 5 1513 1514 1515 # CM CM CM
+1282 6 1514 1515 1516 # CM CM CM
+1283 7 1515 1516 1517 # CM CM CM
+1284 8 1516 1517 1518 # CM CM CM
+1285 9 1517 1518 1519 # CM CM CM
+1286 10 1518 1519 1520 # CM CM CM
+1287 11 1519 1520 1521 # CM CM CT
+1288 1 1522 1523 1524 # HG CM CM
+1289 2 1523 1524 1525 # CM CM CM
+1290 3 1524 1525 1526 # CM CM CM
+1291 4 1525 1526 1527 # CM CM CM
+1292 5 1526 1527 1528 # CM CM CM
+1293 6 1527 1528 1529 # CM CM CM
+1294 7 1528 1529 1530 # CM CM CM
+1295 8 1529 1530 1531 # CM CM CM
+1296 9 1530 1531 1532 # CM CM CM
+1297 10 1531 1532 1533 # CM CM CM
+1298 11 1532 1533 1534 # CM CM CT
+1299 1 1535 1536 1537 # HG CM CM
+1300 2 1536 1537 1538 # CM CM CM
+1301 3 1537 1538 1539 # CM CM CM
+1302 4 1538 1539 1540 # CM CM CM
+1303 5 1539 1540 1541 # CM CM CM
+1304 6 1540 1541 1542 # CM CM CM
+1305 7 1541 1542 1543 # CM CM CM
+1306 8 1542 1543 1544 # CM CM CM
+1307 9 1543 1544 1545 # CM CM CM
+1308 10 1544 1545 1546 # CM CM CM
+1309 11 1545 1546 1547 # CM CM CT
+1310 1 1548 1549 1550 # HG CM CM
+1311 2 1549 1550 1551 # CM CM CM
+1312 3 1550 1551 1552 # CM CM CM
+1313 4 1551 1552 1553 # CM CM CM
+1314 5 1552 1553 1554 # CM CM CM
+1315 6 1553 1554 1555 # CM CM CM
+1316 7 1554 1555 1556 # CM CM CM
+1317 8 1555 1556 1557 # CM CM CM
+1318 9 1556 1557 1558 # CM CM CM
+1319 10 1557 1558 1559 # CM CM CM
+1320 11 1558 1559 1560 # CM CM CT
+1321 1 1561 1562 1563 # HG CM CM
+1322 2 1562 1563 1564 # CM CM CM
+1323 3 1563 1564 1565 # CM CM CM
+1324 4 1564 1565 1566 # CM CM CM
+1325 5 1565 1566 1567 # CM CM CM
+1326 6 1566 1567 1568 # CM CM CM
+1327 7 1567 1568 1569 # CM CM CM
+1328 8 1568 1569 1570 # CM CM CM
+1329 9 1569 1570 1571 # CM CM CM
+1330 10 1570 1571 1572 # CM CM CM
+1331 11 1571 1572 1573 # CM CM CT
+1332 1 1574 1575 1576 # HG CM CM
+1333 2 1575 1576 1577 # CM CM CM
+1334 3 1576 1577 1578 # CM CM CM
+1335 4 1577 1578 1579 # CM CM CM
+1336 5 1578 1579 1580 # CM CM CM
+1337 6 1579 1580 1581 # CM CM CM
+1338 7 1580 1581 1582 # CM CM CM
+1339 8 1581 1582 1583 # CM CM CM
+1340 9 1582 1583 1584 # CM CM CM
+1341 10 1583 1584 1585 # CM CM CM
+1342 11 1584 1585 1586 # CM CM CT
+1343 1 1587 1588 1589 # HG CM CM
+1344 2 1588 1589 1590 # CM CM CM
+1345 3 1589 1590 1591 # CM CM CM
+1346 4 1590 1591 1592 # CM CM CM
+1347 5 1591 1592 1593 # CM CM CM
+1348 6 1592 1593 1594 # CM CM CM
+1349 7 1593 1594 1595 # CM CM CM
+1350 8 1594 1595 1596 # CM CM CM
+1351 9 1595 1596 1597 # CM CM CM
+1352 10 1596 1597 1598 # CM CM CM
+1353 11 1597 1598 1599 # CM CM CT
+1354 1 1600 1601 1602 # HG CM CM
+1355 2 1601 1602 1603 # CM CM CM
+1356 3 1602 1603 1604 # CM CM CM
+1357 4 1603 1604 1605 # CM CM CM
+1358 5 1604 1605 1606 # CM CM CM
+1359 6 1605 1606 1607 # CM CM CM
+1360 7 1606 1607 1608 # CM CM CM
+1361 8 1607 1608 1609 # CM CM CM
+1362 9 1608 1609 1610 # CM CM CM
+1363 10 1609 1610 1611 # CM CM CM
+1364 11 1610 1611 1612 # CM CM CT
+1365 1 1613 1614 1615 # HG CM CM
+1366 2 1614 1615 1616 # CM CM CM
+1367 3 1615 1616 1617 # CM CM CM
+1368 4 1616 1617 1618 # CM CM CM
+1369 5 1617 1618 1619 # CM CM CM
+1370 6 1618 1619 1620 # CM CM CM
+1371 7 1619 1620 1621 # CM CM CM
+1372 8 1620 1621 1622 # CM CM CM
+1373 9 1621 1622 1623 # CM CM CM
+1374 10 1622 1623 1624 # CM CM CM
+1375 11 1623 1624 1625 # CM CM CT
+1376 1 1626 1627 1628 # HG CM CM
+1377 2 1627 1628 1629 # CM CM CM
+1378 3 1628 1629 1630 # CM CM CM
+1379 4 1629 1630 1631 # CM CM CM
+1380 5 1630 1631 1632 # CM CM CM
+1381 6 1631 1632 1633 # CM CM CM
+1382 7 1632 1633 1634 # CM CM CM
+1383 8 1633 1634 1635 # CM CM CM
+1384 9 1634 1635 1636 # CM CM CM
+1385 10 1635 1636 1637 # CM CM CM
+1386 11 1636 1637 1638 # CM CM CT
+1387 1 1639 1640 1641 # HG CM CM
+1388 2 1640 1641 1642 # CM CM CM
+1389 3 1641 1642 1643 # CM CM CM
+1390 4 1642 1643 1644 # CM CM CM
+1391 5 1643 1644 1645 # CM CM CM
+1392 6 1644 1645 1646 # CM CM CM
+1393 7 1645 1646 1647 # CM CM CM
+1394 8 1646 1647 1648 # CM CM CM
+1395 9 1647 1648 1649 # CM CM CM
+1396 10 1648 1649 1650 # CM CM CM
+1397 11 1649 1650 1651 # CM CM CT
+1398 1 1652 1653 1654 # HG CM CM
+1399 2 1653 1654 1655 # CM CM CM
+1400 3 1654 1655 1656 # CM CM CM
+1401 4 1655 1656 1657 # CM CM CM
+1402 5 1656 1657 1658 # CM CM CM
+1403 6 1657 1658 1659 # CM CM CM
+1404 7 1658 1659 1660 # CM CM CM
+1405 8 1659 1660 1661 # CM CM CM
+1406 9 1660 1661 1662 # CM CM CM
+1407 10 1661 1662 1663 # CM CM CM
+1408 11 1662 1663 1664 # CM CM CT
+1409 1 1665 1666 1667 # HG CM CM
+1410 2 1666 1667 1668 # CM CM CM
+1411 3 1667 1668 1669 # CM CM CM
+1412 4 1668 1669 1670 # CM CM CM
+1413 5 1669 1670 1671 # CM CM CM
+1414 6 1670 1671 1672 # CM CM CM
+1415 7 1671 1672 1673 # CM CM CM
+1416 8 1672 1673 1674 # CM CM CM
+1417 9 1673 1674 1675 # CM CM CM
+1418 10 1674 1675 1676 # CM CM CM
+1419 11 1675 1676 1677 # CM CM CT
+1420 1 1678 1679 1680 # HG CM CM
+1421 2 1679 1680 1681 # CM CM CM
+1422 3 1680 1681 1682 # CM CM CM
+1423 4 1681 1682 1683 # CM CM CM
+1424 5 1682 1683 1684 # CM CM CM
+1425 6 1683 1684 1685 # CM CM CM
+1426 7 1684 1685 1686 # CM CM CM
+1427 8 1685 1686 1687 # CM CM CM
+1428 9 1686 1687 1688 # CM CM CM
+1429 10 1687 1688 1689 # CM CM CM
+1430 11 1688 1689 1690 # CM CM CT
+1431 1 1691 1692 1693 # HG CM CM
+1432 2 1692 1693 1694 # CM CM CM
+1433 3 1693 1694 1695 # CM CM CM
+1434 4 1694 1695 1696 # CM CM CM
+1435 5 1695 1696 1697 # CM CM CM
+1436 6 1696 1697 1698 # CM CM CM
+1437 7 1697 1698 1699 # CM CM CM
+1438 8 1698 1699 1700 # CM CM CM
+1439 9 1699 1700 1701 # CM CM CM
+1440 10 1700 1701 1702 # CM CM CM
+1441 11 1701 1702 1703 # CM CM CT
+1442 1 1704 1705 1706 # HG CM CM
+1443 2 1705 1706 1707 # CM CM CM
+1444 3 1706 1707 1708 # CM CM CM
+1445 4 1707 1708 1709 # CM CM CM
+1446 5 1708 1709 1710 # CM CM CM
+1447 6 1709 1710 1711 # CM CM CM
+1448 7 1710 1711 1712 # CM CM CM
+1449 8 1711 1712 1713 # CM CM CM
+1450 9 1712 1713 1714 # CM CM CM
+1451 10 1713 1714 1715 # CM CM CM
+1452 11 1714 1715 1716 # CM CM CT
+1453 1 1717 1718 1719 # HG CM CM
+1454 2 1718 1719 1720 # CM CM CM
+1455 3 1719 1720 1721 # CM CM CM
+1456 4 1720 1721 1722 # CM CM CM
+1457 5 1721 1722 1723 # CM CM CM
+1458 6 1722 1723 1724 # CM CM CM
+1459 7 1723 1724 1725 # CM CM CM
+1460 8 1724 1725 1726 # CM CM CM
+1461 9 1725 1726 1727 # CM CM CM
+1462 10 1726 1727 1728 # CM CM CM
+1463 11 1727 1728 1729 # CM CM CT
+1464 1 1730 1731 1732 # HG CM CM
+1465 2 1731 1732 1733 # CM CM CM
+1466 3 1732 1733 1734 # CM CM CM
+1467 4 1733 1734 1735 # CM CM CM
+1468 5 1734 1735 1736 # CM CM CM
+1469 6 1735 1736 1737 # CM CM CM
+1470 7 1736 1737 1738 # CM CM CM
+1471 8 1737 1738 1739 # CM CM CM
+1472 9 1738 1739 1740 # CM CM CM
+1473 10 1739 1740 1741 # CM CM CM
+1474 11 1740 1741 1742 # CM CM CT
+1475 1 1743 1744 1745 # HG CM CM
+1476 2 1744 1745 1746 # CM CM CM
+1477 3 1745 1746 1747 # CM CM CM
+1478 4 1746 1747 1748 # CM CM CM
+1479 5 1747 1748 1749 # CM CM CM
+1480 6 1748 1749 1750 # CM CM CM
+1481 7 1749 1750 1751 # CM CM CM
+1482 8 1750 1751 1752 # CM CM CM
+1483 9 1751 1752 1753 # CM CM CM
+1484 10 1752 1753 1754 # CM CM CM
+1485 11 1753 1754 1755 # CM CM CT
+1486 1 1756 1757 1758 # HG CM CM
+1487 2 1757 1758 1759 # CM CM CM
+1488 3 1758 1759 1760 # CM CM CM
+1489 4 1759 1760 1761 # CM CM CM
+1490 5 1760 1761 1762 # CM CM CM
+1491 6 1761 1762 1763 # CM CM CM
+1492 7 1762 1763 1764 # CM CM CM
+1493 8 1763 1764 1765 # CM CM CM
+1494 9 1764 1765 1766 # CM CM CM
+1495 10 1765 1766 1767 # CM CM CM
+1496 11 1766 1767 1768 # CM CM CT
+1497 1 1769 1770 1771 # HG CM CM
+1498 2 1770 1771 1772 # CM CM CM
+1499 3 1771 1772 1773 # CM CM CM
+1500 4 1772 1773 1774 # CM CM CM
+1501 5 1773 1774 1775 # CM CM CM
+1502 6 1774 1775 1776 # CM CM CM
+1503 7 1775 1776 1777 # CM CM CM
+1504 8 1776 1777 1778 # CM CM CM
+1505 9 1777 1778 1779 # CM CM CM
+1506 10 1778 1779 1780 # CM CM CM
+1507 11 1779 1780 1781 # CM CM CT
+1508 1 1782 1783 1784 # HG CM CM
+1509 2 1783 1784 1785 # CM CM CM
+1510 3 1784 1785 1786 # CM CM CM
+1511 4 1785 1786 1787 # CM CM CM
+1512 5 1786 1787 1788 # CM CM CM
+1513 6 1787 1788 1789 # CM CM CM
+1514 7 1788 1789 1790 # CM CM CM
+1515 8 1789 1790 1791 # CM CM CM
+1516 9 1790 1791 1792 # CM CM CM
+1517 10 1791 1792 1793 # CM CM CM
+1518 11 1792 1793 1794 # CM CM CT
+1519 1 1795 1796 1797 # HG CM CM
+1520 2 1796 1797 1798 # CM CM CM
+1521 3 1797 1798 1799 # CM CM CM
+1522 4 1798 1799 1800 # CM CM CM
+1523 5 1799 1800 1801 # CM CM CM
+1524 6 1800 1801 1802 # CM CM CM
+1525 7 1801 1802 1803 # CM CM CM
+1526 8 1802 1803 1804 # CM CM CM
+1527 9 1803 1804 1805 # CM CM CM
+1528 10 1804 1805 1806 # CM CM CM
+1529 11 1805 1806 1807 # CM CM CT
+1530 1 1808 1809 1810 # HG CM CM
+1531 2 1809 1810 1811 # CM CM CM
+1532 3 1810 1811 1812 # CM CM CM
+1533 4 1811 1812 1813 # CM CM CM
+1534 5 1812 1813 1814 # CM CM CM
+1535 6 1813 1814 1815 # CM CM CM
+1536 7 1814 1815 1816 # CM CM CM
+1537 8 1815 1816 1817 # CM CM CM
+1538 9 1816 1817 1818 # CM CM CM
+1539 10 1817 1818 1819 # CM CM CM
+1540 11 1818 1819 1820 # CM CM CT
+1541 1 1821 1822 1823 # HG CM CM
+1542 2 1822 1823 1824 # CM CM CM
+1543 3 1823 1824 1825 # CM CM CM
+1544 4 1824 1825 1826 # CM CM CM
+1545 5 1825 1826 1827 # CM CM CM
+1546 6 1826 1827 1828 # CM CM CM
+1547 7 1827 1828 1829 # CM CM CM
+1548 8 1828 1829 1830 # CM CM CM
+1549 9 1829 1830 1831 # CM CM CM
+1550 10 1830 1831 1832 # CM CM CM
+1551 11 1831 1832 1833 # CM CM CT
+1552 1 1834 1835 1836 # HG CM CM
+1553 2 1835 1836 1837 # CM CM CM
+1554 3 1836 1837 1838 # CM CM CM
+1555 4 1837 1838 1839 # CM CM CM
+1556 5 1838 1839 1840 # CM CM CM
+1557 6 1839 1840 1841 # CM CM CM
+1558 7 1840 1841 1842 # CM CM CM
+1559 8 1841 1842 1843 # CM CM CM
+1560 9 1842 1843 1844 # CM CM CM
+1561 10 1843 1844 1845 # CM CM CM
+1562 11 1844 1845 1846 # CM CM CT
+1563 1 1847 1848 1849 # HG CM CM
+1564 2 1848 1849 1850 # CM CM CM
+1565 3 1849 1850 1851 # CM CM CM
+1566 4 1850 1851 1852 # CM CM CM
+1567 5 1851 1852 1853 # CM CM CM
+1568 6 1852 1853 1854 # CM CM CM
+1569 7 1853 1854 1855 # CM CM CM
+1570 8 1854 1855 1856 # CM CM CM
+1571 9 1855 1856 1857 # CM CM CM
+1572 10 1856 1857 1858 # CM CM CM
+1573 11 1857 1858 1859 # CM CM CT
+1574 1 1860 1861 1862 # HG CM CM
+1575 2 1861 1862 1863 # CM CM CM
+1576 3 1862 1863 1864 # CM CM CM
+1577 4 1863 1864 1865 # CM CM CM
+1578 5 1864 1865 1866 # CM CM CM
+1579 6 1865 1866 1867 # CM CM CM
+1580 7 1866 1867 1868 # CM CM CM
+1581 8 1867 1868 1869 # CM CM CM
+1582 9 1868 1869 1870 # CM CM CM
+1583 10 1869 1870 1871 # CM CM CM
+1584 11 1870 1871 1872 # CM CM CT
+1585 1 1873 1874 1875 # HG CM CM
+1586 2 1874 1875 1876 # CM CM CM
+1587 3 1875 1876 1877 # CM CM CM
+1588 4 1876 1877 1878 # CM CM CM
+1589 5 1877 1878 1879 # CM CM CM
+1590 6 1878 1879 1880 # CM CM CM
+1591 7 1879 1880 1881 # CM CM CM
+1592 8 1880 1881 1882 # CM CM CM
+1593 9 1881 1882 1883 # CM CM CM
+1594 10 1882 1883 1884 # CM CM CM
+1595 11 1883 1884 1885 # CM CM CT
+1596 1 1886 1887 1888 # HG CM CM
+1597 2 1887 1888 1889 # CM CM CM
+1598 3 1888 1889 1890 # CM CM CM
+1599 4 1889 1890 1891 # CM CM CM
+1600 5 1890 1891 1892 # CM CM CM
+1601 6 1891 1892 1893 # CM CM CM
+1602 7 1892 1893 1894 # CM CM CM
+1603 8 1893 1894 1895 # CM CM CM
+1604 9 1894 1895 1896 # CM CM CM
+1605 10 1895 1896 1897 # CM CM CM
+1606 11 1896 1897 1898 # CM CM CT
+1607 1 1899 1900 1901 # HG CM CM
+1608 2 1900 1901 1902 # CM CM CM
+1609 3 1901 1902 1903 # CM CM CM
+1610 4 1902 1903 1904 # CM CM CM
+1611 5 1903 1904 1905 # CM CM CM
+1612 6 1904 1905 1906 # CM CM CM
+1613 7 1905 1906 1907 # CM CM CM
+1614 8 1906 1907 1908 # CM CM CM
+1615 9 1907 1908 1909 # CM CM CM
+1616 10 1908 1909 1910 # CM CM CM
+1617 11 1909 1910 1911 # CM CM CT
+1618 1 1912 1913 1914 # HG CM CM
+1619 2 1913 1914 1915 # CM CM CM
+1620 3 1914 1915 1916 # CM CM CM
+1621 4 1915 1916 1917 # CM CM CM
+1622 5 1916 1917 1918 # CM CM CM
+1623 6 1917 1918 1919 # CM CM CM
+1624 7 1918 1919 1920 # CM CM CM
+1625 8 1919 1920 1921 # CM CM CM
+1626 9 1920 1921 1922 # CM CM CM
+1627 10 1921 1922 1923 # CM CM CM
+1628 11 1922 1923 1924 # CM CM CT
+1629 1 1925 1926 1927 # HG CM CM
+1630 2 1926 1927 1928 # CM CM CM
+1631 3 1927 1928 1929 # CM CM CM
+1632 4 1928 1929 1930 # CM CM CM
+1633 5 1929 1930 1931 # CM CM CM
+1634 6 1930 1931 1932 # CM CM CM
+1635 7 1931 1932 1933 # CM CM CM
+1636 8 1932 1933 1934 # CM CM CM
+1637 9 1933 1934 1935 # CM CM CM
+1638 10 1934 1935 1936 # CM CM CM
+1639 11 1935 1936 1937 # CM CM CT
+1640 1 1938 1939 1940 # HG CM CM
+1641 2 1939 1940 1941 # CM CM CM
+1642 3 1940 1941 1942 # CM CM CM
+1643 4 1941 1942 1943 # CM CM CM
+1644 5 1942 1943 1944 # CM CM CM
+1645 6 1943 1944 1945 # CM CM CM
+1646 7 1944 1945 1946 # CM CM CM
+1647 8 1945 1946 1947 # CM CM CM
+1648 9 1946 1947 1948 # CM CM CM
+1649 10 1947 1948 1949 # CM CM CM
+1650 11 1948 1949 1950 # CM CM CT
+1651 1 1951 1952 1953 # HG CM CM
+1652 2 1952 1953 1954 # CM CM CM
+1653 3 1953 1954 1955 # CM CM CM
+1654 4 1954 1955 1956 # CM CM CM
+1655 5 1955 1956 1957 # CM CM CM
+1656 6 1956 1957 1958 # CM CM CM
+1657 7 1957 1958 1959 # CM CM CM
+1658 8 1958 1959 1960 # CM CM CM
+1659 9 1959 1960 1961 # CM CM CM
+1660 10 1960 1961 1962 # CM CM CM
+1661 11 1961 1962 1963 # CM CM CT
+1662 1 1964 1965 1966 # HG CM CM
+1663 2 1965 1966 1967 # CM CM CM
+1664 3 1966 1967 1968 # CM CM CM
+1665 4 1967 1968 1969 # CM CM CM
+1666 5 1968 1969 1970 # CM CM CM
+1667 6 1969 1970 1971 # CM CM CM
+1668 7 1970 1971 1972 # CM CM CM
+1669 8 1971 1972 1973 # CM CM CM
+1670 9 1972 1973 1974 # CM CM CM
+1671 10 1973 1974 1975 # CM CM CM
+1672 11 1974 1975 1976 # CM CM CT
+1673 1 1977 1978 1979 # HG CM CM
+1674 2 1978 1979 1980 # CM CM CM
+1675 3 1979 1980 1981 # CM CM CM
+1676 4 1980 1981 1982 # CM CM CM
+1677 5 1981 1982 1983 # CM CM CM
+1678 6 1982 1983 1984 # CM CM CM
+1679 7 1983 1984 1985 # CM CM CM
+1680 8 1984 1985 1986 # CM CM CM
+1681 9 1985 1986 1987 # CM CM CM
+1682 10 1986 1987 1988 # CM CM CM
+1683 11 1987 1988 1989 # CM CM CT
+1684 1 1990 1991 1992 # HG CM CM
+1685 2 1991 1992 1993 # CM CM CM
+1686 3 1992 1993 1994 # CM CM CM
+1687 4 1993 1994 1995 # CM CM CM
+1688 5 1994 1995 1996 # CM CM CM
+1689 6 1995 1996 1997 # CM CM CM
+1690 7 1996 1997 1998 # CM CM CM
+1691 8 1997 1998 1999 # CM CM CM
+1692 9 1998 1999 2000 # CM CM CM
+1693 10 1999 2000 2001 # CM CM CM
+1694 11 2000 2001 2002 # CM CM CT
+1695 1 2003 2004 2005 # HG CM CM
+1696 2 2004 2005 2006 # CM CM CM
+1697 3 2005 2006 2007 # CM CM CM
+1698 4 2006 2007 2008 # CM CM CM
+1699 5 2007 2008 2009 # CM CM CM
+1700 6 2008 2009 2010 # CM CM CM
+1701 7 2009 2010 2011 # CM CM CM
+1702 8 2010 2011 2012 # CM CM CM
+1703 9 2011 2012 2013 # CM CM CM
+1704 10 2012 2013 2014 # CM CM CM
+1705 11 2013 2014 2015 # CM CM CT
+1706 1 2016 2017 2018 # HG CM CM
+1707 2 2017 2018 2019 # CM CM CM
+1708 3 2018 2019 2020 # CM CM CM
+1709 4 2019 2020 2021 # CM CM CM
+1710 5 2020 2021 2022 # CM CM CM
+1711 6 2021 2022 2023 # CM CM CM
+1712 7 2022 2023 2024 # CM CM CM
+1713 8 2023 2024 2025 # CM CM CM
+1714 9 2024 2025 2026 # CM CM CM
+1715 10 2025 2026 2027 # CM CM CM
+1716 11 2026 2027 2028 # CM CM CT
+1717 1 2029 2030 2031 # HG CM CM
+1718 2 2030 2031 2032 # CM CM CM
+1719 3 2031 2032 2033 # CM CM CM
+1720 4 2032 2033 2034 # CM CM CM
+1721 5 2033 2034 2035 # CM CM CM
+1722 6 2034 2035 2036 # CM CM CM
+1723 7 2035 2036 2037 # CM CM CM
+1724 8 2036 2037 2038 # CM CM CM
+1725 9 2037 2038 2039 # CM CM CM
+1726 10 2038 2039 2040 # CM CM CM
+1727 11 2039 2040 2041 # CM CM CT
+1728 1 2042 2043 2044 # HG CM CM
+1729 2 2043 2044 2045 # CM CM CM
+1730 3 2044 2045 2046 # CM CM CM
+1731 4 2045 2046 2047 # CM CM CM
+1732 5 2046 2047 2048 # CM CM CM
+1733 6 2047 2048 2049 # CM CM CM
+1734 7 2048 2049 2050 # CM CM CM
+1735 8 2049 2050 2051 # CM CM CM
+1736 9 2050 2051 2052 # CM CM CM
+1737 10 2051 2052 2053 # CM CM CM
+1738 11 2052 2053 2054 # CM CM CT
+1739 1 2055 2056 2057 # HG CM CM
+1740 2 2056 2057 2058 # CM CM CM
+1741 3 2057 2058 2059 # CM CM CM
+1742 4 2058 2059 2060 # CM CM CM
+1743 5 2059 2060 2061 # CM CM CM
+1744 6 2060 2061 2062 # CM CM CM
+1745 7 2061 2062 2063 # CM CM CM
+1746 8 2062 2063 2064 # CM CM CM
+1747 9 2063 2064 2065 # CM CM CM
+1748 10 2064 2065 2066 # CM CM CM
+1749 11 2065 2066 2067 # CM CM CT
+1750 1 2068 2069 2070 # HG CM CM
+1751 2 2069 2070 2071 # CM CM CM
+1752 3 2070 2071 2072 # CM CM CM
+1753 4 2071 2072 2073 # CM CM CM
+1754 5 2072 2073 2074 # CM CM CM
+1755 6 2073 2074 2075 # CM CM CM
+1756 7 2074 2075 2076 # CM CM CM
+1757 8 2075 2076 2077 # CM CM CM
+1758 9 2076 2077 2078 # CM CM CM
+1759 10 2077 2078 2079 # CM CM CM
+1760 11 2078 2079 2080 # CM CM CT
+1761 1 2081 2082 2083 # HG CM CM
+1762 2 2082 2083 2084 # CM CM CM
+1763 3 2083 2084 2085 # CM CM CM
+1764 4 2084 2085 2086 # CM CM CM
+1765 5 2085 2086 2087 # CM CM CM
+1766 6 2086 2087 2088 # CM CM CM
+1767 7 2087 2088 2089 # CM CM CM
+1768 8 2088 2089 2090 # CM CM CM
+1769 9 2089 2090 2091 # CM CM CM
+1770 10 2090 2091 2092 # CM CM CM
+1771 11 2091 2092 2093 # CM CM CT
+1772 1 2094 2095 2096 # HG CM CM
+1773 2 2095 2096 2097 # CM CM CM
+1774 3 2096 2097 2098 # CM CM CM
+1775 4 2097 2098 2099 # CM CM CM
+1776 5 2098 2099 2100 # CM CM CM
+1777 6 2099 2100 2101 # CM CM CM
+1778 7 2100 2101 2102 # CM CM CM
+1779 8 2101 2102 2103 # CM CM CM
+1780 9 2102 2103 2104 # CM CM CM
+1781 10 2103 2104 2105 # CM CM CM
+1782 11 2104 2105 2106 # CM CM CT
+1783 1 2107 2108 2109 # HG CM CM
+1784 2 2108 2109 2110 # CM CM CM
+1785 3 2109 2110 2111 # CM CM CM
+1786 4 2110 2111 2112 # CM CM CM
+1787 5 2111 2112 2113 # CM CM CM
+1788 6 2112 2113 2114 # CM CM CM
+1789 7 2113 2114 2115 # CM CM CM
+1790 8 2114 2115 2116 # CM CM CM
+1791 9 2115 2116 2117 # CM CM CM
+1792 10 2116 2117 2118 # CM CM CM
+1793 11 2117 2118 2119 # CM CM CT
+1794 1 2120 2121 2122 # HG CM CM
+1795 2 2121 2122 2123 # CM CM CM
+1796 3 2122 2123 2124 # CM CM CM
+1797 4 2123 2124 2125 # CM CM CM
+1798 5 2124 2125 2126 # CM CM CM
+1799 6 2125 2126 2127 # CM CM CM
+1800 7 2126 2127 2128 # CM CM CM
+1801 8 2127 2128 2129 # CM CM CM
+1802 9 2128 2129 2130 # CM CM CM
+1803 10 2129 2130 2131 # CM CM CM
+1804 11 2130 2131 2132 # CM CM CT
+1805 1 2133 2134 2135 # HG CM CM
+1806 2 2134 2135 2136 # CM CM CM
+1807 3 2135 2136 2137 # CM CM CM
+1808 4 2136 2137 2138 # CM CM CM
+1809 5 2137 2138 2139 # CM CM CM
+1810 6 2138 2139 2140 # CM CM CM
+1811 7 2139 2140 2141 # CM CM CM
+1812 8 2140 2141 2142 # CM CM CM
+1813 9 2141 2142 2143 # CM CM CM
+1814 10 2142 2143 2144 # CM CM CM
+1815 11 2143 2144 2145 # CM CM CT
+1816 1 2146 2147 2148 # HG CM CM
+1817 2 2147 2148 2149 # CM CM CM
+1818 3 2148 2149 2150 # CM CM CM
+1819 4 2149 2150 2151 # CM CM CM
+1820 5 2150 2151 2152 # CM CM CM
+1821 6 2151 2152 2153 # CM CM CM
+1822 7 2152 2153 2154 # CM CM CM
+1823 8 2153 2154 2155 # CM CM CM
+1824 9 2154 2155 2156 # CM CM CM
+1825 10 2155 2156 2157 # CM CM CM
+1826 11 2156 2157 2158 # CM CM CT
+1827 1 2159 2160 2161 # HG CM CM
+1828 2 2160 2161 2162 # CM CM CM
+1829 3 2161 2162 2163 # CM CM CM
+1830 4 2162 2163 2164 # CM CM CM
+1831 5 2163 2164 2165 # CM CM CM
+1832 6 2164 2165 2166 # CM CM CM
+1833 7 2165 2166 2167 # CM CM CM
+1834 8 2166 2167 2168 # CM CM CM
+1835 9 2167 2168 2169 # CM CM CM
+1836 10 2168 2169 2170 # CM CM CM
+1837 11 2169 2170 2171 # CM CM CT
+1838 1 2172 2173 2174 # HG CM CM
+1839 2 2173 2174 2175 # CM CM CM
+1840 3 2174 2175 2176 # CM CM CM
+1841 4 2175 2176 2177 # CM CM CM
+1842 5 2176 2177 2178 # CM CM CM
+1843 6 2177 2178 2179 # CM CM CM
+1844 7 2178 2179 2180 # CM CM CM
+1845 8 2179 2180 2181 # CM CM CM
+1846 9 2180 2181 2182 # CM CM CM
+1847 10 2181 2182 2183 # CM CM CM
+1848 11 2182 2183 2184 # CM CM CT
+1849 1 2185 2186 2187 # HG CM CM
+1850 2 2186 2187 2188 # CM CM CM
+1851 3 2187 2188 2189 # CM CM CM
+1852 4 2188 2189 2190 # CM CM CM
+1853 5 2189 2190 2191 # CM CM CM
+1854 6 2190 2191 2192 # CM CM CM
+1855 7 2191 2192 2193 # CM CM CM
+1856 8 2192 2193 2194 # CM CM CM
+1857 9 2193 2194 2195 # CM CM CM
+1858 10 2194 2195 2196 # CM CM CM
+1859 11 2195 2196 2197 # CM CM CT
+1860 1 2198 2199 2200 # HG CM CM
+1861 2 2199 2200 2201 # CM CM CM
+1862 3 2200 2201 2202 # CM CM CM
+1863 4 2201 2202 2203 # CM CM CM
+1864 5 2202 2203 2204 # CM CM CM
+1865 6 2203 2204 2205 # CM CM CM
+1866 7 2204 2205 2206 # CM CM CM
+1867 8 2205 2206 2207 # CM CM CM
+1868 9 2206 2207 2208 # CM CM CM
+1869 10 2207 2208 2209 # CM CM CM
+1870 11 2208 2209 2210 # CM CM CT
+1871 1 2211 2212 2213 # HG CM CM
+1872 2 2212 2213 2214 # CM CM CM
+1873 3 2213 2214 2215 # CM CM CM
+1874 4 2214 2215 2216 # CM CM CM
+1875 5 2215 2216 2217 # CM CM CM
+1876 6 2216 2217 2218 # CM CM CM
+1877 7 2217 2218 2219 # CM CM CM
+1878 8 2218 2219 2220 # CM CM CM
+1879 9 2219 2220 2221 # CM CM CM
+1880 10 2220 2221 2222 # CM CM CM
+1881 11 2221 2222 2223 # CM CM CT
+1882 1 2224 2225 2226 # HG CM CM
+1883 2 2225 2226 2227 # CM CM CM
+1884 3 2226 2227 2228 # CM CM CM
+1885 4 2227 2228 2229 # CM CM CM
+1886 5 2228 2229 2230 # CM CM CM
+1887 6 2229 2230 2231 # CM CM CM
+1888 7 2230 2231 2232 # CM CM CM
+1889 8 2231 2232 2233 # CM CM CM
+1890 9 2232 2233 2234 # CM CM CM
+1891 10 2233 2234 2235 # CM CM CM
+1892 11 2234 2235 2236 # CM CM CT
+1893 1 2237 2238 2239 # HG CM CM
+1894 2 2238 2239 2240 # CM CM CM
+1895 3 2239 2240 2241 # CM CM CM
+1896 4 2240 2241 2242 # CM CM CM
+1897 5 2241 2242 2243 # CM CM CM
+1898 6 2242 2243 2244 # CM CM CM
+1899 7 2243 2244 2245 # CM CM CM
+1900 8 2244 2245 2246 # CM CM CM
+1901 9 2245 2246 2247 # CM CM CM
+1902 10 2246 2247 2248 # CM CM CM
+1903 11 2247 2248 2249 # CM CM CT
+1904 1 2250 2251 2252 # HG CM CM
+1905 2 2251 2252 2253 # CM CM CM
+1906 3 2252 2253 2254 # CM CM CM
+1907 4 2253 2254 2255 # CM CM CM
+1908 5 2254 2255 2256 # CM CM CM
+1909 6 2255 2256 2257 # CM CM CM
+1910 7 2256 2257 2258 # CM CM CM
+1911 8 2257 2258 2259 # CM CM CM
+1912 9 2258 2259 2260 # CM CM CM
+1913 10 2259 2260 2261 # CM CM CM
+1914 11 2260 2261 2262 # CM CM CT
+1915 1 2263 2264 2265 # HG CM CM
+1916 2 2264 2265 2266 # CM CM CM
+1917 3 2265 2266 2267 # CM CM CM
+1918 4 2266 2267 2268 # CM CM CM
+1919 5 2267 2268 2269 # CM CM CM
+1920 6 2268 2269 2270 # CM CM CM
+1921 7 2269 2270 2271 # CM CM CM
+1922 8 2270 2271 2272 # CM CM CM
+1923 9 2271 2272 2273 # CM CM CM
+1924 10 2272 2273 2274 # CM CM CM
+1925 11 2273 2274 2275 # CM CM CT
+1926 1 2276 2277 2278 # HG CM CM
+1927 2 2277 2278 2279 # CM CM CM
+1928 3 2278 2279 2280 # CM CM CM
+1929 4 2279 2280 2281 # CM CM CM
+1930 5 2280 2281 2282 # CM CM CM
+1931 6 2281 2282 2283 # CM CM CM
+1932 7 2282 2283 2284 # CM CM CM
+1933 8 2283 2284 2285 # CM CM CM
+1934 9 2284 2285 2286 # CM CM CM
+1935 10 2285 2286 2287 # CM CM CM
+1936 11 2286 2287 2288 # CM CM CT
+1937 1 2289 2290 2291 # HG CM CM
+1938 2 2290 2291 2292 # CM CM CM
+1939 3 2291 2292 2293 # CM CM CM
+1940 4 2292 2293 2294 # CM CM CM
+1941 5 2293 2294 2295 # CM CM CM
+1942 6 2294 2295 2296 # CM CM CM
+1943 7 2295 2296 2297 # CM CM CM
+1944 8 2296 2297 2298 # CM CM CM
+1945 9 2297 2298 2299 # CM CM CM
+1946 10 2298 2299 2300 # CM CM CM
+1947 11 2299 2300 2301 # CM CM CT
+1948 1 2302 2303 2304 # HG CM CM
+1949 2 2303 2304 2305 # CM CM CM
+1950 3 2304 2305 2306 # CM CM CM
+1951 4 2305 2306 2307 # CM CM CM
+1952 5 2306 2307 2308 # CM CM CM
+1953 6 2307 2308 2309 # CM CM CM
+1954 7 2308 2309 2310 # CM CM CM
+1955 8 2309 2310 2311 # CM CM CM
+1956 9 2310 2311 2312 # CM CM CM
+1957 10 2311 2312 2313 # CM CM CM
+1958 11 2312 2313 2314 # CM CM CT
+1959 1 2315 2316 2317 # HG CM CM
+1960 2 2316 2317 2318 # CM CM CM
+1961 3 2317 2318 2319 # CM CM CM
+1962 4 2318 2319 2320 # CM CM CM
+1963 5 2319 2320 2321 # CM CM CM
+1964 6 2320 2321 2322 # CM CM CM
+1965 7 2321 2322 2323 # CM CM CM
+1966 8 2322 2323 2324 # CM CM CM
+1967 9 2323 2324 2325 # CM CM CM
+1968 10 2324 2325 2326 # CM CM CM
+1969 11 2325 2326 2327 # CM CM CT
+1970 1 2328 2329 2330 # HG CM CM
+1971 2 2329 2330 2331 # CM CM CM
+1972 3 2330 2331 2332 # CM CM CM
+1973 4 2331 2332 2333 # CM CM CM
+1974 5 2332 2333 2334 # CM CM CM
+1975 6 2333 2334 2335 # CM CM CM
+1976 7 2334 2335 2336 # CM CM CM
+1977 8 2335 2336 2337 # CM CM CM
+1978 9 2336 2337 2338 # CM CM CM
+1979 10 2337 2338 2339 # CM CM CM
+1980 11 2338 2339 2340 # CM CM CT
+1981 1 2341 2342 2343 # HG CM CM
+1982 2 2342 2343 2344 # CM CM CM
+1983 3 2343 2344 2345 # CM CM CM
+1984 4 2344 2345 2346 # CM CM CM
+1985 5 2345 2346 2347 # CM CM CM
+1986 6 2346 2347 2348 # CM CM CM
+1987 7 2347 2348 2349 # CM CM CM
+1988 8 2348 2349 2350 # CM CM CM
+1989 9 2349 2350 2351 # CM CM CM
+1990 10 2350 2351 2352 # CM CM CM
+1991 11 2351 2352 2353 # CM CM CT
+1992 1 2354 2355 2356 # HG CM CM
+1993 2 2355 2356 2357 # CM CM CM
+1994 3 2356 2357 2358 # CM CM CM
+1995 4 2357 2358 2359 # CM CM CM
+1996 5 2358 2359 2360 # CM CM CM
+1997 6 2359 2360 2361 # CM CM CM
+1998 7 2360 2361 2362 # CM CM CM
+1999 8 2361 2362 2363 # CM CM CM
+2000 9 2362 2363 2364 # CM CM CM
+2001 10 2363 2364 2365 # CM CM CM
+2002 11 2364 2365 2366 # CM CM CT
+2003 1 2367 2368 2369 # HG CM CM
+2004 2 2368 2369 2370 # CM CM CM
+2005 3 2369 2370 2371 # CM CM CM
+2006 4 2370 2371 2372 # CM CM CM
+2007 5 2371 2372 2373 # CM CM CM
+2008 6 2372 2373 2374 # CM CM CM
+2009 7 2373 2374 2375 # CM CM CM
+2010 8 2374 2375 2376 # CM CM CM
+2011 9 2375 2376 2377 # CM CM CM
+2012 10 2376 2377 2378 # CM CM CM
+2013 11 2377 2378 2379 # CM CM CT
+2014 1 2380 2381 2382 # HG CM CM
+2015 2 2381 2382 2383 # CM CM CM
+2016 3 2382 2383 2384 # CM CM CM
+2017 4 2383 2384 2385 # CM CM CM
+2018 5 2384 2385 2386 # CM CM CM
+2019 6 2385 2386 2387 # CM CM CM
+2020 7 2386 2387 2388 # CM CM CM
+2021 8 2387 2388 2389 # CM CM CM
+2022 9 2388 2389 2390 # CM CM CM
+2023 10 2389 2390 2391 # CM CM CM
+2024 11 2390 2391 2392 # CM CM CT
+2025 1 2393 2394 2395 # HG CM CM
+2026 2 2394 2395 2396 # CM CM CM
+2027 3 2395 2396 2397 # CM CM CM
+2028 4 2396 2397 2398 # CM CM CM
+2029 5 2397 2398 2399 # CM CM CM
+2030 6 2398 2399 2400 # CM CM CM
+2031 7 2399 2400 2401 # CM CM CM
+2032 8 2400 2401 2402 # CM CM CM
+2033 9 2401 2402 2403 # CM CM CM
+2034 10 2402 2403 2404 # CM CM CM
+2035 11 2403 2404 2405 # CM CM CT
+2036 1 2406 2407 2408 # HG CM CM
+2037 2 2407 2408 2409 # CM CM CM
+2038 3 2408 2409 2410 # CM CM CM
+2039 4 2409 2410 2411 # CM CM CM
+2040 5 2410 2411 2412 # CM CM CM
+2041 6 2411 2412 2413 # CM CM CM
+2042 7 2412 2413 2414 # CM CM CM
+2043 8 2413 2414 2415 # CM CM CM
+2044 9 2414 2415 2416 # CM CM CM
+2045 10 2415 2416 2417 # CM CM CM
+2046 11 2416 2417 2418 # CM CM CT
+2047 1 2419 2420 2421 # HG CM CM
+2048 2 2420 2421 2422 # CM CM CM
+2049 3 2421 2422 2423 # CM CM CM
+2050 4 2422 2423 2424 # CM CM CM
+2051 5 2423 2424 2425 # CM CM CM
+2052 6 2424 2425 2426 # CM CM CM
+2053 7 2425 2426 2427 # CM CM CM
+2054 8 2426 2427 2428 # CM CM CM
+2055 9 2427 2428 2429 # CM CM CM
+2056 10 2428 2429 2430 # CM CM CM
+2057 11 2429 2430 2431 # CM CM CT
+2058 1 2432 2433 2434 # HG CM CM
+2059 2 2433 2434 2435 # CM CM CM
+2060 3 2434 2435 2436 # CM CM CM
+2061 4 2435 2436 2437 # CM CM CM
+2062 5 2436 2437 2438 # CM CM CM
+2063 6 2437 2438 2439 # CM CM CM
+2064 7 2438 2439 2440 # CM CM CM
+2065 8 2439 2440 2441 # CM CM CM
+2066 9 2440 2441 2442 # CM CM CM
+2067 10 2441 2442 2443 # CM CM CM
+2068 11 2442 2443 2444 # CM CM CT
+2069 1 2445 2446 2447 # HG CM CM
+2070 2 2446 2447 2448 # CM CM CM
+2071 3 2447 2448 2449 # CM CM CM
+2072 4 2448 2449 2450 # CM CM CM
+2073 5 2449 2450 2451 # CM CM CM
+2074 6 2450 2451 2452 # CM CM CM
+2075 7 2451 2452 2453 # CM CM CM
+2076 8 2452 2453 2454 # CM CM CM
+2077 9 2453 2454 2455 # CM CM CM
+2078 10 2454 2455 2456 # CM CM CM
+2079 11 2455 2456 2457 # CM CM CT
+2080 1 2458 2459 2460 # HG CM CM
+2081 2 2459 2460 2461 # CM CM CM
+2082 3 2460 2461 2462 # CM CM CM
+2083 4 2461 2462 2463 # CM CM CM
+2084 5 2462 2463 2464 # CM CM CM
+2085 6 2463 2464 2465 # CM CM CM
+2086 7 2464 2465 2466 # CM CM CM
+2087 8 2465 2466 2467 # CM CM CM
+2088 9 2466 2467 2468 # CM CM CM
+2089 10 2467 2468 2469 # CM CM CM
+2090 11 2468 2469 2470 # CM CM CT
+2091 1 2471 2472 2473 # HG CM CM
+2092 2 2472 2473 2474 # CM CM CM
+2093 3 2473 2474 2475 # CM CM CM
+2094 4 2474 2475 2476 # CM CM CM
+2095 5 2475 2476 2477 # CM CM CM
+2096 6 2476 2477 2478 # CM CM CM
+2097 7 2477 2478 2479 # CM CM CM
+2098 8 2478 2479 2480 # CM CM CM
+2099 9 2479 2480 2481 # CM CM CM
+2100 10 2480 2481 2482 # CM CM CM
+2101 11 2481 2482 2483 # CM CM CT
+2102 1 2484 2485 2486 # HG CM CM
+2103 2 2485 2486 2487 # CM CM CM
+2104 3 2486 2487 2488 # CM CM CM
+2105 4 2487 2488 2489 # CM CM CM
+2106 5 2488 2489 2490 # CM CM CM
+2107 6 2489 2490 2491 # CM CM CM
+2108 7 2490 2491 2492 # CM CM CM
+2109 8 2491 2492 2493 # CM CM CM
+2110 9 2492 2493 2494 # CM CM CM
+2111 10 2493 2494 2495 # CM CM CM
+2112 11 2494 2495 2496 # CM CM CT
+2113 1 2497 2498 2499 # HG CM CM
+2114 2 2498 2499 2500 # CM CM CM
+2115 3 2499 2500 2501 # CM CM CM
+2116 4 2500 2501 2502 # CM CM CM
+2117 5 2501 2502 2503 # CM CM CM
+2118 6 2502 2503 2504 # CM CM CM
+2119 7 2503 2504 2505 # CM CM CM
+2120 8 2504 2505 2506 # CM CM CM
+2121 9 2505 2506 2507 # CM CM CM
+2122 10 2506 2507 2508 # CM CM CM
+2123 11 2507 2508 2509 # CM CM CT
+2124 1 2510 2511 2512 # HG CM CM
+2125 2 2511 2512 2513 # CM CM CM
+2126 3 2512 2513 2514 # CM CM CM
+2127 4 2513 2514 2515 # CM CM CM
+2128 5 2514 2515 2516 # CM CM CM
+2129 6 2515 2516 2517 # CM CM CM
+2130 7 2516 2517 2518 # CM CM CM
+2131 8 2517 2518 2519 # CM CM CM
+2132 9 2518 2519 2520 # CM CM CM
+2133 10 2519 2520 2521 # CM CM CM
+2134 11 2520 2521 2522 # CM CM CT
+2135 1 2523 2524 2525 # HG CM CM
+2136 2 2524 2525 2526 # CM CM CM
+2137 3 2525 2526 2527 # CM CM CM
+2138 4 2526 2527 2528 # CM CM CM
+2139 5 2527 2528 2529 # CM CM CM
+2140 6 2528 2529 2530 # CM CM CM
+2141 7 2529 2530 2531 # CM CM CM
+2142 8 2530 2531 2532 # CM CM CM
+2143 9 2531 2532 2533 # CM CM CM
+2144 10 2532 2533 2534 # CM CM CM
+2145 11 2533 2534 2535 # CM CM CT
+2146 1 2536 2537 2538 # HG CM CM
+2147 2 2537 2538 2539 # CM CM CM
+2148 3 2538 2539 2540 # CM CM CM
+2149 4 2539 2540 2541 # CM CM CM
+2150 5 2540 2541 2542 # CM CM CM
+2151 6 2541 2542 2543 # CM CM CM
+2152 7 2542 2543 2544 # CM CM CM
+2153 8 2543 2544 2545 # CM CM CM
+2154 9 2544 2545 2546 # CM CM CM
+2155 10 2545 2546 2547 # CM CM CM
+2156 11 2546 2547 2548 # CM CM CT
+2157 1 2549 2550 2551 # HG CM CM
+2158 2 2550 2551 2552 # CM CM CM
+2159 3 2551 2552 2553 # CM CM CM
+2160 4 2552 2553 2554 # CM CM CM
+2161 5 2553 2554 2555 # CM CM CM
+2162 6 2554 2555 2556 # CM CM CM
+2163 7 2555 2556 2557 # CM CM CM
+2164 8 2556 2557 2558 # CM CM CM
+2165 9 2557 2558 2559 # CM CM CM
+2166 10 2558 2559 2560 # CM CM CM
+2167 11 2559 2560 2561 # CM CM CT
+2168 1 2562 2563 2564 # HG CM CM
+2169 2 2563 2564 2565 # CM CM CM
+2170 3 2564 2565 2566 # CM CM CM
+2171 4 2565 2566 2567 # CM CM CM
+2172 5 2566 2567 2568 # CM CM CM
+2173 6 2567 2568 2569 # CM CM CM
+2174 7 2568 2569 2570 # CM CM CM
+2175 8 2569 2570 2571 # CM CM CM
+2176 9 2570 2571 2572 # CM CM CM
+2177 10 2571 2572 2573 # CM CM CM
+2178 11 2572 2573 2574 # CM CM CT
+2179 1 2575 2576 2577 # HG CM CM
+2180 2 2576 2577 2578 # CM CM CM
+2181 3 2577 2578 2579 # CM CM CM
+2182 4 2578 2579 2580 # CM CM CM
+2183 5 2579 2580 2581 # CM CM CM
+2184 6 2580 2581 2582 # CM CM CM
+2185 7 2581 2582 2583 # CM CM CM
+2186 8 2582 2583 2584 # CM CM CM
+2187 9 2583 2584 2585 # CM CM CM
+2188 10 2584 2585 2586 # CM CM CM
+2189 11 2585 2586 2587 # CM CM CT
+2190 1 2588 2589 2590 # HG CM CM
+2191 2 2589 2590 2591 # CM CM CM
+2192 3 2590 2591 2592 # CM CM CM
+2193 4 2591 2592 2593 # CM CM CM
+2194 5 2592 2593 2594 # CM CM CM
+2195 6 2593 2594 2595 # CM CM CM
+2196 7 2594 2595 2596 # CM CM CM
+2197 8 2595 2596 2597 # CM CM CM
+2198 9 2596 2597 2598 # CM CM CM
+2199 10 2597 2598 2599 # CM CM CM
+2200 11 2598 2599 2600 # CM CM CT
+2201 1 2601 2602 2603 # HG CM CM
+2202 2 2602 2603 2604 # CM CM CM
+2203 3 2603 2604 2605 # CM CM CM
+2204 4 2604 2605 2606 # CM CM CM
+2205 5 2605 2606 2607 # CM CM CM
+2206 6 2606 2607 2608 # CM CM CM
+2207 7 2607 2608 2609 # CM CM CM
+2208 8 2608 2609 2610 # CM CM CM
+2209 9 2609 2610 2611 # CM CM CM
+2210 10 2610 2611 2612 # CM CM CM
+2211 11 2611 2612 2613 # CM CM CT
+2212 1 2614 2615 2616 # HG CM CM
+2213 2 2615 2616 2617 # CM CM CM
+2214 3 2616 2617 2618 # CM CM CM
+2215 4 2617 2618 2619 # CM CM CM
+2216 5 2618 2619 2620 # CM CM CM
+2217 6 2619 2620 2621 # CM CM CM
+2218 7 2620 2621 2622 # CM CM CM
+2219 8 2621 2622 2623 # CM CM CM
+2220 9 2622 2623 2624 # CM CM CM
+2221 10 2623 2624 2625 # CM CM CM
+2222 11 2624 2625 2626 # CM CM CT
+2223 1 2627 2628 2629 # HG CM CM
+2224 2 2628 2629 2630 # CM CM CM
+2225 3 2629 2630 2631 # CM CM CM
+2226 4 2630 2631 2632 # CM CM CM
+2227 5 2631 2632 2633 # CM CM CM
+2228 6 2632 2633 2634 # CM CM CM
+2229 7 2633 2634 2635 # CM CM CM
+2230 8 2634 2635 2636 # CM CM CM
+2231 9 2635 2636 2637 # CM CM CM
+2232 10 2636 2637 2638 # CM CM CM
+2233 11 2637 2638 2639 # CM CM CT
+2234 1 2640 2641 2642 # HG CM CM
+2235 2 2641 2642 2643 # CM CM CM
+2236 3 2642 2643 2644 # CM CM CM
+2237 4 2643 2644 2645 # CM CM CM
+2238 5 2644 2645 2646 # CM CM CM
+2239 6 2645 2646 2647 # CM CM CM
+2240 7 2646 2647 2648 # CM CM CM
+2241 8 2647 2648 2649 # CM CM CM
+2242 9 2648 2649 2650 # CM CM CM
+2243 10 2649 2650 2651 # CM CM CM
+2244 11 2650 2651 2652 # CM CM CT
+2245 1 2653 2654 2655 # HG CM CM
+2246 2 2654 2655 2656 # CM CM CM
+2247 3 2655 2656 2657 # CM CM CM
+2248 4 2656 2657 2658 # CM CM CM
+2249 5 2657 2658 2659 # CM CM CM
+2250 6 2658 2659 2660 # CM CM CM
+2251 7 2659 2660 2661 # CM CM CM
+2252 8 2660 2661 2662 # CM CM CM
+2253 9 2661 2662 2663 # CM CM CM
+2254 10 2662 2663 2664 # CM CM CM
+2255 11 2663 2664 2665 # CM CM CT
+2256 1 2666 2667 2668 # HG CM CM
+2257 2 2667 2668 2669 # CM CM CM
+2258 3 2668 2669 2670 # CM CM CM
+2259 4 2669 2670 2671 # CM CM CM
+2260 5 2670 2671 2672 # CM CM CM
+2261 6 2671 2672 2673 # CM CM CM
+2262 7 2672 2673 2674 # CM CM CM
+2263 8 2673 2674 2675 # CM CM CM
+2264 9 2674 2675 2676 # CM CM CM
+2265 10 2675 2676 2677 # CM CM CM
+2266 11 2676 2677 2678 # CM CM CT
+2267 1 2679 2680 2681 # HG CM CM
+2268 2 2680 2681 2682 # CM CM CM
+2269 3 2681 2682 2683 # CM CM CM
+2270 4 2682 2683 2684 # CM CM CM
+2271 5 2683 2684 2685 # CM CM CM
+2272 6 2684 2685 2686 # CM CM CM
+2273 7 2685 2686 2687 # CM CM CM
+2274 8 2686 2687 2688 # CM CM CM
+2275 9 2687 2688 2689 # CM CM CM
+2276 10 2688 2689 2690 # CM CM CM
+2277 11 2689 2690 2691 # CM CM CT
+2278 1 2692 2693 2694 # HG CM CM
+2279 2 2693 2694 2695 # CM CM CM
+2280 3 2694 2695 2696 # CM CM CM
+2281 4 2695 2696 2697 # CM CM CM
+2282 5 2696 2697 2698 # CM CM CM
+2283 6 2697 2698 2699 # CM CM CM
+2284 7 2698 2699 2700 # CM CM CM
+2285 8 2699 2700 2701 # CM CM CM
+2286 9 2700 2701 2702 # CM CM CM
+2287 10 2701 2702 2703 # CM CM CM
+2288 11 2702 2703 2704 # CM CM CT
+2289 1 2705 2706 2707 # HG CM CM
+2290 2 2706 2707 2708 # CM CM CM
+2291 3 2707 2708 2709 # CM CM CM
+2292 4 2708 2709 2710 # CM CM CM
+2293 5 2709 2710 2711 # CM CM CM
+2294 6 2710 2711 2712 # CM CM CM
+2295 7 2711 2712 2713 # CM CM CM
+2296 8 2712 2713 2714 # CM CM CM
+2297 9 2713 2714 2715 # CM CM CM
+2298 10 2714 2715 2716 # CM CM CM
+2299 11 2715 2716 2717 # CM CM CT
+2300 1 2718 2719 2720 # HG CM CM
+2301 2 2719 2720 2721 # CM CM CM
+2302 3 2720 2721 2722 # CM CM CM
+2303 4 2721 2722 2723 # CM CM CM
+2304 5 2722 2723 2724 # CM CM CM
+2305 6 2723 2724 2725 # CM CM CM
+2306 7 2724 2725 2726 # CM CM CM
+2307 8 2725 2726 2727 # CM CM CM
+2308 9 2726 2727 2728 # CM CM CM
+2309 10 2727 2728 2729 # CM CM CM
+2310 11 2728 2729 2730 # CM CM CT
+2311 1 2731 2732 2733 # HG CM CM
+2312 2 2732 2733 2734 # CM CM CM
+2313 3 2733 2734 2735 # CM CM CM
+2314 4 2734 2735 2736 # CM CM CM
+2315 5 2735 2736 2737 # CM CM CM
+2316 6 2736 2737 2738 # CM CM CM
+2317 7 2737 2738 2739 # CM CM CM
+2318 8 2738 2739 2740 # CM CM CM
+2319 9 2739 2740 2741 # CM CM CM
+2320 10 2740 2741 2742 # CM CM CM
+2321 11 2741 2742 2743 # CM CM CT
+2322 1 2744 2745 2746 # HG CM CM
+2323 2 2745 2746 2747 # CM CM CM
+2324 3 2746 2747 2748 # CM CM CM
+2325 4 2747 2748 2749 # CM CM CM
+2326 5 2748 2749 2750 # CM CM CM
+2327 6 2749 2750 2751 # CM CM CM
+2328 7 2750 2751 2752 # CM CM CM
+2329 8 2751 2752 2753 # CM CM CM
+2330 9 2752 2753 2754 # CM CM CM
+2331 10 2753 2754 2755 # CM CM CM
+2332 11 2754 2755 2756 # CM CM CT
+2333 1 2757 2758 2759 # HG CM CM
+2334 2 2758 2759 2760 # CM CM CM
+2335 3 2759 2760 2761 # CM CM CM
+2336 4 2760 2761 2762 # CM CM CM
+2337 5 2761 2762 2763 # CM CM CM
+2338 6 2762 2763 2764 # CM CM CM
+2339 7 2763 2764 2765 # CM CM CM
+2340 8 2764 2765 2766 # CM CM CM
+2341 9 2765 2766 2767 # CM CM CM
+2342 10 2766 2767 2768 # CM CM CM
+2343 11 2767 2768 2769 # CM CM CT
+2344 1 2770 2771 2772 # HG CM CM
+2345 2 2771 2772 2773 # CM CM CM
+2346 3 2772 2773 2774 # CM CM CM
+2347 4 2773 2774 2775 # CM CM CM
+2348 5 2774 2775 2776 # CM CM CM
+2349 6 2775 2776 2777 # CM CM CM
+2350 7 2776 2777 2778 # CM CM CM
+2351 8 2777 2778 2779 # CM CM CM
+2352 9 2778 2779 2780 # CM CM CM
+2353 10 2779 2780 2781 # CM CM CM
+2354 11 2780 2781 2782 # CM CM CT
+2355 1 2783 2784 2785 # HG CM CM
+2356 2 2784 2785 2786 # CM CM CM
+2357 3 2785 2786 2787 # CM CM CM
+2358 4 2786 2787 2788 # CM CM CM
+2359 5 2787 2788 2789 # CM CM CM
+2360 6 2788 2789 2790 # CM CM CM
+2361 7 2789 2790 2791 # CM CM CM
+2362 8 2790 2791 2792 # CM CM CM
+2363 9 2791 2792 2793 # CM CM CM
+2364 10 2792 2793 2794 # CM CM CM
+2365 11 2793 2794 2795 # CM CM CT
+2366 1 2796 2797 2798 # HG CM CM
+2367 2 2797 2798 2799 # CM CM CM
+2368 3 2798 2799 2800 # CM CM CM
+2369 4 2799 2800 2801 # CM CM CM
+2370 5 2800 2801 2802 # CM CM CM
+2371 6 2801 2802 2803 # CM CM CM
+2372 7 2802 2803 2804 # CM CM CM
+2373 8 2803 2804 2805 # CM CM CM
+2374 9 2804 2805 2806 # CM CM CM
+2375 10 2805 2806 2807 # CM CM CM
+2376 11 2806 2807 2808 # CM CM CT
+2377 1 2809 2810 2811 # HG CM CM
+2378 2 2810 2811 2812 # CM CM CM
+2379 3 2811 2812 2813 # CM CM CM
+2380 4 2812 2813 2814 # CM CM CM
+2381 5 2813 2814 2815 # CM CM CM
+2382 6 2814 2815 2816 # CM CM CM
+2383 7 2815 2816 2817 # CM CM CM
+2384 8 2816 2817 2818 # CM CM CM
+2385 9 2817 2818 2819 # CM CM CM
+2386 10 2818 2819 2820 # CM CM CM
+2387 11 2819 2820 2821 # CM CM CT
+2388 1 2822 2823 2824 # HG CM CM
+2389 2 2823 2824 2825 # CM CM CM
+2390 3 2824 2825 2826 # CM CM CM
+2391 4 2825 2826 2827 # CM CM CM
+2392 5 2826 2827 2828 # CM CM CM
+2393 6 2827 2828 2829 # CM CM CM
+2394 7 2828 2829 2830 # CM CM CM
+2395 8 2829 2830 2831 # CM CM CM
+2396 9 2830 2831 2832 # CM CM CM
+2397 10 2831 2832 2833 # CM CM CM
+2398 11 2832 2833 2834 # CM CM CT
+2399 1 2835 2836 2837 # HG CM CM
+2400 2 2836 2837 2838 # CM CM CM
+2401 3 2837 2838 2839 # CM CM CM
+2402 4 2838 2839 2840 # CM CM CM
+2403 5 2839 2840 2841 # CM CM CM
+2404 6 2840 2841 2842 # CM CM CM
+2405 7 2841 2842 2843 # CM CM CM
+2406 8 2842 2843 2844 # CM CM CM
+2407 9 2843 2844 2845 # CM CM CM
+2408 10 2844 2845 2846 # CM CM CM
+2409 11 2845 2846 2847 # CM CM CT
+2410 1 2848 2849 2850 # HG CM CM
+2411 2 2849 2850 2851 # CM CM CM
+2412 3 2850 2851 2852 # CM CM CM
+2413 4 2851 2852 2853 # CM CM CM
+2414 5 2852 2853 2854 # CM CM CM
+2415 6 2853 2854 2855 # CM CM CM
+2416 7 2854 2855 2856 # CM CM CM
+2417 8 2855 2856 2857 # CM CM CM
+2418 9 2856 2857 2858 # CM CM CM
+2419 10 2857 2858 2859 # CM CM CM
+2420 11 2858 2859 2860 # CM CM CT
+2421 1 2861 2862 2863 # HG CM CM
+2422 2 2862 2863 2864 # CM CM CM
+2423 3 2863 2864 2865 # CM CM CM
+2424 4 2864 2865 2866 # CM CM CM
+2425 5 2865 2866 2867 # CM CM CM
+2426 6 2866 2867 2868 # CM CM CM
+2427 7 2867 2868 2869 # CM CM CM
+2428 8 2868 2869 2870 # CM CM CM
+2429 9 2869 2870 2871 # CM CM CM
+2430 10 2870 2871 2872 # CM CM CM
+2431 11 2871 2872 2873 # CM CM CT
+2432 1 2874 2875 2876 # HG CM CM
+2433 2 2875 2876 2877 # CM CM CM
+2434 3 2876 2877 2878 # CM CM CM
+2435 4 2877 2878 2879 # CM CM CM
+2436 5 2878 2879 2880 # CM CM CM
+2437 6 2879 2880 2881 # CM CM CM
+2438 7 2880 2881 2882 # CM CM CM
+2439 8 2881 2882 2883 # CM CM CM
+2440 9 2882 2883 2884 # CM CM CM
+2441 10 2883 2884 2885 # CM CM CM
+2442 11 2884 2885 2886 # CM CM CT
+2443 1 2887 2888 2889 # HG CM CM
+2444 2 2888 2889 2890 # CM CM CM
+2445 3 2889 2890 2891 # CM CM CM
+2446 4 2890 2891 2892 # CM CM CM
+2447 5 2891 2892 2893 # CM CM CM
+2448 6 2892 2893 2894 # CM CM CM
+2449 7 2893 2894 2895 # CM CM CM
+2450 8 2894 2895 2896 # CM CM CM
+2451 9 2895 2896 2897 # CM CM CM
+2452 10 2896 2897 2898 # CM CM CM
+2453 11 2897 2898 2899 # CM CM CT
+2454 1 2900 2901 2902 # HG CM CM
+2455 2 2901 2902 2903 # CM CM CM
+2456 3 2902 2903 2904 # CM CM CM
+2457 4 2903 2904 2905 # CM CM CM
+2458 5 2904 2905 2906 # CM CM CM
+2459 6 2905 2906 2907 # CM CM CM
+2460 7 2906 2907 2908 # CM CM CM
+2461 8 2907 2908 2909 # CM CM CM
+2462 9 2908 2909 2910 # CM CM CM
+2463 10 2909 2910 2911 # CM CM CM
+2464 11 2910 2911 2912 # CM CM CT
+2465 1 2913 2914 2915 # HG CM CM
+2466 2 2914 2915 2916 # CM CM CM
+2467 3 2915 2916 2917 # CM CM CM
+2468 4 2916 2917 2918 # CM CM CM
+2469 5 2917 2918 2919 # CM CM CM
+2470 6 2918 2919 2920 # CM CM CM
+2471 7 2919 2920 2921 # CM CM CM
+2472 8 2920 2921 2922 # CM CM CM
+2473 9 2921 2922 2923 # CM CM CM
+2474 10 2922 2923 2924 # CM CM CM
+2475 11 2923 2924 2925 # CM CM CT
+2476 1 2926 2927 2928 # HG CM CM
+2477 2 2927 2928 2929 # CM CM CM
+2478 3 2928 2929 2930 # CM CM CM
+2479 4 2929 2930 2931 # CM CM CM
+2480 5 2930 2931 2932 # CM CM CM
+2481 6 2931 2932 2933 # CM CM CM
+2482 7 2932 2933 2934 # CM CM CM
+2483 8 2933 2934 2935 # CM CM CM
+2484 9 2934 2935 2936 # CM CM CM
+2485 10 2935 2936 2937 # CM CM CM
+2486 11 2936 2937 2938 # CM CM CT
+2487 1 2939 2940 2941 # HG CM CM
+2488 2 2940 2941 2942 # CM CM CM
+2489 3 2941 2942 2943 # CM CM CM
+2490 4 2942 2943 2944 # CM CM CM
+2491 5 2943 2944 2945 # CM CM CM
+2492 6 2944 2945 2946 # CM CM CM
+2493 7 2945 2946 2947 # CM CM CM
+2494 8 2946 2947 2948 # CM CM CM
+2495 9 2947 2948 2949 # CM CM CM
+2496 10 2948 2949 2950 # CM CM CM
+2497 11 2949 2950 2951 # CM CM CT
+2498 1 2952 2953 2954 # HG CM CM
+2499 2 2953 2954 2955 # CM CM CM
+2500 3 2954 2955 2956 # CM CM CM
+2501 4 2955 2956 2957 # CM CM CM
+2502 5 2956 2957 2958 # CM CM CM
+2503 6 2957 2958 2959 # CM CM CM
+2504 7 2958 2959 2960 # CM CM CM
+2505 8 2959 2960 2961 # CM CM CM
+2506 9 2960 2961 2962 # CM CM CM
+2507 10 2961 2962 2963 # CM CM CM
+2508 11 2962 2963 2964 # CM CM CT
+2509 1 2965 2966 2967 # HG CM CM
+2510 2 2966 2967 2968 # CM CM CM
+2511 3 2967 2968 2969 # CM CM CM
+2512 4 2968 2969 2970 # CM CM CM
+2513 5 2969 2970 2971 # CM CM CM
+2514 6 2970 2971 2972 # CM CM CM
+2515 7 2971 2972 2973 # CM CM CM
+2516 8 2972 2973 2974 # CM CM CM
+2517 9 2973 2974 2975 # CM CM CM
+2518 10 2974 2975 2976 # CM CM CM
+2519 11 2975 2976 2977 # CM CM CT
+2520 1 2978 2979 2980 # HG CM CM
+2521 2 2979 2980 2981 # CM CM CM
+2522 3 2980 2981 2982 # CM CM CM
+2523 4 2981 2982 2983 # CM CM CM
+2524 5 2982 2983 2984 # CM CM CM
+2525 6 2983 2984 2985 # CM CM CM
+2526 7 2984 2985 2986 # CM CM CM
+2527 8 2985 2986 2987 # CM CM CM
+2528 9 2986 2987 2988 # CM CM CM
+2529 10 2987 2988 2989 # CM CM CM
+2530 11 2988 2989 2990 # CM CM CT
+2531 1 2991 2992 2993 # HG CM CM
+2532 2 2992 2993 2994 # CM CM CM
+2533 3 2993 2994 2995 # CM CM CM
+2534 4 2994 2995 2996 # CM CM CM
+2535 5 2995 2996 2997 # CM CM CM
+2536 6 2996 2997 2998 # CM CM CM
+2537 7 2997 2998 2999 # CM CM CM
+2538 8 2998 2999 3000 # CM CM CM
+2539 9 2999 3000 3001 # CM CM CM
+2540 10 3000 3001 3002 # CM CM CM
+2541 11 3001 3002 3003 # CM CM CT
+2542 1 3004 3005 3006 # HG CM CM
+2543 2 3005 3006 3007 # CM CM CM
+2544 3 3006 3007 3008 # CM CM CM
+2545 4 3007 3008 3009 # CM CM CM
+2546 5 3008 3009 3010 # CM CM CM
+2547 6 3009 3010 3011 # CM CM CM
+2548 7 3010 3011 3012 # CM CM CM
+2549 8 3011 3012 3013 # CM CM CM
+2550 9 3012 3013 3014 # CM CM CM
+2551 10 3013 3014 3015 # CM CM CM
+2552 11 3014 3015 3016 # CM CM CT
+2553 1 3017 3018 3019 # HG CM CM
+2554 2 3018 3019 3020 # CM CM CM
+2555 3 3019 3020 3021 # CM CM CM
+2556 4 3020 3021 3022 # CM CM CM
+2557 5 3021 3022 3023 # CM CM CM
+2558 6 3022 3023 3024 # CM CM CM
+2559 7 3023 3024 3025 # CM CM CM
+2560 8 3024 3025 3026 # CM CM CM
+2561 9 3025 3026 3027 # CM CM CM
+2562 10 3026 3027 3028 # CM CM CM
+2563 11 3027 3028 3029 # CM CM CT
+2564 1 3030 3031 3032 # HG CM CM
+2565 2 3031 3032 3033 # CM CM CM
+2566 3 3032 3033 3034 # CM CM CM
+2567 4 3033 3034 3035 # CM CM CM
+2568 5 3034 3035 3036 # CM CM CM
+2569 6 3035 3036 3037 # CM CM CM
+2570 7 3036 3037 3038 # CM CM CM
+2571 8 3037 3038 3039 # CM CM CM
+2572 9 3038 3039 3040 # CM CM CM
+2573 10 3039 3040 3041 # CM CM CM
+2574 11 3040 3041 3042 # CM CM CT
+2575 1 3043 3044 3045 # HG CM CM
+2576 2 3044 3045 3046 # CM CM CM
+2577 3 3045 3046 3047 # CM CM CM
+2578 4 3046 3047 3048 # CM CM CM
+2579 5 3047 3048 3049 # CM CM CM
+2580 6 3048 3049 3050 # CM CM CM
+2581 7 3049 3050 3051 # CM CM CM
+2582 8 3050 3051 3052 # CM CM CM
+2583 9 3051 3052 3053 # CM CM CM
+2584 10 3052 3053 3054 # CM CM CM
+2585 11 3053 3054 3055 # CM CM CT
+2586 1 3056 3057 3058 # HG CM CM
+2587 2 3057 3058 3059 # CM CM CM
+2588 3 3058 3059 3060 # CM CM CM
+2589 4 3059 3060 3061 # CM CM CM
+2590 5 3060 3061 3062 # CM CM CM
+2591 6 3061 3062 3063 # CM CM CM
+2592 7 3062 3063 3064 # CM CM CM
+2593 8 3063 3064 3065 # CM CM CM
+2594 9 3064 3065 3066 # CM CM CM
+2595 10 3065 3066 3067 # CM CM CM
+2596 11 3066 3067 3068 # CM CM CT
+2597 1 3069 3070 3071 # HG CM CM
+2598 2 3070 3071 3072 # CM CM CM
+2599 3 3071 3072 3073 # CM CM CM
+2600 4 3072 3073 3074 # CM CM CM
+2601 5 3073 3074 3075 # CM CM CM
+2602 6 3074 3075 3076 # CM CM CM
+2603 7 3075 3076 3077 # CM CM CM
+2604 8 3076 3077 3078 # CM CM CM
+2605 9 3077 3078 3079 # CM CM CM
+2606 10 3078 3079 3080 # CM CM CM
+2607 11 3079 3080 3081 # CM CM CT
+2608 1 3082 3083 3084 # HG CM CM
+2609 2 3083 3084 3085 # CM CM CM
+2610 3 3084 3085 3086 # CM CM CM
+2611 4 3085 3086 3087 # CM CM CM
+2612 5 3086 3087 3088 # CM CM CM
+2613 6 3087 3088 3089 # CM CM CM
+2614 7 3088 3089 3090 # CM CM CM
+2615 8 3089 3090 3091 # CM CM CM
+2616 9 3090 3091 3092 # CM CM CM
+2617 10 3091 3092 3093 # CM CM CM
+2618 11 3092 3093 3094 # CM CM CT
+2619 1 3095 3096 3097 # HG CM CM
+2620 2 3096 3097 3098 # CM CM CM
+2621 3 3097 3098 3099 # CM CM CM
+2622 4 3098 3099 3100 # CM CM CM
+2623 5 3099 3100 3101 # CM CM CM
+2624 6 3100 3101 3102 # CM CM CM
+2625 7 3101 3102 3103 # CM CM CM
+2626 8 3102 3103 3104 # CM CM CM
+2627 9 3103 3104 3105 # CM CM CM
+2628 10 3104 3105 3106 # CM CM CM
+2629 11 3105 3106 3107 # CM CM CT
+2630 1 3108 3109 3110 # HG CM CM
+2631 2 3109 3110 3111 # CM CM CM
+2632 3 3110 3111 3112 # CM CM CM
+2633 4 3111 3112 3113 # CM CM CM
+2634 5 3112 3113 3114 # CM CM CM
+2635 6 3113 3114 3115 # CM CM CM
+2636 7 3114 3115 3116 # CM CM CM
+2637 8 3115 3116 3117 # CM CM CM
+2638 9 3116 3117 3118 # CM CM CM
+2639 10 3117 3118 3119 # CM CM CM
+2640 11 3118 3119 3120 # CM CM CT
+2641 1 3121 3122 3123 # HG CM CM
+2642 2 3122 3123 3124 # CM CM CM
+2643 3 3123 3124 3125 # CM CM CM
+2644 4 3124 3125 3126 # CM CM CM
+2645 5 3125 3126 3127 # CM CM CM
+2646 6 3126 3127 3128 # CM CM CM
+2647 7 3127 3128 3129 # CM CM CM
+2648 8 3128 3129 3130 # CM CM CM
+2649 9 3129 3130 3131 # CM CM CM
+2650 10 3130 3131 3132 # CM CM CM
+2651 11 3131 3132 3133 # CM CM CT
+2652 1 3134 3135 3136 # HG CM CM
+2653 2 3135 3136 3137 # CM CM CM
+2654 3 3136 3137 3138 # CM CM CM
+2655 4 3137 3138 3139 # CM CM CM
+2656 5 3138 3139 3140 # CM CM CM
+2657 6 3139 3140 3141 # CM CM CM
+2658 7 3140 3141 3142 # CM CM CM
+2659 8 3141 3142 3143 # CM CM CM
+2660 9 3142 3143 3144 # CM CM CM
+2661 10 3143 3144 3145 # CM CM CM
+2662 11 3144 3145 3146 # CM CM CT
+2663 1 3147 3148 3149 # HG CM CM
+2664 2 3148 3149 3150 # CM CM CM
+2665 3 3149 3150 3151 # CM CM CM
+2666 4 3150 3151 3152 # CM CM CM
+2667 5 3151 3152 3153 # CM CM CM
+2668 6 3152 3153 3154 # CM CM CM
+2669 7 3153 3154 3155 # CM CM CM
+2670 8 3154 3155 3156 # CM CM CM
+2671 9 3155 3156 3157 # CM CM CM
+2672 10 3156 3157 3158 # CM CM CM
+2673 11 3157 3158 3159 # CM CM CT
+2674 1 3160 3161 3162 # HG CM CM
+2675 2 3161 3162 3163 # CM CM CM
+2676 3 3162 3163 3164 # CM CM CM
+2677 4 3163 3164 3165 # CM CM CM
+2678 5 3164 3165 3166 # CM CM CM
+2679 6 3165 3166 3167 # CM CM CM
+2680 7 3166 3167 3168 # CM CM CM
+2681 8 3167 3168 3169 # CM CM CM
+2682 9 3168 3169 3170 # CM CM CM
+2683 10 3169 3170 3171 # CM CM CM
+2684 11 3170 3171 3172 # CM CM CT
+2685 1 3173 3174 3175 # HG CM CM
+2686 2 3174 3175 3176 # CM CM CM
+2687 3 3175 3176 3177 # CM CM CM
+2688 4 3176 3177 3178 # CM CM CM
+2689 5 3177 3178 3179 # CM CM CM
+2690 6 3178 3179 3180 # CM CM CM
+2691 7 3179 3180 3181 # CM CM CM
+2692 8 3180 3181 3182 # CM CM CM
+2693 9 3181 3182 3183 # CM CM CM
+2694 10 3182 3183 3184 # CM CM CM
+2695 11 3183 3184 3185 # CM CM CT
+2696 1 3186 3187 3188 # HG CM CM
+2697 2 3187 3188 3189 # CM CM CM
+2698 3 3188 3189 3190 # CM CM CM
+2699 4 3189 3190 3191 # CM CM CM
+2700 5 3190 3191 3192 # CM CM CM
+2701 6 3191 3192 3193 # CM CM CM
+2702 7 3192 3193 3194 # CM CM CM
+2703 8 3193 3194 3195 # CM CM CM
+2704 9 3194 3195 3196 # CM CM CM
+2705 10 3195 3196 3197 # CM CM CM
+2706 11 3196 3197 3198 # CM CM CT
+2707 1 3199 3200 3201 # HG CM CM
+2708 2 3200 3201 3202 # CM CM CM
+2709 3 3201 3202 3203 # CM CM CM
+2710 4 3202 3203 3204 # CM CM CM
+2711 5 3203 3204 3205 # CM CM CM
+2712 6 3204 3205 3206 # CM CM CM
+2713 7 3205 3206 3207 # CM CM CM
+2714 8 3206 3207 3208 # CM CM CM
+2715 9 3207 3208 3209 # CM CM CM
+2716 10 3208 3209 3210 # CM CM CM
+2717 11 3209 3210 3211 # CM CM CT
+2718 1 3212 3213 3214 # HG CM CM
+2719 2 3213 3214 3215 # CM CM CM
+2720 3 3214 3215 3216 # CM CM CM
+2721 4 3215 3216 3217 # CM CM CM
+2722 5 3216 3217 3218 # CM CM CM
+2723 6 3217 3218 3219 # CM CM CM
+2724 7 3218 3219 3220 # CM CM CM
+2725 8 3219 3220 3221 # CM CM CM
+2726 9 3220 3221 3222 # CM CM CM
+2727 10 3221 3222 3223 # CM CM CM
+2728 11 3222 3223 3224 # CM CM CT
+2729 1 3225 3226 3227 # HG CM CM
+2730 2 3226 3227 3228 # CM CM CM
+2731 3 3227 3228 3229 # CM CM CM
+2732 4 3228 3229 3230 # CM CM CM
+2733 5 3229 3230 3231 # CM CM CM
+2734 6 3230 3231 3232 # CM CM CM
+2735 7 3231 3232 3233 # CM CM CM
+2736 8 3232 3233 3234 # CM CM CM
+2737 9 3233 3234 3235 # CM CM CM
+2738 10 3234 3235 3236 # CM CM CM
+2739 11 3235 3236 3237 # CM CM CT
+2740 1 3238 3239 3240 # HG CM CM
+2741 2 3239 3240 3241 # CM CM CM
+2742 3 3240 3241 3242 # CM CM CM
+2743 4 3241 3242 3243 # CM CM CM
+2744 5 3242 3243 3244 # CM CM CM
+2745 6 3243 3244 3245 # CM CM CM
+2746 7 3244 3245 3246 # CM CM CM
+2747 8 3245 3246 3247 # CM CM CM
+2748 9 3246 3247 3248 # CM CM CM
+2749 10 3247 3248 3249 # CM CM CM
+2750 11 3248 3249 3250 # CM CM CT
+2751 1 3251 3252 3253 # HG CM CM
+2752 2 3252 3253 3254 # CM CM CM
+2753 3 3253 3254 3255 # CM CM CM
+2754 4 3254 3255 3256 # CM CM CM
+2755 5 3255 3256 3257 # CM CM CM
+2756 6 3256 3257 3258 # CM CM CM
+2757 7 3257 3258 3259 # CM CM CM
+2758 8 3258 3259 3260 # CM CM CM
+2759 9 3259 3260 3261 # CM CM CM
+2760 10 3260 3261 3262 # CM CM CM
+2761 11 3261 3262 3263 # CM CM CT
+2762 1 3264 3265 3266 # HG CM CM
+2763 2 3265 3266 3267 # CM CM CM
+2764 3 3266 3267 3268 # CM CM CM
+2765 4 3267 3268 3269 # CM CM CM
+2766 5 3268 3269 3270 # CM CM CM
+2767 6 3269 3270 3271 # CM CM CM
+2768 7 3270 3271 3272 # CM CM CM
+2769 8 3271 3272 3273 # CM CM CM
+2770 9 3272 3273 3274 # CM CM CM
+2771 10 3273 3274 3275 # CM CM CM
+2772 11 3274 3275 3276 # CM CM CT
+2773 1 3277 3278 3279 # HG CM CM
+2774 2 3278 3279 3280 # CM CM CM
+2775 3 3279 3280 3281 # CM CM CM
+2776 4 3280 3281 3282 # CM CM CM
+2777 5 3281 3282 3283 # CM CM CM
+2778 6 3282 3283 3284 # CM CM CM
+2779 7 3283 3284 3285 # CM CM CM
+2780 8 3284 3285 3286 # CM CM CM
+2781 9 3285 3286 3287 # CM CM CM
+2782 10 3286 3287 3288 # CM CM CM
+2783 11 3287 3288 3289 # CM CM CT
+2784 1 3290 3291 3292 # HG CM CM
+2785 2 3291 3292 3293 # CM CM CM
+2786 3 3292 3293 3294 # CM CM CM
+2787 4 3293 3294 3295 # CM CM CM
+2788 5 3294 3295 3296 # CM CM CM
+2789 6 3295 3296 3297 # CM CM CM
+2790 7 3296 3297 3298 # CM CM CM
+2791 8 3297 3298 3299 # CM CM CM
+2792 9 3298 3299 3300 # CM CM CM
+2793 10 3299 3300 3301 # CM CM CM
+2794 11 3300 3301 3302 # CM CM CT
+2795 1 3303 3304 3305 # HG CM CM
+2796 2 3304 3305 3306 # CM CM CM
+2797 3 3305 3306 3307 # CM CM CM
+2798 4 3306 3307 3308 # CM CM CM
+2799 5 3307 3308 3309 # CM CM CM
+2800 6 3308 3309 3310 # CM CM CM
+2801 7 3309 3310 3311 # CM CM CM
+2802 8 3310 3311 3312 # CM CM CM
+2803 9 3311 3312 3313 # CM CM CM
+2804 10 3312 3313 3314 # CM CM CM
+2805 11 3313 3314 3315 # CM CM CT
+2806 1 3316 3317 3318 # HG CM CM
+2807 2 3317 3318 3319 # CM CM CM
+2808 3 3318 3319 3320 # CM CM CM
+2809 4 3319 3320 3321 # CM CM CM
+2810 5 3320 3321 3322 # CM CM CM
+2811 6 3321 3322 3323 # CM CM CM
+2812 7 3322 3323 3324 # CM CM CM
+2813 8 3323 3324 3325 # CM CM CM
+2814 9 3324 3325 3326 # CM CM CM
+2815 10 3325 3326 3327 # CM CM CM
+2816 11 3326 3327 3328 # CM CM CT
+2817 1 3329 3330 3331 # HG CM CM
+2818 2 3330 3331 3332 # CM CM CM
+2819 3 3331 3332 3333 # CM CM CM
+2820 4 3332 3333 3334 # CM CM CM
+2821 5 3333 3334 3335 # CM CM CM
+2822 6 3334 3335 3336 # CM CM CM
+2823 7 3335 3336 3337 # CM CM CM
+2824 8 3336 3337 3338 # CM CM CM
+2825 9 3337 3338 3339 # CM CM CM
+2826 10 3338 3339 3340 # CM CM CM
+2827 11 3339 3340 3341 # CM CM CT
+2828 1 3342 3343 3344 # HG CM CM
+2829 2 3343 3344 3345 # CM CM CM
+2830 3 3344 3345 3346 # CM CM CM
+2831 4 3345 3346 3347 # CM CM CM
+2832 5 3346 3347 3348 # CM CM CM
+2833 6 3347 3348 3349 # CM CM CM
+2834 7 3348 3349 3350 # CM CM CM
+2835 8 3349 3350 3351 # CM CM CM
+2836 9 3350 3351 3352 # CM CM CM
+2837 10 3351 3352 3353 # CM CM CM
+2838 11 3352 3353 3354 # CM CM CT
+2839 1 3355 3356 3357 # HG CM CM
+2840 2 3356 3357 3358 # CM CM CM
+2841 3 3357 3358 3359 # CM CM CM
+2842 4 3358 3359 3360 # CM CM CM
+2843 5 3359 3360 3361 # CM CM CM
+2844 6 3360 3361 3362 # CM CM CM
+2845 7 3361 3362 3363 # CM CM CM
+2846 8 3362 3363 3364 # CM CM CM
+2847 9 3363 3364 3365 # CM CM CM
+2848 10 3364 3365 3366 # CM CM CM
+2849 11 3365 3366 3367 # CM CM CT
+2850 1 3368 3369 3370 # HG CM CM
+2851 2 3369 3370 3371 # CM CM CM
+2852 3 3370 3371 3372 # CM CM CM
+2853 4 3371 3372 3373 # CM CM CM
+2854 5 3372 3373 3374 # CM CM CM
+2855 6 3373 3374 3375 # CM CM CM
+2856 7 3374 3375 3376 # CM CM CM
+2857 8 3375 3376 3377 # CM CM CM
+2858 9 3376 3377 3378 # CM CM CM
+2859 10 3377 3378 3379 # CM CM CM
+2860 11 3378 3379 3380 # CM CM CT
+2861 1 3381 3382 3383 # HG CM CM
+2862 2 3382 3383 3384 # CM CM CM
+2863 3 3383 3384 3385 # CM CM CM
+2864 4 3384 3385 3386 # CM CM CM
+2865 5 3385 3386 3387 # CM CM CM
+2866 6 3386 3387 3388 # CM CM CM
+2867 7 3387 3388 3389 # CM CM CM
+2868 8 3388 3389 3390 # CM CM CM
+2869 9 3389 3390 3391 # CM CM CM
+2870 10 3390 3391 3392 # CM CM CM
+2871 11 3391 3392 3393 # CM CM CT
+2872 1 3394 3395 3396 # HG CM CM
+2873 2 3395 3396 3397 # CM CM CM
+2874 3 3396 3397 3398 # CM CM CM
+2875 4 3397 3398 3399 # CM CM CM
+2876 5 3398 3399 3400 # CM CM CM
+2877 6 3399 3400 3401 # CM CM CM
+2878 7 3400 3401 3402 # CM CM CM
+2879 8 3401 3402 3403 # CM CM CM
+2880 9 3402 3403 3404 # CM CM CM
+2881 10 3403 3404 3405 # CM CM CM
+2882 11 3404 3405 3406 # CM CM CT
+2883 1 3407 3408 3409 # HG CM CM
+2884 2 3408 3409 3410 # CM CM CM
+2885 3 3409 3410 3411 # CM CM CM
+2886 4 3410 3411 3412 # CM CM CM
+2887 5 3411 3412 3413 # CM CM CM
+2888 6 3412 3413 3414 # CM CM CM
+2889 7 3413 3414 3415 # CM CM CM
+2890 8 3414 3415 3416 # CM CM CM
+2891 9 3415 3416 3417 # CM CM CM
+2892 10 3416 3417 3418 # CM CM CM
+2893 11 3417 3418 3419 # CM CM CT
+2894 1 3420 3421 3422 # HG CM CM
+2895 2 3421 3422 3423 # CM CM CM
+2896 3 3422 3423 3424 # CM CM CM
+2897 4 3423 3424 3425 # CM CM CM
+2898 5 3424 3425 3426 # CM CM CM
+2899 6 3425 3426 3427 # CM CM CM
+2900 7 3426 3427 3428 # CM CM CM
+2901 8 3427 3428 3429 # CM CM CM
+2902 9 3428 3429 3430 # CM CM CM
+2903 10 3429 3430 3431 # CM CM CM
+2904 11 3430 3431 3432 # CM CM CT
+2905 1 3433 3434 3435 # HG CM CM
+2906 2 3434 3435 3436 # CM CM CM
+2907 3 3435 3436 3437 # CM CM CM
+2908 4 3436 3437 3438 # CM CM CM
+2909 5 3437 3438 3439 # CM CM CM
+2910 6 3438 3439 3440 # CM CM CM
+2911 7 3439 3440 3441 # CM CM CM
+2912 8 3440 3441 3442 # CM CM CM
+2913 9 3441 3442 3443 # CM CM CM
+2914 10 3442 3443 3444 # CM CM CM
+2915 11 3443 3444 3445 # CM CM CT
+2916 1 3446 3447 3448 # HG CM CM
+2917 2 3447 3448 3449 # CM CM CM
+2918 3 3448 3449 3450 # CM CM CM
+2919 4 3449 3450 3451 # CM CM CM
+2920 5 3450 3451 3452 # CM CM CM
+2921 6 3451 3452 3453 # CM CM CM
+2922 7 3452 3453 3454 # CM CM CM
+2923 8 3453 3454 3455 # CM CM CM
+2924 9 3454 3455 3456 # CM CM CM
+2925 10 3455 3456 3457 # CM CM CM
+2926 11 3456 3457 3458 # CM CM CT
+2927 1 3459 3460 3461 # HG CM CM
+2928 2 3460 3461 3462 # CM CM CM
+2929 3 3461 3462 3463 # CM CM CM
+2930 4 3462 3463 3464 # CM CM CM
+2931 5 3463 3464 3465 # CM CM CM
+2932 6 3464 3465 3466 # CM CM CM
+2933 7 3465 3466 3467 # CM CM CM
+2934 8 3466 3467 3468 # CM CM CM
+2935 9 3467 3468 3469 # CM CM CM
+2936 10 3468 3469 3470 # CM CM CM
+2937 11 3469 3470 3471 # CM CM CT
+2938 1 3472 3473 3474 # HG CM CM
+2939 2 3473 3474 3475 # CM CM CM
+2940 3 3474 3475 3476 # CM CM CM
+2941 4 3475 3476 3477 # CM CM CM
+2942 5 3476 3477 3478 # CM CM CM
+2943 6 3477 3478 3479 # CM CM CM
+2944 7 3478 3479 3480 # CM CM CM
+2945 8 3479 3480 3481 # CM CM CM
+2946 9 3480 3481 3482 # CM CM CM
+2947 10 3481 3482 3483 # CM CM CM
+2948 11 3482 3483 3484 # CM CM CT
+2949 1 3485 3486 3487 # HG CM CM
+2950 2 3486 3487 3488 # CM CM CM
+2951 3 3487 3488 3489 # CM CM CM
+2952 4 3488 3489 3490 # CM CM CM
+2953 5 3489 3490 3491 # CM CM CM
+2954 6 3490 3491 3492 # CM CM CM
+2955 7 3491 3492 3493 # CM CM CM
+2956 8 3492 3493 3494 # CM CM CM
+2957 9 3493 3494 3495 # CM CM CM
+2958 10 3494 3495 3496 # CM CM CM
+2959 11 3495 3496 3497 # CM CM CT
+2960 1 3498 3499 3500 # HG CM CM
+2961 2 3499 3500 3501 # CM CM CM
+2962 3 3500 3501 3502 # CM CM CM
+2963 4 3501 3502 3503 # CM CM CM
+2964 5 3502 3503 3504 # CM CM CM
+2965 6 3503 3504 3505 # CM CM CM
+2966 7 3504 3505 3506 # CM CM CM
+2967 8 3505 3506 3507 # CM CM CM
+2968 9 3506 3507 3508 # CM CM CM
+2969 10 3507 3508 3509 # CM CM CM
+2970 11 3508 3509 3510 # CM CM CT
+2971 1 3511 3512 3513 # HG CM CM
+2972 2 3512 3513 3514 # CM CM CM
+2973 3 3513 3514 3515 # CM CM CM
+2974 4 3514 3515 3516 # CM CM CM
+2975 5 3515 3516 3517 # CM CM CM
+2976 6 3516 3517 3518 # CM CM CM
+2977 7 3517 3518 3519 # CM CM CM
+2978 8 3518 3519 3520 # CM CM CM
+2979 9 3519 3520 3521 # CM CM CM
+2980 10 3520 3521 3522 # CM CM CM
+2981 11 3521 3522 3523 # CM CM CT
+2982 1 3524 3525 3526 # HG CM CM
+2983 2 3525 3526 3527 # CM CM CM
+2984 3 3526 3527 3528 # CM CM CM
+2985 4 3527 3528 3529 # CM CM CM
+2986 5 3528 3529 3530 # CM CM CM
+2987 6 3529 3530 3531 # CM CM CM
+2988 7 3530 3531 3532 # CM CM CM
+2989 8 3531 3532 3533 # CM CM CM
+2990 9 3532 3533 3534 # CM CM CM
+2991 10 3533 3534 3535 # CM CM CM
+2992 11 3534 3535 3536 # CM CM CT
+2993 1 3537 3538 3539 # HG CM CM
+2994 2 3538 3539 3540 # CM CM CM
+2995 3 3539 3540 3541 # CM CM CM
+2996 4 3540 3541 3542 # CM CM CM
+2997 5 3541 3542 3543 # CM CM CM
+2998 6 3542 3543 3544 # CM CM CM
+2999 7 3543 3544 3545 # CM CM CM
+3000 8 3544 3545 3546 # CM CM CM
+3001 9 3545 3546 3547 # CM CM CM
+3002 10 3546 3547 3548 # CM CM CM
+3003 11 3547 3548 3549 # CM CM CT
+3004 1 3550 3551 3552 # HG CM CM
+3005 2 3551 3552 3553 # CM CM CM
+3006 3 3552 3553 3554 # CM CM CM
+3007 4 3553 3554 3555 # CM CM CM
+3008 5 3554 3555 3556 # CM CM CM
+3009 6 3555 3556 3557 # CM CM CM
+3010 7 3556 3557 3558 # CM CM CM
+3011 8 3557 3558 3559 # CM CM CM
+3012 9 3558 3559 3560 # CM CM CM
+3013 10 3559 3560 3561 # CM CM CM
+3014 11 3560 3561 3562 # CM CM CT
+3015 1 3563 3564 3565 # HG CM CM
+3016 2 3564 3565 3566 # CM CM CM
+3017 3 3565 3566 3567 # CM CM CM
+3018 4 3566 3567 3568 # CM CM CM
+3019 5 3567 3568 3569 # CM CM CM
+3020 6 3568 3569 3570 # CM CM CM
+3021 7 3569 3570 3571 # CM CM CM
+3022 8 3570 3571 3572 # CM CM CM
+3023 9 3571 3572 3573 # CM CM CM
+3024 10 3572 3573 3574 # CM CM CM
+3025 11 3573 3574 3575 # CM CM CT
+3026 1 3576 3577 3578 # HG CM CM
+3027 2 3577 3578 3579 # CM CM CM
+3028 3 3578 3579 3580 # CM CM CM
+3029 4 3579 3580 3581 # CM CM CM
+3030 5 3580 3581 3582 # CM CM CM
+3031 6 3581 3582 3583 # CM CM CM
+3032 7 3582 3583 3584 # CM CM CM
+3033 8 3583 3584 3585 # CM CM CM
+3034 9 3584 3585 3586 # CM CM CM
+3035 10 3585 3586 3587 # CM CM CM
+3036 11 3586 3587 3588 # CM CM CT
+3037 1 3589 3590 3591 # HG CM CM
+3038 2 3590 3591 3592 # CM CM CM
+3039 3 3591 3592 3593 # CM CM CM
+3040 4 3592 3593 3594 # CM CM CM
+3041 5 3593 3594 3595 # CM CM CM
+3042 6 3594 3595 3596 # CM CM CM
+3043 7 3595 3596 3597 # CM CM CM
+3044 8 3596 3597 3598 # CM CM CM
+3045 9 3597 3598 3599 # CM CM CM
+3046 10 3598 3599 3600 # CM CM CM
+3047 11 3599 3600 3601 # CM CM CT
+3048 1 3602 3603 3604 # HG CM CM
+3049 2 3603 3604 3605 # CM CM CM
+3050 3 3604 3605 3606 # CM CM CM
+3051 4 3605 3606 3607 # CM CM CM
+3052 5 3606 3607 3608 # CM CM CM
+3053 6 3607 3608 3609 # CM CM CM
+3054 7 3608 3609 3610 # CM CM CM
+3055 8 3609 3610 3611 # CM CM CM
+3056 9 3610 3611 3612 # CM CM CM
+3057 10 3611 3612 3613 # CM CM CM
+3058 11 3612 3613 3614 # CM CM CT
+3059 1 3615 3616 3617 # HG CM CM
+3060 2 3616 3617 3618 # CM CM CM
+3061 3 3617 3618 3619 # CM CM CM
+3062 4 3618 3619 3620 # CM CM CM
+3063 5 3619 3620 3621 # CM CM CM
+3064 6 3620 3621 3622 # CM CM CM
+3065 7 3621 3622 3623 # CM CM CM
+3066 8 3622 3623 3624 # CM CM CM
+3067 9 3623 3624 3625 # CM CM CM
+3068 10 3624 3625 3626 # CM CM CM
+3069 11 3625 3626 3627 # CM CM CT
+3070 1 3628 3629 3630 # HG CM CM
+3071 2 3629 3630 3631 # CM CM CM
+3072 3 3630 3631 3632 # CM CM CM
+3073 4 3631 3632 3633 # CM CM CM
+3074 5 3632 3633 3634 # CM CM CM
+3075 6 3633 3634 3635 # CM CM CM
+3076 7 3634 3635 3636 # CM CM CM
+3077 8 3635 3636 3637 # CM CM CM
+3078 9 3636 3637 3638 # CM CM CM
+3079 10 3637 3638 3639 # CM CM CM
+3080 11 3638 3639 3640 # CM CM CT
+3081 1 3641 3642 3643 # HG CM CM
+3082 2 3642 3643 3644 # CM CM CM
+3083 3 3643 3644 3645 # CM CM CM
+3084 4 3644 3645 3646 # CM CM CM
+3085 5 3645 3646 3647 # CM CM CM
+3086 6 3646 3647 3648 # CM CM CM
+3087 7 3647 3648 3649 # CM CM CM
+3088 8 3648 3649 3650 # CM CM CM
+3089 9 3649 3650 3651 # CM CM CM
+3090 10 3650 3651 3652 # CM CM CM
+3091 11 3651 3652 3653 # CM CM CT
+3092 1 3654 3655 3656 # HG CM CM
+3093 2 3655 3656 3657 # CM CM CM
+3094 3 3656 3657 3658 # CM CM CM
+3095 4 3657 3658 3659 # CM CM CM
+3096 5 3658 3659 3660 # CM CM CM
+3097 6 3659 3660 3661 # CM CM CM
+3098 7 3660 3661 3662 # CM CM CM
+3099 8 3661 3662 3663 # CM CM CM
+3100 9 3662 3663 3664 # CM CM CM
+3101 10 3663 3664 3665 # CM CM CM
+3102 11 3664 3665 3666 # CM CM CT
+3103 1 3667 3668 3669 # HG CM CM
+3104 2 3668 3669 3670 # CM CM CM
+3105 3 3669 3670 3671 # CM CM CM
+3106 4 3670 3671 3672 # CM CM CM
+3107 5 3671 3672 3673 # CM CM CM
+3108 6 3672 3673 3674 # CM CM CM
+3109 7 3673 3674 3675 # CM CM CM
+3110 8 3674 3675 3676 # CM CM CM
+3111 9 3675 3676 3677 # CM CM CM
+3112 10 3676 3677 3678 # CM CM CM
+3113 11 3677 3678 3679 # CM CM CT
+3114 1 3680 3681 3682 # HG CM CM
+3115 2 3681 3682 3683 # CM CM CM
+3116 3 3682 3683 3684 # CM CM CM
+3117 4 3683 3684 3685 # CM CM CM
+3118 5 3684 3685 3686 # CM CM CM
+3119 6 3685 3686 3687 # CM CM CM
+3120 7 3686 3687 3688 # CM CM CM
+3121 8 3687 3688 3689 # CM CM CM
+3122 9 3688 3689 3690 # CM CM CM
+3123 10 3689 3690 3691 # CM CM CM
+3124 11 3690 3691 3692 # CM CM CT
+3125 1 3693 3694 3695 # HG CM CM
+3126 2 3694 3695 3696 # CM CM CM
+3127 3 3695 3696 3697 # CM CM CM
+3128 4 3696 3697 3698 # CM CM CM
+3129 5 3697 3698 3699 # CM CM CM
+3130 6 3698 3699 3700 # CM CM CM
+3131 7 3699 3700 3701 # CM CM CM
+3132 8 3700 3701 3702 # CM CM CM
+3133 9 3701 3702 3703 # CM CM CM
+3134 10 3702 3703 3704 # CM CM CM
+3135 11 3703 3704 3705 # CM CM CT
+3136 1 3706 3707 3708 # HG CM CM
+3137 2 3707 3708 3709 # CM CM CM
+3138 3 3708 3709 3710 # CM CM CM
+3139 4 3709 3710 3711 # CM CM CM
+3140 5 3710 3711 3712 # CM CM CM
+3141 6 3711 3712 3713 # CM CM CM
+3142 7 3712 3713 3714 # CM CM CM
+3143 8 3713 3714 3715 # CM CM CM
+3144 9 3714 3715 3716 # CM CM CM
+3145 10 3715 3716 3717 # CM CM CM
+3146 11 3716 3717 3718 # CM CM CT
+3147 1 3719 3720 3721 # HG CM CM
+3148 2 3720 3721 3722 # CM CM CM
+3149 3 3721 3722 3723 # CM CM CM
+3150 4 3722 3723 3724 # CM CM CM
+3151 5 3723 3724 3725 # CM CM CM
+3152 6 3724 3725 3726 # CM CM CM
+3153 7 3725 3726 3727 # CM CM CM
+3154 8 3726 3727 3728 # CM CM CM
+3155 9 3727 3728 3729 # CM CM CM
+3156 10 3728 3729 3730 # CM CM CM
+3157 11 3729 3730 3731 # CM CM CT
+3158 1 3732 3733 3734 # HG CM CM
+3159 2 3733 3734 3735 # CM CM CM
+3160 3 3734 3735 3736 # CM CM CM
+3161 4 3735 3736 3737 # CM CM CM
+3162 5 3736 3737 3738 # CM CM CM
+3163 6 3737 3738 3739 # CM CM CM
+3164 7 3738 3739 3740 # CM CM CM
+3165 8 3739 3740 3741 # CM CM CM
+3166 9 3740 3741 3742 # CM CM CM
+3167 10 3741 3742 3743 # CM CM CM
+3168 11 3742 3743 3744 # CM CM CT
+3169 1 3745 3746 3747 # HG CM CM
+3170 2 3746 3747 3748 # CM CM CM
+3171 3 3747 3748 3749 # CM CM CM
+3172 4 3748 3749 3750 # CM CM CM
+3173 5 3749 3750 3751 # CM CM CM
+3174 6 3750 3751 3752 # CM CM CM
+3175 7 3751 3752 3753 # CM CM CM
+3176 8 3752 3753 3754 # CM CM CM
+3177 9 3753 3754 3755 # CM CM CM
+3178 10 3754 3755 3756 # CM CM CM
+3179 11 3755 3756 3757 # CM CM CT
+3180 1 3758 3759 3760 # HG CM CM
+3181 2 3759 3760 3761 # CM CM CM
+3182 3 3760 3761 3762 # CM CM CM
+3183 4 3761 3762 3763 # CM CM CM
+3184 5 3762 3763 3764 # CM CM CM
+3185 6 3763 3764 3765 # CM CM CM
+3186 7 3764 3765 3766 # CM CM CM
+3187 8 3765 3766 3767 # CM CM CM
+3188 9 3766 3767 3768 # CM CM CM
+3189 10 3767 3768 3769 # CM CM CM
+3190 11 3768 3769 3770 # CM CM CT
+3191 1 3771 3772 3773 # HG CM CM
+3192 2 3772 3773 3774 # CM CM CM
+3193 3 3773 3774 3775 # CM CM CM
+3194 4 3774 3775 3776 # CM CM CM
+3195 5 3775 3776 3777 # CM CM CM
+3196 6 3776 3777 3778 # CM CM CM
+3197 7 3777 3778 3779 # CM CM CM
+3198 8 3778 3779 3780 # CM CM CM
+3199 9 3779 3780 3781 # CM CM CM
+3200 10 3780 3781 3782 # CM CM CM
+3201 11 3781 3782 3783 # CM CM CT
+3202 1 3784 3785 3786 # HG CM CM
+3203 2 3785 3786 3787 # CM CM CM
+3204 3 3786 3787 3788 # CM CM CM
+3205 4 3787 3788 3789 # CM CM CM
+3206 5 3788 3789 3790 # CM CM CM
+3207 6 3789 3790 3791 # CM CM CM
+3208 7 3790 3791 3792 # CM CM CM
+3209 8 3791 3792 3793 # CM CM CM
+3210 9 3792 3793 3794 # CM CM CM
+3211 10 3793 3794 3795 # CM CM CM
+3212 11 3794 3795 3796 # CM CM CT
+3213 1 3797 3798 3799 # HG CM CM
+3214 2 3798 3799 3800 # CM CM CM
+3215 3 3799 3800 3801 # CM CM CM
+3216 4 3800 3801 3802 # CM CM CM
+3217 5 3801 3802 3803 # CM CM CM
+3218 6 3802 3803 3804 # CM CM CM
+3219 7 3803 3804 3805 # CM CM CM
+3220 8 3804 3805 3806 # CM CM CM
+3221 9 3805 3806 3807 # CM CM CM
+3222 10 3806 3807 3808 # CM CM CM
+3223 11 3807 3808 3809 # CM CM CT
+3224 1 3810 3811 3812 # HG CM CM
+3225 2 3811 3812 3813 # CM CM CM
+3226 3 3812 3813 3814 # CM CM CM
+3227 4 3813 3814 3815 # CM CM CM
+3228 5 3814 3815 3816 # CM CM CM
+3229 6 3815 3816 3817 # CM CM CM
+3230 7 3816 3817 3818 # CM CM CM
+3231 8 3817 3818 3819 # CM CM CM
+3232 9 3818 3819 3820 # CM CM CM
+3233 10 3819 3820 3821 # CM CM CM
+3234 11 3820 3821 3822 # CM CM CT
+3235 1 3823 3824 3825 # HG CM CM
+3236 2 3824 3825 3826 # CM CM CM
+3237 3 3825 3826 3827 # CM CM CM
+3238 4 3826 3827 3828 # CM CM CM
+3239 5 3827 3828 3829 # CM CM CM
+3240 6 3828 3829 3830 # CM CM CM
+3241 7 3829 3830 3831 # CM CM CM
+3242 8 3830 3831 3832 # CM CM CM
+3243 9 3831 3832 3833 # CM CM CM
+3244 10 3832 3833 3834 # CM CM CM
+3245 11 3833 3834 3835 # CM CM CT
+3246 1 3836 3837 3838 # HG CM CM
+3247 2 3837 3838 3839 # CM CM CM
+3248 3 3838 3839 3840 # CM CM CM
+3249 4 3839 3840 3841 # CM CM CM
+3250 5 3840 3841 3842 # CM CM CM
+3251 6 3841 3842 3843 # CM CM CM
+3252 7 3842 3843 3844 # CM CM CM
+3253 8 3843 3844 3845 # CM CM CM
+3254 9 3844 3845 3846 # CM CM CM
+3255 10 3845 3846 3847 # CM CM CM
+3256 11 3846 3847 3848 # CM CM CT
+3257 1 3849 3850 3851 # HG CM CM
+3258 2 3850 3851 3852 # CM CM CM
+3259 3 3851 3852 3853 # CM CM CM
+3260 4 3852 3853 3854 # CM CM CM
+3261 5 3853 3854 3855 # CM CM CM
+3262 6 3854 3855 3856 # CM CM CM
+3263 7 3855 3856 3857 # CM CM CM
+3264 8 3856 3857 3858 # CM CM CM
+3265 9 3857 3858 3859 # CM CM CM
+3266 10 3858 3859 3860 # CM CM CM
+3267 11 3859 3860 3861 # CM CM CT
+3268 1 3862 3863 3864 # HG CM CM
+3269 2 3863 3864 3865 # CM CM CM
+3270 3 3864 3865 3866 # CM CM CM
+3271 4 3865 3866 3867 # CM CM CM
+3272 5 3866 3867 3868 # CM CM CM
+3273 6 3867 3868 3869 # CM CM CM
+3274 7 3868 3869 3870 # CM CM CM
+3275 8 3869 3870 3871 # CM CM CM
+3276 9 3870 3871 3872 # CM CM CM
+3277 10 3871 3872 3873 # CM CM CM
+3278 11 3872 3873 3874 # CM CM CT
+3279 1 3875 3876 3877 # HG CM CM
+3280 2 3876 3877 3878 # CM CM CM
+3281 3 3877 3878 3879 # CM CM CM
+3282 4 3878 3879 3880 # CM CM CM
+3283 5 3879 3880 3881 # CM CM CM
+3284 6 3880 3881 3882 # CM CM CM
+3285 7 3881 3882 3883 # CM CM CM
+3286 8 3882 3883 3884 # CM CM CM
+3287 9 3883 3884 3885 # CM CM CM
+3288 10 3884 3885 3886 # CM CM CM
+3289 11 3885 3886 3887 # CM CM CT
+3290 1 3888 3889 3890 # HG CM CM
+3291 2 3889 3890 3891 # CM CM CM
+3292 3 3890 3891 3892 # CM CM CM
+3293 4 3891 3892 3893 # CM CM CM
+3294 5 3892 3893 3894 # CM CM CM
+3295 6 3893 3894 3895 # CM CM CM
+3296 7 3894 3895 3896 # CM CM CM
+3297 8 3895 3896 3897 # CM CM CM
+3298 9 3896 3897 3898 # CM CM CM
+3299 10 3897 3898 3899 # CM CM CM
+3300 11 3898 3899 3900 # CM CM CT
+
+Dihedrals
+
+1 1 1 2 3 4 # HG CM CM CM
+2 2 2 3 4 5 # CM CM CM CM
+3 3 3 4 5 6 # CM CM CM CM
+4 4 4 5 6 7 # CM CM CM CM
+5 5 5 6 7 8 # CM CM CM CM
+6 6 6 7 8 9 # CM CM CM CM
+7 7 7 8 9 10 # CM CM CM CM
+8 8 8 9 10 11 # CM CM CM CM
+9 9 9 10 11 12 # CM CM CM CM
+10 10 10 11 12 13 # CM CM CM CT
+11 1 14 15 16 17 # HG CM CM CM
+12 2 15 16 17 18 # CM CM CM CM
+13 3 16 17 18 19 # CM CM CM CM
+14 4 17 18 19 20 # CM CM CM CM
+15 5 18 19 20 21 # CM CM CM CM
+16 6 19 20 21 22 # CM CM CM CM
+17 7 20 21 22 23 # CM CM CM CM
+18 8 21 22 23 24 # CM CM CM CM
+19 9 22 23 24 25 # CM CM CM CM
+20 10 23 24 25 26 # CM CM CM CT
+21 1 27 28 29 30 # HG CM CM CM
+22 2 28 29 30 31 # CM CM CM CM
+23 3 29 30 31 32 # CM CM CM CM
+24 4 30 31 32 33 # CM CM CM CM
+25 5 31 32 33 34 # CM CM CM CM
+26 6 32 33 34 35 # CM CM CM CM
+27 7 33 34 35 36 # CM CM CM CM
+28 8 34 35 36 37 # CM CM CM CM
+29 9 35 36 37 38 # CM CM CM CM
+30 10 36 37 38 39 # CM CM CM CT
+31 1 40 41 42 43 # HG CM CM CM
+32 2 41 42 43 44 # CM CM CM CM
+33 3 42 43 44 45 # CM CM CM CM
+34 4 43 44 45 46 # CM CM CM CM
+35 5 44 45 46 47 # CM CM CM CM
+36 6 45 46 47 48 # CM CM CM CM
+37 7 46 47 48 49 # CM CM CM CM
+38 8 47 48 49 50 # CM CM CM CM
+39 9 48 49 50 51 # CM CM CM CM
+40 10 49 50 51 52 # CM CM CM CT
+41 1 53 54 55 56 # HG CM CM CM
+42 2 54 55 56 57 # CM CM CM CM
+43 3 55 56 57 58 # CM CM CM CM
+44 4 56 57 58 59 # CM CM CM CM
+45 5 57 58 59 60 # CM CM CM CM
+46 6 58 59 60 61 # CM CM CM CM
+47 7 59 60 61 62 # CM CM CM CM
+48 8 60 61 62 63 # CM CM CM CM
+49 9 61 62 63 64 # CM CM CM CM
+50 10 62 63 64 65 # CM CM CM CT
+51 1 66 67 68 69 # HG CM CM CM
+52 2 67 68 69 70 # CM CM CM CM
+53 3 68 69 70 71 # CM CM CM CM
+54 4 69 70 71 72 # CM CM CM CM
+55 5 70 71 72 73 # CM CM CM CM
+56 6 71 72 73 74 # CM CM CM CM
+57 7 72 73 74 75 # CM CM CM CM
+58 8 73 74 75 76 # CM CM CM CM
+59 9 74 75 76 77 # CM CM CM CM
+60 10 75 76 77 78 # CM CM CM CT
+61 1 79 80 81 82 # HG CM CM CM
+62 2 80 81 82 83 # CM CM CM CM
+63 3 81 82 83 84 # CM CM CM CM
+64 4 82 83 84 85 # CM CM CM CM
+65 5 83 84 85 86 # CM CM CM CM
+66 6 84 85 86 87 # CM CM CM CM
+67 7 85 86 87 88 # CM CM CM CM
+68 8 86 87 88 89 # CM CM CM CM
+69 9 87 88 89 90 # CM CM CM CM
+70 10 88 89 90 91 # CM CM CM CT
+71 1 92 93 94 95 # HG CM CM CM
+72 2 93 94 95 96 # CM CM CM CM
+73 3 94 95 96 97 # CM CM CM CM
+74 4 95 96 97 98 # CM CM CM CM
+75 5 96 97 98 99 # CM CM CM CM
+76 6 97 98 99 100 # CM CM CM CM
+77 7 98 99 100 101 # CM CM CM CM
+78 8 99 100 101 102 # CM CM CM CM
+79 9 100 101 102 103 # CM CM CM CM
+80 10 101 102 103 104 # CM CM CM CT
+81 1 105 106 107 108 # HG CM CM CM
+82 2 106 107 108 109 # CM CM CM CM
+83 3 107 108 109 110 # CM CM CM CM
+84 4 108 109 110 111 # CM CM CM CM
+85 5 109 110 111 112 # CM CM CM CM
+86 6 110 111 112 113 # CM CM CM CM
+87 7 111 112 113 114 # CM CM CM CM
+88 8 112 113 114 115 # CM CM CM CM
+89 9 113 114 115 116 # CM CM CM CM
+90 10 114 115 116 117 # CM CM CM CT
+91 1 118 119 120 121 # HG CM CM CM
+92 2 119 120 121 122 # CM CM CM CM
+93 3 120 121 122 123 # CM CM CM CM
+94 4 121 122 123 124 # CM CM CM CM
+95 5 122 123 124 125 # CM CM CM CM
+96 6 123 124 125 126 # CM CM CM CM
+97 7 124 125 126 127 # CM CM CM CM
+98 8 125 126 127 128 # CM CM CM CM
+99 9 126 127 128 129 # CM CM CM CM
+100 10 127 128 129 130 # CM CM CM CT
+101 1 131 132 133 134 # HG CM CM CM
+102 2 132 133 134 135 # CM CM CM CM
+103 3 133 134 135 136 # CM CM CM CM
+104 4 134 135 136 137 # CM CM CM CM
+105 5 135 136 137 138 # CM CM CM CM
+106 6 136 137 138 139 # CM CM CM CM
+107 7 137 138 139 140 # CM CM CM CM
+108 8 138 139 140 141 # CM CM CM CM
+109 9 139 140 141 142 # CM CM CM CM
+110 10 140 141 142 143 # CM CM CM CT
+111 1 144 145 146 147 # HG CM CM CM
+112 2 145 146 147 148 # CM CM CM CM
+113 3 146 147 148 149 # CM CM CM CM
+114 4 147 148 149 150 # CM CM CM CM
+115 5 148 149 150 151 # CM CM CM CM
+116 6 149 150 151 152 # CM CM CM CM
+117 7 150 151 152 153 # CM CM CM CM
+118 8 151 152 153 154 # CM CM CM CM
+119 9 152 153 154 155 # CM CM CM CM
+120 10 153 154 155 156 # CM CM CM CT
+121 1 157 158 159 160 # HG CM CM CM
+122 2 158 159 160 161 # CM CM CM CM
+123 3 159 160 161 162 # CM CM CM CM
+124 4 160 161 162 163 # CM CM CM CM
+125 5 161 162 163 164 # CM CM CM CM
+126 6 162 163 164 165 # CM CM CM CM
+127 7 163 164 165 166 # CM CM CM CM
+128 8 164 165 166 167 # CM CM CM CM
+129 9 165 166 167 168 # CM CM CM CM
+130 10 166 167 168 169 # CM CM CM CT
+131 1 170 171 172 173 # HG CM CM CM
+132 2 171 172 173 174 # CM CM CM CM
+133 3 172 173 174 175 # CM CM CM CM
+134 4 173 174 175 176 # CM CM CM CM
+135 5 174 175 176 177 # CM CM CM CM
+136 6 175 176 177 178 # CM CM CM CM
+137 7 176 177 178 179 # CM CM CM CM
+138 8 177 178 179 180 # CM CM CM CM
+139 9 178 179 180 181 # CM CM CM CM
+140 10 179 180 181 182 # CM CM CM CT
+141 1 183 184 185 186 # HG CM CM CM
+142 2 184 185 186 187 # CM CM CM CM
+143 3 185 186 187 188 # CM CM CM CM
+144 4 186 187 188 189 # CM CM CM CM
+145 5 187 188 189 190 # CM CM CM CM
+146 6 188 189 190 191 # CM CM CM CM
+147 7 189 190 191 192 # CM CM CM CM
+148 8 190 191 192 193 # CM CM CM CM
+149 9 191 192 193 194 # CM CM CM CM
+150 10 192 193 194 195 # CM CM CM CT
+151 1 196 197 198 199 # HG CM CM CM
+152 2 197 198 199 200 # CM CM CM CM
+153 3 198 199 200 201 # CM CM CM CM
+154 4 199 200 201 202 # CM CM CM CM
+155 5 200 201 202 203 # CM CM CM CM
+156 6 201 202 203 204 # CM CM CM CM
+157 7 202 203 204 205 # CM CM CM CM
+158 8 203 204 205 206 # CM CM CM CM
+159 9 204 205 206 207 # CM CM CM CM
+160 10 205 206 207 208 # CM CM CM CT
+161 1 209 210 211 212 # HG CM CM CM
+162 2 210 211 212 213 # CM CM CM CM
+163 3 211 212 213 214 # CM CM CM CM
+164 4 212 213 214 215 # CM CM CM CM
+165 5 213 214 215 216 # CM CM CM CM
+166 6 214 215 216 217 # CM CM CM CM
+167 7 215 216 217 218 # CM CM CM CM
+168 8 216 217 218 219 # CM CM CM CM
+169 9 217 218 219 220 # CM CM CM CM
+170 10 218 219 220 221 # CM CM CM CT
+171 1 222 223 224 225 # HG CM CM CM
+172 2 223 224 225 226 # CM CM CM CM
+173 3 224 225 226 227 # CM CM CM CM
+174 4 225 226 227 228 # CM CM CM CM
+175 5 226 227 228 229 # CM CM CM CM
+176 6 227 228 229 230 # CM CM CM CM
+177 7 228 229 230 231 # CM CM CM CM
+178 8 229 230 231 232 # CM CM CM CM
+179 9 230 231 232 233 # CM CM CM CM
+180 10 231 232 233 234 # CM CM CM CT
+181 1 235 236 237 238 # HG CM CM CM
+182 2 236 237 238 239 # CM CM CM CM
+183 3 237 238 239 240 # CM CM CM CM
+184 4 238 239 240 241 # CM CM CM CM
+185 5 239 240 241 242 # CM CM CM CM
+186 6 240 241 242 243 # CM CM CM CM
+187 7 241 242 243 244 # CM CM CM CM
+188 8 242 243 244 245 # CM CM CM CM
+189 9 243 244 245 246 # CM CM CM CM
+190 10 244 245 246 247 # CM CM CM CT
+191 1 248 249 250 251 # HG CM CM CM
+192 2 249 250 251 252 # CM CM CM CM
+193 3 250 251 252 253 # CM CM CM CM
+194 4 251 252 253 254 # CM CM CM CM
+195 5 252 253 254 255 # CM CM CM CM
+196 6 253 254 255 256 # CM CM CM CM
+197 7 254 255 256 257 # CM CM CM CM
+198 8 255 256 257 258 # CM CM CM CM
+199 9 256 257 258 259 # CM CM CM CM
+200 10 257 258 259 260 # CM CM CM CT
+201 1 261 262 263 264 # HG CM CM CM
+202 2 262 263 264 265 # CM CM CM CM
+203 3 263 264 265 266 # CM CM CM CM
+204 4 264 265 266 267 # CM CM CM CM
+205 5 265 266 267 268 # CM CM CM CM
+206 6 266 267 268 269 # CM CM CM CM
+207 7 267 268 269 270 # CM CM CM CM
+208 8 268 269 270 271 # CM CM CM CM
+209 9 269 270 271 272 # CM CM CM CM
+210 10 270 271 272 273 # CM CM CM CT
+211 1 274 275 276 277 # HG CM CM CM
+212 2 275 276 277 278 # CM CM CM CM
+213 3 276 277 278 279 # CM CM CM CM
+214 4 277 278 279 280 # CM CM CM CM
+215 5 278 279 280 281 # CM CM CM CM
+216 6 279 280 281 282 # CM CM CM CM
+217 7 280 281 282 283 # CM CM CM CM
+218 8 281 282 283 284 # CM CM CM CM
+219 9 282 283 284 285 # CM CM CM CM
+220 10 283 284 285 286 # CM CM CM CT
+221 1 287 288 289 290 # HG CM CM CM
+222 2 288 289 290 291 # CM CM CM CM
+223 3 289 290 291 292 # CM CM CM CM
+224 4 290 291 292 293 # CM CM CM CM
+225 5 291 292 293 294 # CM CM CM CM
+226 6 292 293 294 295 # CM CM CM CM
+227 7 293 294 295 296 # CM CM CM CM
+228 8 294 295 296 297 # CM CM CM CM
+229 9 295 296 297 298 # CM CM CM CM
+230 10 296 297 298 299 # CM CM CM CT
+231 1 300 301 302 303 # HG CM CM CM
+232 2 301 302 303 304 # CM CM CM CM
+233 3 302 303 304 305 # CM CM CM CM
+234 4 303 304 305 306 # CM CM CM CM
+235 5 304 305 306 307 # CM CM CM CM
+236 6 305 306 307 308 # CM CM CM CM
+237 7 306 307 308 309 # CM CM CM CM
+238 8 307 308 309 310 # CM CM CM CM
+239 9 308 309 310 311 # CM CM CM CM
+240 10 309 310 311 312 # CM CM CM CT
+241 1 313 314 315 316 # HG CM CM CM
+242 2 314 315 316 317 # CM CM CM CM
+243 3 315 316 317 318 # CM CM CM CM
+244 4 316 317 318 319 # CM CM CM CM
+245 5 317 318 319 320 # CM CM CM CM
+246 6 318 319 320 321 # CM CM CM CM
+247 7 319 320 321 322 # CM CM CM CM
+248 8 320 321 322 323 # CM CM CM CM
+249 9 321 322 323 324 # CM CM CM CM
+250 10 322 323 324 325 # CM CM CM CT
+251 1 326 327 328 329 # HG CM CM CM
+252 2 327 328 329 330 # CM CM CM CM
+253 3 328 329 330 331 # CM CM CM CM
+254 4 329 330 331 332 # CM CM CM CM
+255 5 330 331 332 333 # CM CM CM CM
+256 6 331 332 333 334 # CM CM CM CM
+257 7 332 333 334 335 # CM CM CM CM
+258 8 333 334 335 336 # CM CM CM CM
+259 9 334 335 336 337 # CM CM CM CM
+260 10 335 336 337 338 # CM CM CM CT
+261 1 339 340 341 342 # HG CM CM CM
+262 2 340 341 342 343 # CM CM CM CM
+263 3 341 342 343 344 # CM CM CM CM
+264 4 342 343 344 345 # CM CM CM CM
+265 5 343 344 345 346 # CM CM CM CM
+266 6 344 345 346 347 # CM CM CM CM
+267 7 345 346 347 348 # CM CM CM CM
+268 8 346 347 348 349 # CM CM CM CM
+269 9 347 348 349 350 # CM CM CM CM
+270 10 348 349 350 351 # CM CM CM CT
+271 1 352 353 354 355 # HG CM CM CM
+272 2 353 354 355 356 # CM CM CM CM
+273 3 354 355 356 357 # CM CM CM CM
+274 4 355 356 357 358 # CM CM CM CM
+275 5 356 357 358 359 # CM CM CM CM
+276 6 357 358 359 360 # CM CM CM CM
+277 7 358 359 360 361 # CM CM CM CM
+278 8 359 360 361 362 # CM CM CM CM
+279 9 360 361 362 363 # CM CM CM CM
+280 10 361 362 363 364 # CM CM CM CT
+281 1 365 366 367 368 # HG CM CM CM
+282 2 366 367 368 369 # CM CM CM CM
+283 3 367 368 369 370 # CM CM CM CM
+284 4 368 369 370 371 # CM CM CM CM
+285 5 369 370 371 372 # CM CM CM CM
+286 6 370 371 372 373 # CM CM CM CM
+287 7 371 372 373 374 # CM CM CM CM
+288 8 372 373 374 375 # CM CM CM CM
+289 9 373 374 375 376 # CM CM CM CM
+290 10 374 375 376 377 # CM CM CM CT
+291 1 378 379 380 381 # HG CM CM CM
+292 2 379 380 381 382 # CM CM CM CM
+293 3 380 381 382 383 # CM CM CM CM
+294 4 381 382 383 384 # CM CM CM CM
+295 5 382 383 384 385 # CM CM CM CM
+296 6 383 384 385 386 # CM CM CM CM
+297 7 384 385 386 387 # CM CM CM CM
+298 8 385 386 387 388 # CM CM CM CM
+299 9 386 387 388 389 # CM CM CM CM
+300 10 387 388 389 390 # CM CM CM CT
+301 1 391 392 393 394 # HG CM CM CM
+302 2 392 393 394 395 # CM CM CM CM
+303 3 393 394 395 396 # CM CM CM CM
+304 4 394 395 396 397 # CM CM CM CM
+305 5 395 396 397 398 # CM CM CM CM
+306 6 396 397 398 399 # CM CM CM CM
+307 7 397 398 399 400 # CM CM CM CM
+308 8 398 399 400 401 # CM CM CM CM
+309 9 399 400 401 402 # CM CM CM CM
+310 10 400 401 402 403 # CM CM CM CT
+311 1 404 405 406 407 # HG CM CM CM
+312 2 405 406 407 408 # CM CM CM CM
+313 3 406 407 408 409 # CM CM CM CM
+314 4 407 408 409 410 # CM CM CM CM
+315 5 408 409 410 411 # CM CM CM CM
+316 6 409 410 411 412 # CM CM CM CM
+317 7 410 411 412 413 # CM CM CM CM
+318 8 411 412 413 414 # CM CM CM CM
+319 9 412 413 414 415 # CM CM CM CM
+320 10 413 414 415 416 # CM CM CM CT
+321 1 417 418 419 420 # HG CM CM CM
+322 2 418 419 420 421 # CM CM CM CM
+323 3 419 420 421 422 # CM CM CM CM
+324 4 420 421 422 423 # CM CM CM CM
+325 5 421 422 423 424 # CM CM CM CM
+326 6 422 423 424 425 # CM CM CM CM
+327 7 423 424 425 426 # CM CM CM CM
+328 8 424 425 426 427 # CM CM CM CM
+329 9 425 426 427 428 # CM CM CM CM
+330 10 426 427 428 429 # CM CM CM CT
+331 1 430 431 432 433 # HG CM CM CM
+332 2 431 432 433 434 # CM CM CM CM
+333 3 432 433 434 435 # CM CM CM CM
+334 4 433 434 435 436 # CM CM CM CM
+335 5 434 435 436 437 # CM CM CM CM
+336 6 435 436 437 438 # CM CM CM CM
+337 7 436 437 438 439 # CM CM CM CM
+338 8 437 438 439 440 # CM CM CM CM
+339 9 438 439 440 441 # CM CM CM CM
+340 10 439 440 441 442 # CM CM CM CT
+341 1 443 444 445 446 # HG CM CM CM
+342 2 444 445 446 447 # CM CM CM CM
+343 3 445 446 447 448 # CM CM CM CM
+344 4 446 447 448 449 # CM CM CM CM
+345 5 447 448 449 450 # CM CM CM CM
+346 6 448 449 450 451 # CM CM CM CM
+347 7 449 450 451 452 # CM CM CM CM
+348 8 450 451 452 453 # CM CM CM CM
+349 9 451 452 453 454 # CM CM CM CM
+350 10 452 453 454 455 # CM CM CM CT
+351 1 456 457 458 459 # HG CM CM CM
+352 2 457 458 459 460 # CM CM CM CM
+353 3 458 459 460 461 # CM CM CM CM
+354 4 459 460 461 462 # CM CM CM CM
+355 5 460 461 462 463 # CM CM CM CM
+356 6 461 462 463 464 # CM CM CM CM
+357 7 462 463 464 465 # CM CM CM CM
+358 8 463 464 465 466 # CM CM CM CM
+359 9 464 465 466 467 # CM CM CM CM
+360 10 465 466 467 468 # CM CM CM CT
+361 1 469 470 471 472 # HG CM CM CM
+362 2 470 471 472 473 # CM CM CM CM
+363 3 471 472 473 474 # CM CM CM CM
+364 4 472 473 474 475 # CM CM CM CM
+365 5 473 474 475 476 # CM CM CM CM
+366 6 474 475 476 477 # CM CM CM CM
+367 7 475 476 477 478 # CM CM CM CM
+368 8 476 477 478 479 # CM CM CM CM
+369 9 477 478 479 480 # CM CM CM CM
+370 10 478 479 480 481 # CM CM CM CT
+371 1 482 483 484 485 # HG CM CM CM
+372 2 483 484 485 486 # CM CM CM CM
+373 3 484 485 486 487 # CM CM CM CM
+374 4 485 486 487 488 # CM CM CM CM
+375 5 486 487 488 489 # CM CM CM CM
+376 6 487 488 489 490 # CM CM CM CM
+377 7 488 489 490 491 # CM CM CM CM
+378 8 489 490 491 492 # CM CM CM CM
+379 9 490 491 492 493 # CM CM CM CM
+380 10 491 492 493 494 # CM CM CM CT
+381 1 495 496 497 498 # HG CM CM CM
+382 2 496 497 498 499 # CM CM CM CM
+383 3 497 498 499 500 # CM CM CM CM
+384 4 498 499 500 501 # CM CM CM CM
+385 5 499 500 501 502 # CM CM CM CM
+386 6 500 501 502 503 # CM CM CM CM
+387 7 501 502 503 504 # CM CM CM CM
+388 8 502 503 504 505 # CM CM CM CM
+389 9 503 504 505 506 # CM CM CM CM
+390 10 504 505 506 507 # CM CM CM CT
+391 1 508 509 510 511 # HG CM CM CM
+392 2 509 510 511 512 # CM CM CM CM
+393 3 510 511 512 513 # CM CM CM CM
+394 4 511 512 513 514 # CM CM CM CM
+395 5 512 513 514 515 # CM CM CM CM
+396 6 513 514 515 516 # CM CM CM CM
+397 7 514 515 516 517 # CM CM CM CM
+398 8 515 516 517 518 # CM CM CM CM
+399 9 516 517 518 519 # CM CM CM CM
+400 10 517 518 519 520 # CM CM CM CT
+401 1 521 522 523 524 # HG CM CM CM
+402 2 522 523 524 525 # CM CM CM CM
+403 3 523 524 525 526 # CM CM CM CM
+404 4 524 525 526 527 # CM CM CM CM
+405 5 525 526 527 528 # CM CM CM CM
+406 6 526 527 528 529 # CM CM CM CM
+407 7 527 528 529 530 # CM CM CM CM
+408 8 528 529 530 531 # CM CM CM CM
+409 9 529 530 531 532 # CM CM CM CM
+410 10 530 531 532 533 # CM CM CM CT
+411 1 534 535 536 537 # HG CM CM CM
+412 2 535 536 537 538 # CM CM CM CM
+413 3 536 537 538 539 # CM CM CM CM
+414 4 537 538 539 540 # CM CM CM CM
+415 5 538 539 540 541 # CM CM CM CM
+416 6 539 540 541 542 # CM CM CM CM
+417 7 540 541 542 543 # CM CM CM CM
+418 8 541 542 543 544 # CM CM CM CM
+419 9 542 543 544 545 # CM CM CM CM
+420 10 543 544 545 546 # CM CM CM CT
+421 1 547 548 549 550 # HG CM CM CM
+422 2 548 549 550 551 # CM CM CM CM
+423 3 549 550 551 552 # CM CM CM CM
+424 4 550 551 552 553 # CM CM CM CM
+425 5 551 552 553 554 # CM CM CM CM
+426 6 552 553 554 555 # CM CM CM CM
+427 7 553 554 555 556 # CM CM CM CM
+428 8 554 555 556 557 # CM CM CM CM
+429 9 555 556 557 558 # CM CM CM CM
+430 10 556 557 558 559 # CM CM CM CT
+431 1 560 561 562 563 # HG CM CM CM
+432 2 561 562 563 564 # CM CM CM CM
+433 3 562 563 564 565 # CM CM CM CM
+434 4 563 564 565 566 # CM CM CM CM
+435 5 564 565 566 567 # CM CM CM CM
+436 6 565 566 567 568 # CM CM CM CM
+437 7 566 567 568 569 # CM CM CM CM
+438 8 567 568 569 570 # CM CM CM CM
+439 9 568 569 570 571 # CM CM CM CM
+440 10 569 570 571 572 # CM CM CM CT
+441 1 573 574 575 576 # HG CM CM CM
+442 2 574 575 576 577 # CM CM CM CM
+443 3 575 576 577 578 # CM CM CM CM
+444 4 576 577 578 579 # CM CM CM CM
+445 5 577 578 579 580 # CM CM CM CM
+446 6 578 579 580 581 # CM CM CM CM
+447 7 579 580 581 582 # CM CM CM CM
+448 8 580 581 582 583 # CM CM CM CM
+449 9 581 582 583 584 # CM CM CM CM
+450 10 582 583 584 585 # CM CM CM CT
+451 1 586 587 588 589 # HG CM CM CM
+452 2 587 588 589 590 # CM CM CM CM
+453 3 588 589 590 591 # CM CM CM CM
+454 4 589 590 591 592 # CM CM CM CM
+455 5 590 591 592 593 # CM CM CM CM
+456 6 591 592 593 594 # CM CM CM CM
+457 7 592 593 594 595 # CM CM CM CM
+458 8 593 594 595 596 # CM CM CM CM
+459 9 594 595 596 597 # CM CM CM CM
+460 10 595 596 597 598 # CM CM CM CT
+461 1 599 600 601 602 # HG CM CM CM
+462 2 600 601 602 603 # CM CM CM CM
+463 3 601 602 603 604 # CM CM CM CM
+464 4 602 603 604 605 # CM CM CM CM
+465 5 603 604 605 606 # CM CM CM CM
+466 6 604 605 606 607 # CM CM CM CM
+467 7 605 606 607 608 # CM CM CM CM
+468 8 606 607 608 609 # CM CM CM CM
+469 9 607 608 609 610 # CM CM CM CM
+470 10 608 609 610 611 # CM CM CM CT
+471 1 612 613 614 615 # HG CM CM CM
+472 2 613 614 615 616 # CM CM CM CM
+473 3 614 615 616 617 # CM CM CM CM
+474 4 615 616 617 618 # CM CM CM CM
+475 5 616 617 618 619 # CM CM CM CM
+476 6 617 618 619 620 # CM CM CM CM
+477 7 618 619 620 621 # CM CM CM CM
+478 8 619 620 621 622 # CM CM CM CM
+479 9 620 621 622 623 # CM CM CM CM
+480 10 621 622 623 624 # CM CM CM CT
+481 1 625 626 627 628 # HG CM CM CM
+482 2 626 627 628 629 # CM CM CM CM
+483 3 627 628 629 630 # CM CM CM CM
+484 4 628 629 630 631 # CM CM CM CM
+485 5 629 630 631 632 # CM CM CM CM
+486 6 630 631 632 633 # CM CM CM CM
+487 7 631 632 633 634 # CM CM CM CM
+488 8 632 633 634 635 # CM CM CM CM
+489 9 633 634 635 636 # CM CM CM CM
+490 10 634 635 636 637 # CM CM CM CT
+491 1 638 639 640 641 # HG CM CM CM
+492 2 639 640 641 642 # CM CM CM CM
+493 3 640 641 642 643 # CM CM CM CM
+494 4 641 642 643 644 # CM CM CM CM
+495 5 642 643 644 645 # CM CM CM CM
+496 6 643 644 645 646 # CM CM CM CM
+497 7 644 645 646 647 # CM CM CM CM
+498 8 645 646 647 648 # CM CM CM CM
+499 9 646 647 648 649 # CM CM CM CM
+500 10 647 648 649 650 # CM CM CM CT
+501 1 651 652 653 654 # HG CM CM CM
+502 2 652 653 654 655 # CM CM CM CM
+503 3 653 654 655 656 # CM CM CM CM
+504 4 654 655 656 657 # CM CM CM CM
+505 5 655 656 657 658 # CM CM CM CM
+506 6 656 657 658 659 # CM CM CM CM
+507 7 657 658 659 660 # CM CM CM CM
+508 8 658 659 660 661 # CM CM CM CM
+509 9 659 660 661 662 # CM CM CM CM
+510 10 660 661 662 663 # CM CM CM CT
+511 1 664 665 666 667 # HG CM CM CM
+512 2 665 666 667 668 # CM CM CM CM
+513 3 666 667 668 669 # CM CM CM CM
+514 4 667 668 669 670 # CM CM CM CM
+515 5 668 669 670 671 # CM CM CM CM
+516 6 669 670 671 672 # CM CM CM CM
+517 7 670 671 672 673 # CM CM CM CM
+518 8 671 672 673 674 # CM CM CM CM
+519 9 672 673 674 675 # CM CM CM CM
+520 10 673 674 675 676 # CM CM CM CT
+521 1 677 678 679 680 # HG CM CM CM
+522 2 678 679 680 681 # CM CM CM CM
+523 3 679 680 681 682 # CM CM CM CM
+524 4 680 681 682 683 # CM CM CM CM
+525 5 681 682 683 684 # CM CM CM CM
+526 6 682 683 684 685 # CM CM CM CM
+527 7 683 684 685 686 # CM CM CM CM
+528 8 684 685 686 687 # CM CM CM CM
+529 9 685 686 687 688 # CM CM CM CM
+530 10 686 687 688 689 # CM CM CM CT
+531 1 690 691 692 693 # HG CM CM CM
+532 2 691 692 693 694 # CM CM CM CM
+533 3 692 693 694 695 # CM CM CM CM
+534 4 693 694 695 696 # CM CM CM CM
+535 5 694 695 696 697 # CM CM CM CM
+536 6 695 696 697 698 # CM CM CM CM
+537 7 696 697 698 699 # CM CM CM CM
+538 8 697 698 699 700 # CM CM CM CM
+539 9 698 699 700 701 # CM CM CM CM
+540 10 699 700 701 702 # CM CM CM CT
+541 1 703 704 705 706 # HG CM CM CM
+542 2 704 705 706 707 # CM CM CM CM
+543 3 705 706 707 708 # CM CM CM CM
+544 4 706 707 708 709 # CM CM CM CM
+545 5 707 708 709 710 # CM CM CM CM
+546 6 708 709 710 711 # CM CM CM CM
+547 7 709 710 711 712 # CM CM CM CM
+548 8 710 711 712 713 # CM CM CM CM
+549 9 711 712 713 714 # CM CM CM CM
+550 10 712 713 714 715 # CM CM CM CT
+551 1 716 717 718 719 # HG CM CM CM
+552 2 717 718 719 720 # CM CM CM CM
+553 3 718 719 720 721 # CM CM CM CM
+554 4 719 720 721 722 # CM CM CM CM
+555 5 720 721 722 723 # CM CM CM CM
+556 6 721 722 723 724 # CM CM CM CM
+557 7 722 723 724 725 # CM CM CM CM
+558 8 723 724 725 726 # CM CM CM CM
+559 9 724 725 726 727 # CM CM CM CM
+560 10 725 726 727 728 # CM CM CM CT
+561 1 729 730 731 732 # HG CM CM CM
+562 2 730 731 732 733 # CM CM CM CM
+563 3 731 732 733 734 # CM CM CM CM
+564 4 732 733 734 735 # CM CM CM CM
+565 5 733 734 735 736 # CM CM CM CM
+566 6 734 735 736 737 # CM CM CM CM
+567 7 735 736 737 738 # CM CM CM CM
+568 8 736 737 738 739 # CM CM CM CM
+569 9 737 738 739 740 # CM CM CM CM
+570 10 738 739 740 741 # CM CM CM CT
+571 1 742 743 744 745 # HG CM CM CM
+572 2 743 744 745 746 # CM CM CM CM
+573 3 744 745 746 747 # CM CM CM CM
+574 4 745 746 747 748 # CM CM CM CM
+575 5 746 747 748 749 # CM CM CM CM
+576 6 747 748 749 750 # CM CM CM CM
+577 7 748 749 750 751 # CM CM CM CM
+578 8 749 750 751 752 # CM CM CM CM
+579 9 750 751 752 753 # CM CM CM CM
+580 10 751 752 753 754 # CM CM CM CT
+581 1 755 756 757 758 # HG CM CM CM
+582 2 756 757 758 759 # CM CM CM CM
+583 3 757 758 759 760 # CM CM CM CM
+584 4 758 759 760 761 # CM CM CM CM
+585 5 759 760 761 762 # CM CM CM CM
+586 6 760 761 762 763 # CM CM CM CM
+587 7 761 762 763 764 # CM CM CM CM
+588 8 762 763 764 765 # CM CM CM CM
+589 9 763 764 765 766 # CM CM CM CM
+590 10 764 765 766 767 # CM CM CM CT
+591 1 768 769 770 771 # HG CM CM CM
+592 2 769 770 771 772 # CM CM CM CM
+593 3 770 771 772 773 # CM CM CM CM
+594 4 771 772 773 774 # CM CM CM CM
+595 5 772 773 774 775 # CM CM CM CM
+596 6 773 774 775 776 # CM CM CM CM
+597 7 774 775 776 777 # CM CM CM CM
+598 8 775 776 777 778 # CM CM CM CM
+599 9 776 777 778 779 # CM CM CM CM
+600 10 777 778 779 780 # CM CM CM CT
+601 1 781 782 783 784 # HG CM CM CM
+602 2 782 783 784 785 # CM CM CM CM
+603 3 783 784 785 786 # CM CM CM CM
+604 4 784 785 786 787 # CM CM CM CM
+605 5 785 786 787 788 # CM CM CM CM
+606 6 786 787 788 789 # CM CM CM CM
+607 7 787 788 789 790 # CM CM CM CM
+608 8 788 789 790 791 # CM CM CM CM
+609 9 789 790 791 792 # CM CM CM CM
+610 10 790 791 792 793 # CM CM CM CT
+611 1 794 795 796 797 # HG CM CM CM
+612 2 795 796 797 798 # CM CM CM CM
+613 3 796 797 798 799 # CM CM CM CM
+614 4 797 798 799 800 # CM CM CM CM
+615 5 798 799 800 801 # CM CM CM CM
+616 6 799 800 801 802 # CM CM CM CM
+617 7 800 801 802 803 # CM CM CM CM
+618 8 801 802 803 804 # CM CM CM CM
+619 9 802 803 804 805 # CM CM CM CM
+620 10 803 804 805 806 # CM CM CM CT
+621 1 807 808 809 810 # HG CM CM CM
+622 2 808 809 810 811 # CM CM CM CM
+623 3 809 810 811 812 # CM CM CM CM
+624 4 810 811 812 813 # CM CM CM CM
+625 5 811 812 813 814 # CM CM CM CM
+626 6 812 813 814 815 # CM CM CM CM
+627 7 813 814 815 816 # CM CM CM CM
+628 8 814 815 816 817 # CM CM CM CM
+629 9 815 816 817 818 # CM CM CM CM
+630 10 816 817 818 819 # CM CM CM CT
+631 1 820 821 822 823 # HG CM CM CM
+632 2 821 822 823 824 # CM CM CM CM
+633 3 822 823 824 825 # CM CM CM CM
+634 4 823 824 825 826 # CM CM CM CM
+635 5 824 825 826 827 # CM CM CM CM
+636 6 825 826 827 828 # CM CM CM CM
+637 7 826 827 828 829 # CM CM CM CM
+638 8 827 828 829 830 # CM CM CM CM
+639 9 828 829 830 831 # CM CM CM CM
+640 10 829 830 831 832 # CM CM CM CT
+641 1 833 834 835 836 # HG CM CM CM
+642 2 834 835 836 837 # CM CM CM CM
+643 3 835 836 837 838 # CM CM CM CM
+644 4 836 837 838 839 # CM CM CM CM
+645 5 837 838 839 840 # CM CM CM CM
+646 6 838 839 840 841 # CM CM CM CM
+647 7 839 840 841 842 # CM CM CM CM
+648 8 840 841 842 843 # CM CM CM CM
+649 9 841 842 843 844 # CM CM CM CM
+650 10 842 843 844 845 # CM CM CM CT
+651 1 846 847 848 849 # HG CM CM CM
+652 2 847 848 849 850 # CM CM CM CM
+653 3 848 849 850 851 # CM CM CM CM
+654 4 849 850 851 852 # CM CM CM CM
+655 5 850 851 852 853 # CM CM CM CM
+656 6 851 852 853 854 # CM CM CM CM
+657 7 852 853 854 855 # CM CM CM CM
+658 8 853 854 855 856 # CM CM CM CM
+659 9 854 855 856 857 # CM CM CM CM
+660 10 855 856 857 858 # CM CM CM CT
+661 1 859 860 861 862 # HG CM CM CM
+662 2 860 861 862 863 # CM CM CM CM
+663 3 861 862 863 864 # CM CM CM CM
+664 4 862 863 864 865 # CM CM CM CM
+665 5 863 864 865 866 # CM CM CM CM
+666 6 864 865 866 867 # CM CM CM CM
+667 7 865 866 867 868 # CM CM CM CM
+668 8 866 867 868 869 # CM CM CM CM
+669 9 867 868 869 870 # CM CM CM CM
+670 10 868 869 870 871 # CM CM CM CT
+671 1 872 873 874 875 # HG CM CM CM
+672 2 873 874 875 876 # CM CM CM CM
+673 3 874 875 876 877 # CM CM CM CM
+674 4 875 876 877 878 # CM CM CM CM
+675 5 876 877 878 879 # CM CM CM CM
+676 6 877 878 879 880 # CM CM CM CM
+677 7 878 879 880 881 # CM CM CM CM
+678 8 879 880 881 882 # CM CM CM CM
+679 9 880 881 882 883 # CM CM CM CM
+680 10 881 882 883 884 # CM CM CM CT
+681 1 885 886 887 888 # HG CM CM CM
+682 2 886 887 888 889 # CM CM CM CM
+683 3 887 888 889 890 # CM CM CM CM
+684 4 888 889 890 891 # CM CM CM CM
+685 5 889 890 891 892 # CM CM CM CM
+686 6 890 891 892 893 # CM CM CM CM
+687 7 891 892 893 894 # CM CM CM CM
+688 8 892 893 894 895 # CM CM CM CM
+689 9 893 894 895 896 # CM CM CM CM
+690 10 894 895 896 897 # CM CM CM CT
+691 1 898 899 900 901 # HG CM CM CM
+692 2 899 900 901 902 # CM CM CM CM
+693 3 900 901 902 903 # CM CM CM CM
+694 4 901 902 903 904 # CM CM CM CM
+695 5 902 903 904 905 # CM CM CM CM
+696 6 903 904 905 906 # CM CM CM CM
+697 7 904 905 906 907 # CM CM CM CM
+698 8 905 906 907 908 # CM CM CM CM
+699 9 906 907 908 909 # CM CM CM CM
+700 10 907 908 909 910 # CM CM CM CT
+701 1 911 912 913 914 # HG CM CM CM
+702 2 912 913 914 915 # CM CM CM CM
+703 3 913 914 915 916 # CM CM CM CM
+704 4 914 915 916 917 # CM CM CM CM
+705 5 915 916 917 918 # CM CM CM CM
+706 6 916 917 918 919 # CM CM CM CM
+707 7 917 918 919 920 # CM CM CM CM
+708 8 918 919 920 921 # CM CM CM CM
+709 9 919 920 921 922 # CM CM CM CM
+710 10 920 921 922 923 # CM CM CM CT
+711 1 924 925 926 927 # HG CM CM CM
+712 2 925 926 927 928 # CM CM CM CM
+713 3 926 927 928 929 # CM CM CM CM
+714 4 927 928 929 930 # CM CM CM CM
+715 5 928 929 930 931 # CM CM CM CM
+716 6 929 930 931 932 # CM CM CM CM
+717 7 930 931 932 933 # CM CM CM CM
+718 8 931 932 933 934 # CM CM CM CM
+719 9 932 933 934 935 # CM CM CM CM
+720 10 933 934 935 936 # CM CM CM CT
+721 1 937 938 939 940 # HG CM CM CM
+722 2 938 939 940 941 # CM CM CM CM
+723 3 939 940 941 942 # CM CM CM CM
+724 4 940 941 942 943 # CM CM CM CM
+725 5 941 942 943 944 # CM CM CM CM
+726 6 942 943 944 945 # CM CM CM CM
+727 7 943 944 945 946 # CM CM CM CM
+728 8 944 945 946 947 # CM CM CM CM
+729 9 945 946 947 948 # CM CM CM CM
+730 10 946 947 948 949 # CM CM CM CT
+731 1 950 951 952 953 # HG CM CM CM
+732 2 951 952 953 954 # CM CM CM CM
+733 3 952 953 954 955 # CM CM CM CM
+734 4 953 954 955 956 # CM CM CM CM
+735 5 954 955 956 957 # CM CM CM CM
+736 6 955 956 957 958 # CM CM CM CM
+737 7 956 957 958 959 # CM CM CM CM
+738 8 957 958 959 960 # CM CM CM CM
+739 9 958 959 960 961 # CM CM CM CM
+740 10 959 960 961 962 # CM CM CM CT
+741 1 963 964 965 966 # HG CM CM CM
+742 2 964 965 966 967 # CM CM CM CM
+743 3 965 966 967 968 # CM CM CM CM
+744 4 966 967 968 969 # CM CM CM CM
+745 5 967 968 969 970 # CM CM CM CM
+746 6 968 969 970 971 # CM CM CM CM
+747 7 969 970 971 972 # CM CM CM CM
+748 8 970 971 972 973 # CM CM CM CM
+749 9 971 972 973 974 # CM CM CM CM
+750 10 972 973 974 975 # CM CM CM CT
+751 1 976 977 978 979 # HG CM CM CM
+752 2 977 978 979 980 # CM CM CM CM
+753 3 978 979 980 981 # CM CM CM CM
+754 4 979 980 981 982 # CM CM CM CM
+755 5 980 981 982 983 # CM CM CM CM
+756 6 981 982 983 984 # CM CM CM CM
+757 7 982 983 984 985 # CM CM CM CM
+758 8 983 984 985 986 # CM CM CM CM
+759 9 984 985 986 987 # CM CM CM CM
+760 10 985 986 987 988 # CM CM CM CT
+761 1 989 990 991 992 # HG CM CM CM
+762 2 990 991 992 993 # CM CM CM CM
+763 3 991 992 993 994 # CM CM CM CM
+764 4 992 993 994 995 # CM CM CM CM
+765 5 993 994 995 996 # CM CM CM CM
+766 6 994 995 996 997 # CM CM CM CM
+767 7 995 996 997 998 # CM CM CM CM
+768 8 996 997 998 999 # CM CM CM CM
+769 9 997 998 999 1000 # CM CM CM CM
+770 10 998 999 1000 1001 # CM CM CM CT
+771 1 1002 1003 1004 1005 # HG CM CM CM
+772 2 1003 1004 1005 1006 # CM CM CM CM
+773 3 1004 1005 1006 1007 # CM CM CM CM
+774 4 1005 1006 1007 1008 # CM CM CM CM
+775 5 1006 1007 1008 1009 # CM CM CM CM
+776 6 1007 1008 1009 1010 # CM CM CM CM
+777 7 1008 1009 1010 1011 # CM CM CM CM
+778 8 1009 1010 1011 1012 # CM CM CM CM
+779 9 1010 1011 1012 1013 # CM CM CM CM
+780 10 1011 1012 1013 1014 # CM CM CM CT
+781 1 1015 1016 1017 1018 # HG CM CM CM
+782 2 1016 1017 1018 1019 # CM CM CM CM
+783 3 1017 1018 1019 1020 # CM CM CM CM
+784 4 1018 1019 1020 1021 # CM CM CM CM
+785 5 1019 1020 1021 1022 # CM CM CM CM
+786 6 1020 1021 1022 1023 # CM CM CM CM
+787 7 1021 1022 1023 1024 # CM CM CM CM
+788 8 1022 1023 1024 1025 # CM CM CM CM
+789 9 1023 1024 1025 1026 # CM CM CM CM
+790 10 1024 1025 1026 1027 # CM CM CM CT
+791 1 1028 1029 1030 1031 # HG CM CM CM
+792 2 1029 1030 1031 1032 # CM CM CM CM
+793 3 1030 1031 1032 1033 # CM CM CM CM
+794 4 1031 1032 1033 1034 # CM CM CM CM
+795 5 1032 1033 1034 1035 # CM CM CM CM
+796 6 1033 1034 1035 1036 # CM CM CM CM
+797 7 1034 1035 1036 1037 # CM CM CM CM
+798 8 1035 1036 1037 1038 # CM CM CM CM
+799 9 1036 1037 1038 1039 # CM CM CM CM
+800 10 1037 1038 1039 1040 # CM CM CM CT
+801 1 1041 1042 1043 1044 # HG CM CM CM
+802 2 1042 1043 1044 1045 # CM CM CM CM
+803 3 1043 1044 1045 1046 # CM CM CM CM
+804 4 1044 1045 1046 1047 # CM CM CM CM
+805 5 1045 1046 1047 1048 # CM CM CM CM
+806 6 1046 1047 1048 1049 # CM CM CM CM
+807 7 1047 1048 1049 1050 # CM CM CM CM
+808 8 1048 1049 1050 1051 # CM CM CM CM
+809 9 1049 1050 1051 1052 # CM CM CM CM
+810 10 1050 1051 1052 1053 # CM CM CM CT
+811 1 1054 1055 1056 1057 # HG CM CM CM
+812 2 1055 1056 1057 1058 # CM CM CM CM
+813 3 1056 1057 1058 1059 # CM CM CM CM
+814 4 1057 1058 1059 1060 # CM CM CM CM
+815 5 1058 1059 1060 1061 # CM CM CM CM
+816 6 1059 1060 1061 1062 # CM CM CM CM
+817 7 1060 1061 1062 1063 # CM CM CM CM
+818 8 1061 1062 1063 1064 # CM CM CM CM
+819 9 1062 1063 1064 1065 # CM CM CM CM
+820 10 1063 1064 1065 1066 # CM CM CM CT
+821 1 1067 1068 1069 1070 # HG CM CM CM
+822 2 1068 1069 1070 1071 # CM CM CM CM
+823 3 1069 1070 1071 1072 # CM CM CM CM
+824 4 1070 1071 1072 1073 # CM CM CM CM
+825 5 1071 1072 1073 1074 # CM CM CM CM
+826 6 1072 1073 1074 1075 # CM CM CM CM
+827 7 1073 1074 1075 1076 # CM CM CM CM
+828 8 1074 1075 1076 1077 # CM CM CM CM
+829 9 1075 1076 1077 1078 # CM CM CM CM
+830 10 1076 1077 1078 1079 # CM CM CM CT
+831 1 1080 1081 1082 1083 # HG CM CM CM
+832 2 1081 1082 1083 1084 # CM CM CM CM
+833 3 1082 1083 1084 1085 # CM CM CM CM
+834 4 1083 1084 1085 1086 # CM CM CM CM
+835 5 1084 1085 1086 1087 # CM CM CM CM
+836 6 1085 1086 1087 1088 # CM CM CM CM
+837 7 1086 1087 1088 1089 # CM CM CM CM
+838 8 1087 1088 1089 1090 # CM CM CM CM
+839 9 1088 1089 1090 1091 # CM CM CM CM
+840 10 1089 1090 1091 1092 # CM CM CM CT
+841 1 1093 1094 1095 1096 # HG CM CM CM
+842 2 1094 1095 1096 1097 # CM CM CM CM
+843 3 1095 1096 1097 1098 # CM CM CM CM
+844 4 1096 1097 1098 1099 # CM CM CM CM
+845 5 1097 1098 1099 1100 # CM CM CM CM
+846 6 1098 1099 1100 1101 # CM CM CM CM
+847 7 1099 1100 1101 1102 # CM CM CM CM
+848 8 1100 1101 1102 1103 # CM CM CM CM
+849 9 1101 1102 1103 1104 # CM CM CM CM
+850 10 1102 1103 1104 1105 # CM CM CM CT
+851 1 1106 1107 1108 1109 # HG CM CM CM
+852 2 1107 1108 1109 1110 # CM CM CM CM
+853 3 1108 1109 1110 1111 # CM CM CM CM
+854 4 1109 1110 1111 1112 # CM CM CM CM
+855 5 1110 1111 1112 1113 # CM CM CM CM
+856 6 1111 1112 1113 1114 # CM CM CM CM
+857 7 1112 1113 1114 1115 # CM CM CM CM
+858 8 1113 1114 1115 1116 # CM CM CM CM
+859 9 1114 1115 1116 1117 # CM CM CM CM
+860 10 1115 1116 1117 1118 # CM CM CM CT
+861 1 1119 1120 1121 1122 # HG CM CM CM
+862 2 1120 1121 1122 1123 # CM CM CM CM
+863 3 1121 1122 1123 1124 # CM CM CM CM
+864 4 1122 1123 1124 1125 # CM CM CM CM
+865 5 1123 1124 1125 1126 # CM CM CM CM
+866 6 1124 1125 1126 1127 # CM CM CM CM
+867 7 1125 1126 1127 1128 # CM CM CM CM
+868 8 1126 1127 1128 1129 # CM CM CM CM
+869 9 1127 1128 1129 1130 # CM CM CM CM
+870 10 1128 1129 1130 1131 # CM CM CM CT
+871 1 1132 1133 1134 1135 # HG CM CM CM
+872 2 1133 1134 1135 1136 # CM CM CM CM
+873 3 1134 1135 1136 1137 # CM CM CM CM
+874 4 1135 1136 1137 1138 # CM CM CM CM
+875 5 1136 1137 1138 1139 # CM CM CM CM
+876 6 1137 1138 1139 1140 # CM CM CM CM
+877 7 1138 1139 1140 1141 # CM CM CM CM
+878 8 1139 1140 1141 1142 # CM CM CM CM
+879 9 1140 1141 1142 1143 # CM CM CM CM
+880 10 1141 1142 1143 1144 # CM CM CM CT
+881 1 1145 1146 1147 1148 # HG CM CM CM
+882 2 1146 1147 1148 1149 # CM CM CM CM
+883 3 1147 1148 1149 1150 # CM CM CM CM
+884 4 1148 1149 1150 1151 # CM CM CM CM
+885 5 1149 1150 1151 1152 # CM CM CM CM
+886 6 1150 1151 1152 1153 # CM CM CM CM
+887 7 1151 1152 1153 1154 # CM CM CM CM
+888 8 1152 1153 1154 1155 # CM CM CM CM
+889 9 1153 1154 1155 1156 # CM CM CM CM
+890 10 1154 1155 1156 1157 # CM CM CM CT
+891 1 1158 1159 1160 1161 # HG CM CM CM
+892 2 1159 1160 1161 1162 # CM CM CM CM
+893 3 1160 1161 1162 1163 # CM CM CM CM
+894 4 1161 1162 1163 1164 # CM CM CM CM
+895 5 1162 1163 1164 1165 # CM CM CM CM
+896 6 1163 1164 1165 1166 # CM CM CM CM
+897 7 1164 1165 1166 1167 # CM CM CM CM
+898 8 1165 1166 1167 1168 # CM CM CM CM
+899 9 1166 1167 1168 1169 # CM CM CM CM
+900 10 1167 1168 1169 1170 # CM CM CM CT
+901 1 1171 1172 1173 1174 # HG CM CM CM
+902 2 1172 1173 1174 1175 # CM CM CM CM
+903 3 1173 1174 1175 1176 # CM CM CM CM
+904 4 1174 1175 1176 1177 # CM CM CM CM
+905 5 1175 1176 1177 1178 # CM CM CM CM
+906 6 1176 1177 1178 1179 # CM CM CM CM
+907 7 1177 1178 1179 1180 # CM CM CM CM
+908 8 1178 1179 1180 1181 # CM CM CM CM
+909 9 1179 1180 1181 1182 # CM CM CM CM
+910 10 1180 1181 1182 1183 # CM CM CM CT
+911 1 1184 1185 1186 1187 # HG CM CM CM
+912 2 1185 1186 1187 1188 # CM CM CM CM
+913 3 1186 1187 1188 1189 # CM CM CM CM
+914 4 1187 1188 1189 1190 # CM CM CM CM
+915 5 1188 1189 1190 1191 # CM CM CM CM
+916 6 1189 1190 1191 1192 # CM CM CM CM
+917 7 1190 1191 1192 1193 # CM CM CM CM
+918 8 1191 1192 1193 1194 # CM CM CM CM
+919 9 1192 1193 1194 1195 # CM CM CM CM
+920 10 1193 1194 1195 1196 # CM CM CM CT
+921 1 1197 1198 1199 1200 # HG CM CM CM
+922 2 1198 1199 1200 1201 # CM CM CM CM
+923 3 1199 1200 1201 1202 # CM CM CM CM
+924 4 1200 1201 1202 1203 # CM CM CM CM
+925 5 1201 1202 1203 1204 # CM CM CM CM
+926 6 1202 1203 1204 1205 # CM CM CM CM
+927 7 1203 1204 1205 1206 # CM CM CM CM
+928 8 1204 1205 1206 1207 # CM CM CM CM
+929 9 1205 1206 1207 1208 # CM CM CM CM
+930 10 1206 1207 1208 1209 # CM CM CM CT
+931 1 1210 1211 1212 1213 # HG CM CM CM
+932 2 1211 1212 1213 1214 # CM CM CM CM
+933 3 1212 1213 1214 1215 # CM CM CM CM
+934 4 1213 1214 1215 1216 # CM CM CM CM
+935 5 1214 1215 1216 1217 # CM CM CM CM
+936 6 1215 1216 1217 1218 # CM CM CM CM
+937 7 1216 1217 1218 1219 # CM CM CM CM
+938 8 1217 1218 1219 1220 # CM CM CM CM
+939 9 1218 1219 1220 1221 # CM CM CM CM
+940 10 1219 1220 1221 1222 # CM CM CM CT
+941 1 1223 1224 1225 1226 # HG CM CM CM
+942 2 1224 1225 1226 1227 # CM CM CM CM
+943 3 1225 1226 1227 1228 # CM CM CM CM
+944 4 1226 1227 1228 1229 # CM CM CM CM
+945 5 1227 1228 1229 1230 # CM CM CM CM
+946 6 1228 1229 1230 1231 # CM CM CM CM
+947 7 1229 1230 1231 1232 # CM CM CM CM
+948 8 1230 1231 1232 1233 # CM CM CM CM
+949 9 1231 1232 1233 1234 # CM CM CM CM
+950 10 1232 1233 1234 1235 # CM CM CM CT
+951 1 1236 1237 1238 1239 # HG CM CM CM
+952 2 1237 1238 1239 1240 # CM CM CM CM
+953 3 1238 1239 1240 1241 # CM CM CM CM
+954 4 1239 1240 1241 1242 # CM CM CM CM
+955 5 1240 1241 1242 1243 # CM CM CM CM
+956 6 1241 1242 1243 1244 # CM CM CM CM
+957 7 1242 1243 1244 1245 # CM CM CM CM
+958 8 1243 1244 1245 1246 # CM CM CM CM
+959 9 1244 1245 1246 1247 # CM CM CM CM
+960 10 1245 1246 1247 1248 # CM CM CM CT
+961 1 1249 1250 1251 1252 # HG CM CM CM
+962 2 1250 1251 1252 1253 # CM CM CM CM
+963 3 1251 1252 1253 1254 # CM CM CM CM
+964 4 1252 1253 1254 1255 # CM CM CM CM
+965 5 1253 1254 1255 1256 # CM CM CM CM
+966 6 1254 1255 1256 1257 # CM CM CM CM
+967 7 1255 1256 1257 1258 # CM CM CM CM
+968 8 1256 1257 1258 1259 # CM CM CM CM
+969 9 1257 1258 1259 1260 # CM CM CM CM
+970 10 1258 1259 1260 1261 # CM CM CM CT
+971 1 1262 1263 1264 1265 # HG CM CM CM
+972 2 1263 1264 1265 1266 # CM CM CM CM
+973 3 1264 1265 1266 1267 # CM CM CM CM
+974 4 1265 1266 1267 1268 # CM CM CM CM
+975 5 1266 1267 1268 1269 # CM CM CM CM
+976 6 1267 1268 1269 1270 # CM CM CM CM
+977 7 1268 1269 1270 1271 # CM CM CM CM
+978 8 1269 1270 1271 1272 # CM CM CM CM
+979 9 1270 1271 1272 1273 # CM CM CM CM
+980 10 1271 1272 1273 1274 # CM CM CM CT
+981 1 1275 1276 1277 1278 # HG CM CM CM
+982 2 1276 1277 1278 1279 # CM CM CM CM
+983 3 1277 1278 1279 1280 # CM CM CM CM
+984 4 1278 1279 1280 1281 # CM CM CM CM
+985 5 1279 1280 1281 1282 # CM CM CM CM
+986 6 1280 1281 1282 1283 # CM CM CM CM
+987 7 1281 1282 1283 1284 # CM CM CM CM
+988 8 1282 1283 1284 1285 # CM CM CM CM
+989 9 1283 1284 1285 1286 # CM CM CM CM
+990 10 1284 1285 1286 1287 # CM CM CM CT
+991 1 1288 1289 1290 1291 # HG CM CM CM
+992 2 1289 1290 1291 1292 # CM CM CM CM
+993 3 1290 1291 1292 1293 # CM CM CM CM
+994 4 1291 1292 1293 1294 # CM CM CM CM
+995 5 1292 1293 1294 1295 # CM CM CM CM
+996 6 1293 1294 1295 1296 # CM CM CM CM
+997 7 1294 1295 1296 1297 # CM CM CM CM
+998 8 1295 1296 1297 1298 # CM CM CM CM
+999 9 1296 1297 1298 1299 # CM CM CM CM
+1000 10 1297 1298 1299 1300 # CM CM CM CT
+1001 1 1301 1302 1303 1304 # HG CM CM CM
+1002 2 1302 1303 1304 1305 # CM CM CM CM
+1003 3 1303 1304 1305 1306 # CM CM CM CM
+1004 4 1304 1305 1306 1307 # CM CM CM CM
+1005 5 1305 1306 1307 1308 # CM CM CM CM
+1006 6 1306 1307 1308 1309 # CM CM CM CM
+1007 7 1307 1308 1309 1310 # CM CM CM CM
+1008 8 1308 1309 1310 1311 # CM CM CM CM
+1009 9 1309 1310 1311 1312 # CM CM CM CM
+1010 10 1310 1311 1312 1313 # CM CM CM CT
+1011 1 1314 1315 1316 1317 # HG CM CM CM
+1012 2 1315 1316 1317 1318 # CM CM CM CM
+1013 3 1316 1317 1318 1319 # CM CM CM CM
+1014 4 1317 1318 1319 1320 # CM CM CM CM
+1015 5 1318 1319 1320 1321 # CM CM CM CM
+1016 6 1319 1320 1321 1322 # CM CM CM CM
+1017 7 1320 1321 1322 1323 # CM CM CM CM
+1018 8 1321 1322 1323 1324 # CM CM CM CM
+1019 9 1322 1323 1324 1325 # CM CM CM CM
+1020 10 1323 1324 1325 1326 # CM CM CM CT
+1021 1 1327 1328 1329 1330 # HG CM CM CM
+1022 2 1328 1329 1330 1331 # CM CM CM CM
+1023 3 1329 1330 1331 1332 # CM CM CM CM
+1024 4 1330 1331 1332 1333 # CM CM CM CM
+1025 5 1331 1332 1333 1334 # CM CM CM CM
+1026 6 1332 1333 1334 1335 # CM CM CM CM
+1027 7 1333 1334 1335 1336 # CM CM CM CM
+1028 8 1334 1335 1336 1337 # CM CM CM CM
+1029 9 1335 1336 1337 1338 # CM CM CM CM
+1030 10 1336 1337 1338 1339 # CM CM CM CT
+1031 1 1340 1341 1342 1343 # HG CM CM CM
+1032 2 1341 1342 1343 1344 # CM CM CM CM
+1033 3 1342 1343 1344 1345 # CM CM CM CM
+1034 4 1343 1344 1345 1346 # CM CM CM CM
+1035 5 1344 1345 1346 1347 # CM CM CM CM
+1036 6 1345 1346 1347 1348 # CM CM CM CM
+1037 7 1346 1347 1348 1349 # CM CM CM CM
+1038 8 1347 1348 1349 1350 # CM CM CM CM
+1039 9 1348 1349 1350 1351 # CM CM CM CM
+1040 10 1349 1350 1351 1352 # CM CM CM CT
+1041 1 1353 1354 1355 1356 # HG CM CM CM
+1042 2 1354 1355 1356 1357 # CM CM CM CM
+1043 3 1355 1356 1357 1358 # CM CM CM CM
+1044 4 1356 1357 1358 1359 # CM CM CM CM
+1045 5 1357 1358 1359 1360 # CM CM CM CM
+1046 6 1358 1359 1360 1361 # CM CM CM CM
+1047 7 1359 1360 1361 1362 # CM CM CM CM
+1048 8 1360 1361 1362 1363 # CM CM CM CM
+1049 9 1361 1362 1363 1364 # CM CM CM CM
+1050 10 1362 1363 1364 1365 # CM CM CM CT
+1051 1 1366 1367 1368 1369 # HG CM CM CM
+1052 2 1367 1368 1369 1370 # CM CM CM CM
+1053 3 1368 1369 1370 1371 # CM CM CM CM
+1054 4 1369 1370 1371 1372 # CM CM CM CM
+1055 5 1370 1371 1372 1373 # CM CM CM CM
+1056 6 1371 1372 1373 1374 # CM CM CM CM
+1057 7 1372 1373 1374 1375 # CM CM CM CM
+1058 8 1373 1374 1375 1376 # CM CM CM CM
+1059 9 1374 1375 1376 1377 # CM CM CM CM
+1060 10 1375 1376 1377 1378 # CM CM CM CT
+1061 1 1379 1380 1381 1382 # HG CM CM CM
+1062 2 1380 1381 1382 1383 # CM CM CM CM
+1063 3 1381 1382 1383 1384 # CM CM CM CM
+1064 4 1382 1383 1384 1385 # CM CM CM CM
+1065 5 1383 1384 1385 1386 # CM CM CM CM
+1066 6 1384 1385 1386 1387 # CM CM CM CM
+1067 7 1385 1386 1387 1388 # CM CM CM CM
+1068 8 1386 1387 1388 1389 # CM CM CM CM
+1069 9 1387 1388 1389 1390 # CM CM CM CM
+1070 10 1388 1389 1390 1391 # CM CM CM CT
+1071 1 1392 1393 1394 1395 # HG CM CM CM
+1072 2 1393 1394 1395 1396 # CM CM CM CM
+1073 3 1394 1395 1396 1397 # CM CM CM CM
+1074 4 1395 1396 1397 1398 # CM CM CM CM
+1075 5 1396 1397 1398 1399 # CM CM CM CM
+1076 6 1397 1398 1399 1400 # CM CM CM CM
+1077 7 1398 1399 1400 1401 # CM CM CM CM
+1078 8 1399 1400 1401 1402 # CM CM CM CM
+1079 9 1400 1401 1402 1403 # CM CM CM CM
+1080 10 1401 1402 1403 1404 # CM CM CM CT
+1081 1 1405 1406 1407 1408 # HG CM CM CM
+1082 2 1406 1407 1408 1409 # CM CM CM CM
+1083 3 1407 1408 1409 1410 # CM CM CM CM
+1084 4 1408 1409 1410 1411 # CM CM CM CM
+1085 5 1409 1410 1411 1412 # CM CM CM CM
+1086 6 1410 1411 1412 1413 # CM CM CM CM
+1087 7 1411 1412 1413 1414 # CM CM CM CM
+1088 8 1412 1413 1414 1415 # CM CM CM CM
+1089 9 1413 1414 1415 1416 # CM CM CM CM
+1090 10 1414 1415 1416 1417 # CM CM CM CT
+1091 1 1418 1419 1420 1421 # HG CM CM CM
+1092 2 1419 1420 1421 1422 # CM CM CM CM
+1093 3 1420 1421 1422 1423 # CM CM CM CM
+1094 4 1421 1422 1423 1424 # CM CM CM CM
+1095 5 1422 1423 1424 1425 # CM CM CM CM
+1096 6 1423 1424 1425 1426 # CM CM CM CM
+1097 7 1424 1425 1426 1427 # CM CM CM CM
+1098 8 1425 1426 1427 1428 # CM CM CM CM
+1099 9 1426 1427 1428 1429 # CM CM CM CM
+1100 10 1427 1428 1429 1430 # CM CM CM CT
+1101 1 1431 1432 1433 1434 # HG CM CM CM
+1102 2 1432 1433 1434 1435 # CM CM CM CM
+1103 3 1433 1434 1435 1436 # CM CM CM CM
+1104 4 1434 1435 1436 1437 # CM CM CM CM
+1105 5 1435 1436 1437 1438 # CM CM CM CM
+1106 6 1436 1437 1438 1439 # CM CM CM CM
+1107 7 1437 1438 1439 1440 # CM CM CM CM
+1108 8 1438 1439 1440 1441 # CM CM CM CM
+1109 9 1439 1440 1441 1442 # CM CM CM CM
+1110 10 1440 1441 1442 1443 # CM CM CM CT
+1111 1 1444 1445 1446 1447 # HG CM CM CM
+1112 2 1445 1446 1447 1448 # CM CM CM CM
+1113 3 1446 1447 1448 1449 # CM CM CM CM
+1114 4 1447 1448 1449 1450 # CM CM CM CM
+1115 5 1448 1449 1450 1451 # CM CM CM CM
+1116 6 1449 1450 1451 1452 # CM CM CM CM
+1117 7 1450 1451 1452 1453 # CM CM CM CM
+1118 8 1451 1452 1453 1454 # CM CM CM CM
+1119 9 1452 1453 1454 1455 # CM CM CM CM
+1120 10 1453 1454 1455 1456 # CM CM CM CT
+1121 1 1457 1458 1459 1460 # HG CM CM CM
+1122 2 1458 1459 1460 1461 # CM CM CM CM
+1123 3 1459 1460 1461 1462 # CM CM CM CM
+1124 4 1460 1461 1462 1463 # CM CM CM CM
+1125 5 1461 1462 1463 1464 # CM CM CM CM
+1126 6 1462 1463 1464 1465 # CM CM CM CM
+1127 7 1463 1464 1465 1466 # CM CM CM CM
+1128 8 1464 1465 1466 1467 # CM CM CM CM
+1129 9 1465 1466 1467 1468 # CM CM CM CM
+1130 10 1466 1467 1468 1469 # CM CM CM CT
+1131 1 1470 1471 1472 1473 # HG CM CM CM
+1132 2 1471 1472 1473 1474 # CM CM CM CM
+1133 3 1472 1473 1474 1475 # CM CM CM CM
+1134 4 1473 1474 1475 1476 # CM CM CM CM
+1135 5 1474 1475 1476 1477 # CM CM CM CM
+1136 6 1475 1476 1477 1478 # CM CM CM CM
+1137 7 1476 1477 1478 1479 # CM CM CM CM
+1138 8 1477 1478 1479 1480 # CM CM CM CM
+1139 9 1478 1479 1480 1481 # CM CM CM CM
+1140 10 1479 1480 1481 1482 # CM CM CM CT
+1141 1 1483 1484 1485 1486 # HG CM CM CM
+1142 2 1484 1485 1486 1487 # CM CM CM CM
+1143 3 1485 1486 1487 1488 # CM CM CM CM
+1144 4 1486 1487 1488 1489 # CM CM CM CM
+1145 5 1487 1488 1489 1490 # CM CM CM CM
+1146 6 1488 1489 1490 1491 # CM CM CM CM
+1147 7 1489 1490 1491 1492 # CM CM CM CM
+1148 8 1490 1491 1492 1493 # CM CM CM CM
+1149 9 1491 1492 1493 1494 # CM CM CM CM
+1150 10 1492 1493 1494 1495 # CM CM CM CT
+1151 1 1496 1497 1498 1499 # HG CM CM CM
+1152 2 1497 1498 1499 1500 # CM CM CM CM
+1153 3 1498 1499 1500 1501 # CM CM CM CM
+1154 4 1499 1500 1501 1502 # CM CM CM CM
+1155 5 1500 1501 1502 1503 # CM CM CM CM
+1156 6 1501 1502 1503 1504 # CM CM CM CM
+1157 7 1502 1503 1504 1505 # CM CM CM CM
+1158 8 1503 1504 1505 1506 # CM CM CM CM
+1159 9 1504 1505 1506 1507 # CM CM CM CM
+1160 10 1505 1506 1507 1508 # CM CM CM CT
+1161 1 1509 1510 1511 1512 # HG CM CM CM
+1162 2 1510 1511 1512 1513 # CM CM CM CM
+1163 3 1511 1512 1513 1514 # CM CM CM CM
+1164 4 1512 1513 1514 1515 # CM CM CM CM
+1165 5 1513 1514 1515 1516 # CM CM CM CM
+1166 6 1514 1515 1516 1517 # CM CM CM CM
+1167 7 1515 1516 1517 1518 # CM CM CM CM
+1168 8 1516 1517 1518 1519 # CM CM CM CM
+1169 9 1517 1518 1519 1520 # CM CM CM CM
+1170 10 1518 1519 1520 1521 # CM CM CM CT
+1171 1 1522 1523 1524 1525 # HG CM CM CM
+1172 2 1523 1524 1525 1526 # CM CM CM CM
+1173 3 1524 1525 1526 1527 # CM CM CM CM
+1174 4 1525 1526 1527 1528 # CM CM CM CM
+1175 5 1526 1527 1528 1529 # CM CM CM CM
+1176 6 1527 1528 1529 1530 # CM CM CM CM
+1177 7 1528 1529 1530 1531 # CM CM CM CM
+1178 8 1529 1530 1531 1532 # CM CM CM CM
+1179 9 1530 1531 1532 1533 # CM CM CM CM
+1180 10 1531 1532 1533 1534 # CM CM CM CT
+1181 1 1535 1536 1537 1538 # HG CM CM CM
+1182 2 1536 1537 1538 1539 # CM CM CM CM
+1183 3 1537 1538 1539 1540 # CM CM CM CM
+1184 4 1538 1539 1540 1541 # CM CM CM CM
+1185 5 1539 1540 1541 1542 # CM CM CM CM
+1186 6 1540 1541 1542 1543 # CM CM CM CM
+1187 7 1541 1542 1543 1544 # CM CM CM CM
+1188 8 1542 1543 1544 1545 # CM CM CM CM
+1189 9 1543 1544 1545 1546 # CM CM CM CM
+1190 10 1544 1545 1546 1547 # CM CM CM CT
+1191 1 1548 1549 1550 1551 # HG CM CM CM
+1192 2 1549 1550 1551 1552 # CM CM CM CM
+1193 3 1550 1551 1552 1553 # CM CM CM CM
+1194 4 1551 1552 1553 1554 # CM CM CM CM
+1195 5 1552 1553 1554 1555 # CM CM CM CM
+1196 6 1553 1554 1555 1556 # CM CM CM CM
+1197 7 1554 1555 1556 1557 # CM CM CM CM
+1198 8 1555 1556 1557 1558 # CM CM CM CM
+1199 9 1556 1557 1558 1559 # CM CM CM CM
+1200 10 1557 1558 1559 1560 # CM CM CM CT
+1201 1 1561 1562 1563 1564 # HG CM CM CM
+1202 2 1562 1563 1564 1565 # CM CM CM CM
+1203 3 1563 1564 1565 1566 # CM CM CM CM
+1204 4 1564 1565 1566 1567 # CM CM CM CM
+1205 5 1565 1566 1567 1568 # CM CM CM CM
+1206 6 1566 1567 1568 1569 # CM CM CM CM
+1207 7 1567 1568 1569 1570 # CM CM CM CM
+1208 8 1568 1569 1570 1571 # CM CM CM CM
+1209 9 1569 1570 1571 1572 # CM CM CM CM
+1210 10 1570 1571 1572 1573 # CM CM CM CT
+1211 1 1574 1575 1576 1577 # HG CM CM CM
+1212 2 1575 1576 1577 1578 # CM CM CM CM
+1213 3 1576 1577 1578 1579 # CM CM CM CM
+1214 4 1577 1578 1579 1580 # CM CM CM CM
+1215 5 1578 1579 1580 1581 # CM CM CM CM
+1216 6 1579 1580 1581 1582 # CM CM CM CM
+1217 7 1580 1581 1582 1583 # CM CM CM CM
+1218 8 1581 1582 1583 1584 # CM CM CM CM
+1219 9 1582 1583 1584 1585 # CM CM CM CM
+1220 10 1583 1584 1585 1586 # CM CM CM CT
+1221 1 1587 1588 1589 1590 # HG CM CM CM
+1222 2 1588 1589 1590 1591 # CM CM CM CM
+1223 3 1589 1590 1591 1592 # CM CM CM CM
+1224 4 1590 1591 1592 1593 # CM CM CM CM
+1225 5 1591 1592 1593 1594 # CM CM CM CM
+1226 6 1592 1593 1594 1595 # CM CM CM CM
+1227 7 1593 1594 1595 1596 # CM CM CM CM
+1228 8 1594 1595 1596 1597 # CM CM CM CM
+1229 9 1595 1596 1597 1598 # CM CM CM CM
+1230 10 1596 1597 1598 1599 # CM CM CM CT
+1231 1 1600 1601 1602 1603 # HG CM CM CM
+1232 2 1601 1602 1603 1604 # CM CM CM CM
+1233 3 1602 1603 1604 1605 # CM CM CM CM
+1234 4 1603 1604 1605 1606 # CM CM CM CM
+1235 5 1604 1605 1606 1607 # CM CM CM CM
+1236 6 1605 1606 1607 1608 # CM CM CM CM
+1237 7 1606 1607 1608 1609 # CM CM CM CM
+1238 8 1607 1608 1609 1610 # CM CM CM CM
+1239 9 1608 1609 1610 1611 # CM CM CM CM
+1240 10 1609 1610 1611 1612 # CM CM CM CT
+1241 1 1613 1614 1615 1616 # HG CM CM CM
+1242 2 1614 1615 1616 1617 # CM CM CM CM
+1243 3 1615 1616 1617 1618 # CM CM CM CM
+1244 4 1616 1617 1618 1619 # CM CM CM CM
+1245 5 1617 1618 1619 1620 # CM CM CM CM
+1246 6 1618 1619 1620 1621 # CM CM CM CM
+1247 7 1619 1620 1621 1622 # CM CM CM CM
+1248 8 1620 1621 1622 1623 # CM CM CM CM
+1249 9 1621 1622 1623 1624 # CM CM CM CM
+1250 10 1622 1623 1624 1625 # CM CM CM CT
+1251 1 1626 1627 1628 1629 # HG CM CM CM
+1252 2 1627 1628 1629 1630 # CM CM CM CM
+1253 3 1628 1629 1630 1631 # CM CM CM CM
+1254 4 1629 1630 1631 1632 # CM CM CM CM
+1255 5 1630 1631 1632 1633 # CM CM CM CM
+1256 6 1631 1632 1633 1634 # CM CM CM CM
+1257 7 1632 1633 1634 1635 # CM CM CM CM
+1258 8 1633 1634 1635 1636 # CM CM CM CM
+1259 9 1634 1635 1636 1637 # CM CM CM CM
+1260 10 1635 1636 1637 1638 # CM CM CM CT
+1261 1 1639 1640 1641 1642 # HG CM CM CM
+1262 2 1640 1641 1642 1643 # CM CM CM CM
+1263 3 1641 1642 1643 1644 # CM CM CM CM
+1264 4 1642 1643 1644 1645 # CM CM CM CM
+1265 5 1643 1644 1645 1646 # CM CM CM CM
+1266 6 1644 1645 1646 1647 # CM CM CM CM
+1267 7 1645 1646 1647 1648 # CM CM CM CM
+1268 8 1646 1647 1648 1649 # CM CM CM CM
+1269 9 1647 1648 1649 1650 # CM CM CM CM
+1270 10 1648 1649 1650 1651 # CM CM CM CT
+1271 1 1652 1653 1654 1655 # HG CM CM CM
+1272 2 1653 1654 1655 1656 # CM CM CM CM
+1273 3 1654 1655 1656 1657 # CM CM CM CM
+1274 4 1655 1656 1657 1658 # CM CM CM CM
+1275 5 1656 1657 1658 1659 # CM CM CM CM
+1276 6 1657 1658 1659 1660 # CM CM CM CM
+1277 7 1658 1659 1660 1661 # CM CM CM CM
+1278 8 1659 1660 1661 1662 # CM CM CM CM
+1279 9 1660 1661 1662 1663 # CM CM CM CM
+1280 10 1661 1662 1663 1664 # CM CM CM CT
+1281 1 1665 1666 1667 1668 # HG CM CM CM
+1282 2 1666 1667 1668 1669 # CM CM CM CM
+1283 3 1667 1668 1669 1670 # CM CM CM CM
+1284 4 1668 1669 1670 1671 # CM CM CM CM
+1285 5 1669 1670 1671 1672 # CM CM CM CM
+1286 6 1670 1671 1672 1673 # CM CM CM CM
+1287 7 1671 1672 1673 1674 # CM CM CM CM
+1288 8 1672 1673 1674 1675 # CM CM CM CM
+1289 9 1673 1674 1675 1676 # CM CM CM CM
+1290 10 1674 1675 1676 1677 # CM CM CM CT
+1291 1 1678 1679 1680 1681 # HG CM CM CM
+1292 2 1679 1680 1681 1682 # CM CM CM CM
+1293 3 1680 1681 1682 1683 # CM CM CM CM
+1294 4 1681 1682 1683 1684 # CM CM CM CM
+1295 5 1682 1683 1684 1685 # CM CM CM CM
+1296 6 1683 1684 1685 1686 # CM CM CM CM
+1297 7 1684 1685 1686 1687 # CM CM CM CM
+1298 8 1685 1686 1687 1688 # CM CM CM CM
+1299 9 1686 1687 1688 1689 # CM CM CM CM
+1300 10 1687 1688 1689 1690 # CM CM CM CT
+1301 1 1691 1692 1693 1694 # HG CM CM CM
+1302 2 1692 1693 1694 1695 # CM CM CM CM
+1303 3 1693 1694 1695 1696 # CM CM CM CM
+1304 4 1694 1695 1696 1697 # CM CM CM CM
+1305 5 1695 1696 1697 1698 # CM CM CM CM
+1306 6 1696 1697 1698 1699 # CM CM CM CM
+1307 7 1697 1698 1699 1700 # CM CM CM CM
+1308 8 1698 1699 1700 1701 # CM CM CM CM
+1309 9 1699 1700 1701 1702 # CM CM CM CM
+1310 10 1700 1701 1702 1703 # CM CM CM CT
+1311 1 1704 1705 1706 1707 # HG CM CM CM
+1312 2 1705 1706 1707 1708 # CM CM CM CM
+1313 3 1706 1707 1708 1709 # CM CM CM CM
+1314 4 1707 1708 1709 1710 # CM CM CM CM
+1315 5 1708 1709 1710 1711 # CM CM CM CM
+1316 6 1709 1710 1711 1712 # CM CM CM CM
+1317 7 1710 1711 1712 1713 # CM CM CM CM
+1318 8 1711 1712 1713 1714 # CM CM CM CM
+1319 9 1712 1713 1714 1715 # CM CM CM CM
+1320 10 1713 1714 1715 1716 # CM CM CM CT
+1321 1 1717 1718 1719 1720 # HG CM CM CM
+1322 2 1718 1719 1720 1721 # CM CM CM CM
+1323 3 1719 1720 1721 1722 # CM CM CM CM
+1324 4 1720 1721 1722 1723 # CM CM CM CM
+1325 5 1721 1722 1723 1724 # CM CM CM CM
+1326 6 1722 1723 1724 1725 # CM CM CM CM
+1327 7 1723 1724 1725 1726 # CM CM CM CM
+1328 8 1724 1725 1726 1727 # CM CM CM CM
+1329 9 1725 1726 1727 1728 # CM CM CM CM
+1330 10 1726 1727 1728 1729 # CM CM CM CT
+1331 1 1730 1731 1732 1733 # HG CM CM CM
+1332 2 1731 1732 1733 1734 # CM CM CM CM
+1333 3 1732 1733 1734 1735 # CM CM CM CM
+1334 4 1733 1734 1735 1736 # CM CM CM CM
+1335 5 1734 1735 1736 1737 # CM CM CM CM
+1336 6 1735 1736 1737 1738 # CM CM CM CM
+1337 7 1736 1737 1738 1739 # CM CM CM CM
+1338 8 1737 1738 1739 1740 # CM CM CM CM
+1339 9 1738 1739 1740 1741 # CM CM CM CM
+1340 10 1739 1740 1741 1742 # CM CM CM CT
+1341 1 1743 1744 1745 1746 # HG CM CM CM
+1342 2 1744 1745 1746 1747 # CM CM CM CM
+1343 3 1745 1746 1747 1748 # CM CM CM CM
+1344 4 1746 1747 1748 1749 # CM CM CM CM
+1345 5 1747 1748 1749 1750 # CM CM CM CM
+1346 6 1748 1749 1750 1751 # CM CM CM CM
+1347 7 1749 1750 1751 1752 # CM CM CM CM
+1348 8 1750 1751 1752 1753 # CM CM CM CM
+1349 9 1751 1752 1753 1754 # CM CM CM CM
+1350 10 1752 1753 1754 1755 # CM CM CM CT
+1351 1 1756 1757 1758 1759 # HG CM CM CM
+1352 2 1757 1758 1759 1760 # CM CM CM CM
+1353 3 1758 1759 1760 1761 # CM CM CM CM
+1354 4 1759 1760 1761 1762 # CM CM CM CM
+1355 5 1760 1761 1762 1763 # CM CM CM CM
+1356 6 1761 1762 1763 1764 # CM CM CM CM
+1357 7 1762 1763 1764 1765 # CM CM CM CM
+1358 8 1763 1764 1765 1766 # CM CM CM CM
+1359 9 1764 1765 1766 1767 # CM CM CM CM
+1360 10 1765 1766 1767 1768 # CM CM CM CT
+1361 1 1769 1770 1771 1772 # HG CM CM CM
+1362 2 1770 1771 1772 1773 # CM CM CM CM
+1363 3 1771 1772 1773 1774 # CM CM CM CM
+1364 4 1772 1773 1774 1775 # CM CM CM CM
+1365 5 1773 1774 1775 1776 # CM CM CM CM
+1366 6 1774 1775 1776 1777 # CM CM CM CM
+1367 7 1775 1776 1777 1778 # CM CM CM CM
+1368 8 1776 1777 1778 1779 # CM CM CM CM
+1369 9 1777 1778 1779 1780 # CM CM CM CM
+1370 10 1778 1779 1780 1781 # CM CM CM CT
+1371 1 1782 1783 1784 1785 # HG CM CM CM
+1372 2 1783 1784 1785 1786 # CM CM CM CM
+1373 3 1784 1785 1786 1787 # CM CM CM CM
+1374 4 1785 1786 1787 1788 # CM CM CM CM
+1375 5 1786 1787 1788 1789 # CM CM CM CM
+1376 6 1787 1788 1789 1790 # CM CM CM CM
+1377 7 1788 1789 1790 1791 # CM CM CM CM
+1378 8 1789 1790 1791 1792 # CM CM CM CM
+1379 9 1790 1791 1792 1793 # CM CM CM CM
+1380 10 1791 1792 1793 1794 # CM CM CM CT
+1381 1 1795 1796 1797 1798 # HG CM CM CM
+1382 2 1796 1797 1798 1799 # CM CM CM CM
+1383 3 1797 1798 1799 1800 # CM CM CM CM
+1384 4 1798 1799 1800 1801 # CM CM CM CM
+1385 5 1799 1800 1801 1802 # CM CM CM CM
+1386 6 1800 1801 1802 1803 # CM CM CM CM
+1387 7 1801 1802 1803 1804 # CM CM CM CM
+1388 8 1802 1803 1804 1805 # CM CM CM CM
+1389 9 1803 1804 1805 1806 # CM CM CM CM
+1390 10 1804 1805 1806 1807 # CM CM CM CT
+1391 1 1808 1809 1810 1811 # HG CM CM CM
+1392 2 1809 1810 1811 1812 # CM CM CM CM
+1393 3 1810 1811 1812 1813 # CM CM CM CM
+1394 4 1811 1812 1813 1814 # CM CM CM CM
+1395 5 1812 1813 1814 1815 # CM CM CM CM
+1396 6 1813 1814 1815 1816 # CM CM CM CM
+1397 7 1814 1815 1816 1817 # CM CM CM CM
+1398 8 1815 1816 1817 1818 # CM CM CM CM
+1399 9 1816 1817 1818 1819 # CM CM CM CM
+1400 10 1817 1818 1819 1820 # CM CM CM CT
+1401 1 1821 1822 1823 1824 # HG CM CM CM
+1402 2 1822 1823 1824 1825 # CM CM CM CM
+1403 3 1823 1824 1825 1826 # CM CM CM CM
+1404 4 1824 1825 1826 1827 # CM CM CM CM
+1405 5 1825 1826 1827 1828 # CM CM CM CM
+1406 6 1826 1827 1828 1829 # CM CM CM CM
+1407 7 1827 1828 1829 1830 # CM CM CM CM
+1408 8 1828 1829 1830 1831 # CM CM CM CM
+1409 9 1829 1830 1831 1832 # CM CM CM CM
+1410 10 1830 1831 1832 1833 # CM CM CM CT
+1411 1 1834 1835 1836 1837 # HG CM CM CM
+1412 2 1835 1836 1837 1838 # CM CM CM CM
+1413 3 1836 1837 1838 1839 # CM CM CM CM
+1414 4 1837 1838 1839 1840 # CM CM CM CM
+1415 5 1838 1839 1840 1841 # CM CM CM CM
+1416 6 1839 1840 1841 1842 # CM CM CM CM
+1417 7 1840 1841 1842 1843 # CM CM CM CM
+1418 8 1841 1842 1843 1844 # CM CM CM CM
+1419 9 1842 1843 1844 1845 # CM CM CM CM
+1420 10 1843 1844 1845 1846 # CM CM CM CT
+1421 1 1847 1848 1849 1850 # HG CM CM CM
+1422 2 1848 1849 1850 1851 # CM CM CM CM
+1423 3 1849 1850 1851 1852 # CM CM CM CM
+1424 4 1850 1851 1852 1853 # CM CM CM CM
+1425 5 1851 1852 1853 1854 # CM CM CM CM
+1426 6 1852 1853 1854 1855 # CM CM CM CM
+1427 7 1853 1854 1855 1856 # CM CM CM CM
+1428 8 1854 1855 1856 1857 # CM CM CM CM
+1429 9 1855 1856 1857 1858 # CM CM CM CM
+1430 10 1856 1857 1858 1859 # CM CM CM CT
+1431 1 1860 1861 1862 1863 # HG CM CM CM
+1432 2 1861 1862 1863 1864 # CM CM CM CM
+1433 3 1862 1863 1864 1865 # CM CM CM CM
+1434 4 1863 1864 1865 1866 # CM CM CM CM
+1435 5 1864 1865 1866 1867 # CM CM CM CM
+1436 6 1865 1866 1867 1868 # CM CM CM CM
+1437 7 1866 1867 1868 1869 # CM CM CM CM
+1438 8 1867 1868 1869 1870 # CM CM CM CM
+1439 9 1868 1869 1870 1871 # CM CM CM CM
+1440 10 1869 1870 1871 1872 # CM CM CM CT
+1441 1 1873 1874 1875 1876 # HG CM CM CM
+1442 2 1874 1875 1876 1877 # CM CM CM CM
+1443 3 1875 1876 1877 1878 # CM CM CM CM
+1444 4 1876 1877 1878 1879 # CM CM CM CM
+1445 5 1877 1878 1879 1880 # CM CM CM CM
+1446 6 1878 1879 1880 1881 # CM CM CM CM
+1447 7 1879 1880 1881 1882 # CM CM CM CM
+1448 8 1880 1881 1882 1883 # CM CM CM CM
+1449 9 1881 1882 1883 1884 # CM CM CM CM
+1450 10 1882 1883 1884 1885 # CM CM CM CT
+1451 1 1886 1887 1888 1889 # HG CM CM CM
+1452 2 1887 1888 1889 1890 # CM CM CM CM
+1453 3 1888 1889 1890 1891 # CM CM CM CM
+1454 4 1889 1890 1891 1892 # CM CM CM CM
+1455 5 1890 1891 1892 1893 # CM CM CM CM
+1456 6 1891 1892 1893 1894 # CM CM CM CM
+1457 7 1892 1893 1894 1895 # CM CM CM CM
+1458 8 1893 1894 1895 1896 # CM CM CM CM
+1459 9 1894 1895 1896 1897 # CM CM CM CM
+1460 10 1895 1896 1897 1898 # CM CM CM CT
+1461 1 1899 1900 1901 1902 # HG CM CM CM
+1462 2 1900 1901 1902 1903 # CM CM CM CM
+1463 3 1901 1902 1903 1904 # CM CM CM CM
+1464 4 1902 1903 1904 1905 # CM CM CM CM
+1465 5 1903 1904 1905 1906 # CM CM CM CM
+1466 6 1904 1905 1906 1907 # CM CM CM CM
+1467 7 1905 1906 1907 1908 # CM CM CM CM
+1468 8 1906 1907 1908 1909 # CM CM CM CM
+1469 9 1907 1908 1909 1910 # CM CM CM CM
+1470 10 1908 1909 1910 1911 # CM CM CM CT
+1471 1 1912 1913 1914 1915 # HG CM CM CM
+1472 2 1913 1914 1915 1916 # CM CM CM CM
+1473 3 1914 1915 1916 1917 # CM CM CM CM
+1474 4 1915 1916 1917 1918 # CM CM CM CM
+1475 5 1916 1917 1918 1919 # CM CM CM CM
+1476 6 1917 1918 1919 1920 # CM CM CM CM
+1477 7 1918 1919 1920 1921 # CM CM CM CM
+1478 8 1919 1920 1921 1922 # CM CM CM CM
+1479 9 1920 1921 1922 1923 # CM CM CM CM
+1480 10 1921 1922 1923 1924 # CM CM CM CT
+1481 1 1925 1926 1927 1928 # HG CM CM CM
+1482 2 1926 1927 1928 1929 # CM CM CM CM
+1483 3 1927 1928 1929 1930 # CM CM CM CM
+1484 4 1928 1929 1930 1931 # CM CM CM CM
+1485 5 1929 1930 1931 1932 # CM CM CM CM
+1486 6 1930 1931 1932 1933 # CM CM CM CM
+1487 7 1931 1932 1933 1934 # CM CM CM CM
+1488 8 1932 1933 1934 1935 # CM CM CM CM
+1489 9 1933 1934 1935 1936 # CM CM CM CM
+1490 10 1934 1935 1936 1937 # CM CM CM CT
+1491 1 1938 1939 1940 1941 # HG CM CM CM
+1492 2 1939 1940 1941 1942 # CM CM CM CM
+1493 3 1940 1941 1942 1943 # CM CM CM CM
+1494 4 1941 1942 1943 1944 # CM CM CM CM
+1495 5 1942 1943 1944 1945 # CM CM CM CM
+1496 6 1943 1944 1945 1946 # CM CM CM CM
+1497 7 1944 1945 1946 1947 # CM CM CM CM
+1498 8 1945 1946 1947 1948 # CM CM CM CM
+1499 9 1946 1947 1948 1949 # CM CM CM CM
+1500 10 1947 1948 1949 1950 # CM CM CM CT
+1501 1 1951 1952 1953 1954 # HG CM CM CM
+1502 2 1952 1953 1954 1955 # CM CM CM CM
+1503 3 1953 1954 1955 1956 # CM CM CM CM
+1504 4 1954 1955 1956 1957 # CM CM CM CM
+1505 5 1955 1956 1957 1958 # CM CM CM CM
+1506 6 1956 1957 1958 1959 # CM CM CM CM
+1507 7 1957 1958 1959 1960 # CM CM CM CM
+1508 8 1958 1959 1960 1961 # CM CM CM CM
+1509 9 1959 1960 1961 1962 # CM CM CM CM
+1510 10 1960 1961 1962 1963 # CM CM CM CT
+1511 1 1964 1965 1966 1967 # HG CM CM CM
+1512 2 1965 1966 1967 1968 # CM CM CM CM
+1513 3 1966 1967 1968 1969 # CM CM CM CM
+1514 4 1967 1968 1969 1970 # CM CM CM CM
+1515 5 1968 1969 1970 1971 # CM CM CM CM
+1516 6 1969 1970 1971 1972 # CM CM CM CM
+1517 7 1970 1971 1972 1973 # CM CM CM CM
+1518 8 1971 1972 1973 1974 # CM CM CM CM
+1519 9 1972 1973 1974 1975 # CM CM CM CM
+1520 10 1973 1974 1975 1976 # CM CM CM CT
+1521 1 1977 1978 1979 1980 # HG CM CM CM
+1522 2 1978 1979 1980 1981 # CM CM CM CM
+1523 3 1979 1980 1981 1982 # CM CM CM CM
+1524 4 1980 1981 1982 1983 # CM CM CM CM
+1525 5 1981 1982 1983 1984 # CM CM CM CM
+1526 6 1982 1983 1984 1985 # CM CM CM CM
+1527 7 1983 1984 1985 1986 # CM CM CM CM
+1528 8 1984 1985 1986 1987 # CM CM CM CM
+1529 9 1985 1986 1987 1988 # CM CM CM CM
+1530 10 1986 1987 1988 1989 # CM CM CM CT
+1531 1 1990 1991 1992 1993 # HG CM CM CM
+1532 2 1991 1992 1993 1994 # CM CM CM CM
+1533 3 1992 1993 1994 1995 # CM CM CM CM
+1534 4 1993 1994 1995 1996 # CM CM CM CM
+1535 5 1994 1995 1996 1997 # CM CM CM CM
+1536 6 1995 1996 1997 1998 # CM CM CM CM
+1537 7 1996 1997 1998 1999 # CM CM CM CM
+1538 8 1997 1998 1999 2000 # CM CM CM CM
+1539 9 1998 1999 2000 2001 # CM CM CM CM
+1540 10 1999 2000 2001 2002 # CM CM CM CT
+1541 1 2003 2004 2005 2006 # HG CM CM CM
+1542 2 2004 2005 2006 2007 # CM CM CM CM
+1543 3 2005 2006 2007 2008 # CM CM CM CM
+1544 4 2006 2007 2008 2009 # CM CM CM CM
+1545 5 2007 2008 2009 2010 # CM CM CM CM
+1546 6 2008 2009 2010 2011 # CM CM CM CM
+1547 7 2009 2010 2011 2012 # CM CM CM CM
+1548 8 2010 2011 2012 2013 # CM CM CM CM
+1549 9 2011 2012 2013 2014 # CM CM CM CM
+1550 10 2012 2013 2014 2015 # CM CM CM CT
+1551 1 2016 2017 2018 2019 # HG CM CM CM
+1552 2 2017 2018 2019 2020 # CM CM CM CM
+1553 3 2018 2019 2020 2021 # CM CM CM CM
+1554 4 2019 2020 2021 2022 # CM CM CM CM
+1555 5 2020 2021 2022 2023 # CM CM CM CM
+1556 6 2021 2022 2023 2024 # CM CM CM CM
+1557 7 2022 2023 2024 2025 # CM CM CM CM
+1558 8 2023 2024 2025 2026 # CM CM CM CM
+1559 9 2024 2025 2026 2027 # CM CM CM CM
+1560 10 2025 2026 2027 2028 # CM CM CM CT
+1561 1 2029 2030 2031 2032 # HG CM CM CM
+1562 2 2030 2031 2032 2033 # CM CM CM CM
+1563 3 2031 2032 2033 2034 # CM CM CM CM
+1564 4 2032 2033 2034 2035 # CM CM CM CM
+1565 5 2033 2034 2035 2036 # CM CM CM CM
+1566 6 2034 2035 2036 2037 # CM CM CM CM
+1567 7 2035 2036 2037 2038 # CM CM CM CM
+1568 8 2036 2037 2038 2039 # CM CM CM CM
+1569 9 2037 2038 2039 2040 # CM CM CM CM
+1570 10 2038 2039 2040 2041 # CM CM CM CT
+1571 1 2042 2043 2044 2045 # HG CM CM CM
+1572 2 2043 2044 2045 2046 # CM CM CM CM
+1573 3 2044 2045 2046 2047 # CM CM CM CM
+1574 4 2045 2046 2047 2048 # CM CM CM CM
+1575 5 2046 2047 2048 2049 # CM CM CM CM
+1576 6 2047 2048 2049 2050 # CM CM CM CM
+1577 7 2048 2049 2050 2051 # CM CM CM CM
+1578 8 2049 2050 2051 2052 # CM CM CM CM
+1579 9 2050 2051 2052 2053 # CM CM CM CM
+1580 10 2051 2052 2053 2054 # CM CM CM CT
+1581 1 2055 2056 2057 2058 # HG CM CM CM
+1582 2 2056 2057 2058 2059 # CM CM CM CM
+1583 3 2057 2058 2059 2060 # CM CM CM CM
+1584 4 2058 2059 2060 2061 # CM CM CM CM
+1585 5 2059 2060 2061 2062 # CM CM CM CM
+1586 6 2060 2061 2062 2063 # CM CM CM CM
+1587 7 2061 2062 2063 2064 # CM CM CM CM
+1588 8 2062 2063 2064 2065 # CM CM CM CM
+1589 9 2063 2064 2065 2066 # CM CM CM CM
+1590 10 2064 2065 2066 2067 # CM CM CM CT
+1591 1 2068 2069 2070 2071 # HG CM CM CM
+1592 2 2069 2070 2071 2072 # CM CM CM CM
+1593 3 2070 2071 2072 2073 # CM CM CM CM
+1594 4 2071 2072 2073 2074 # CM CM CM CM
+1595 5 2072 2073 2074 2075 # CM CM CM CM
+1596 6 2073 2074 2075 2076 # CM CM CM CM
+1597 7 2074 2075 2076 2077 # CM CM CM CM
+1598 8 2075 2076 2077 2078 # CM CM CM CM
+1599 9 2076 2077 2078 2079 # CM CM CM CM
+1600 10 2077 2078 2079 2080 # CM CM CM CT
+1601 1 2081 2082 2083 2084 # HG CM CM CM
+1602 2 2082 2083 2084 2085 # CM CM CM CM
+1603 3 2083 2084 2085 2086 # CM CM CM CM
+1604 4 2084 2085 2086 2087 # CM CM CM CM
+1605 5 2085 2086 2087 2088 # CM CM CM CM
+1606 6 2086 2087 2088 2089 # CM CM CM CM
+1607 7 2087 2088 2089 2090 # CM CM CM CM
+1608 8 2088 2089 2090 2091 # CM CM CM CM
+1609 9 2089 2090 2091 2092 # CM CM CM CM
+1610 10 2090 2091 2092 2093 # CM CM CM CT
+1611 1 2094 2095 2096 2097 # HG CM CM CM
+1612 2 2095 2096 2097 2098 # CM CM CM CM
+1613 3 2096 2097 2098 2099 # CM CM CM CM
+1614 4 2097 2098 2099 2100 # CM CM CM CM
+1615 5 2098 2099 2100 2101 # CM CM CM CM
+1616 6 2099 2100 2101 2102 # CM CM CM CM
+1617 7 2100 2101 2102 2103 # CM CM CM CM
+1618 8 2101 2102 2103 2104 # CM CM CM CM
+1619 9 2102 2103 2104 2105 # CM CM CM CM
+1620 10 2103 2104 2105 2106 # CM CM CM CT
+1621 1 2107 2108 2109 2110 # HG CM CM CM
+1622 2 2108 2109 2110 2111 # CM CM CM CM
+1623 3 2109 2110 2111 2112 # CM CM CM CM
+1624 4 2110 2111 2112 2113 # CM CM CM CM
+1625 5 2111 2112 2113 2114 # CM CM CM CM
+1626 6 2112 2113 2114 2115 # CM CM CM CM
+1627 7 2113 2114 2115 2116 # CM CM CM CM
+1628 8 2114 2115 2116 2117 # CM CM CM CM
+1629 9 2115 2116 2117 2118 # CM CM CM CM
+1630 10 2116 2117 2118 2119 # CM CM CM CT
+1631 1 2120 2121 2122 2123 # HG CM CM CM
+1632 2 2121 2122 2123 2124 # CM CM CM CM
+1633 3 2122 2123 2124 2125 # CM CM CM CM
+1634 4 2123 2124 2125 2126 # CM CM CM CM
+1635 5 2124 2125 2126 2127 # CM CM CM CM
+1636 6 2125 2126 2127 2128 # CM CM CM CM
+1637 7 2126 2127 2128 2129 # CM CM CM CM
+1638 8 2127 2128 2129 2130 # CM CM CM CM
+1639 9 2128 2129 2130 2131 # CM CM CM CM
+1640 10 2129 2130 2131 2132 # CM CM CM CT
+1641 1 2133 2134 2135 2136 # HG CM CM CM
+1642 2 2134 2135 2136 2137 # CM CM CM CM
+1643 3 2135 2136 2137 2138 # CM CM CM CM
+1644 4 2136 2137 2138 2139 # CM CM CM CM
+1645 5 2137 2138 2139 2140 # CM CM CM CM
+1646 6 2138 2139 2140 2141 # CM CM CM CM
+1647 7 2139 2140 2141 2142 # CM CM CM CM
+1648 8 2140 2141 2142 2143 # CM CM CM CM
+1649 9 2141 2142 2143 2144 # CM CM CM CM
+1650 10 2142 2143 2144 2145 # CM CM CM CT
+1651 1 2146 2147 2148 2149 # HG CM CM CM
+1652 2 2147 2148 2149 2150 # CM CM CM CM
+1653 3 2148 2149 2150 2151 # CM CM CM CM
+1654 4 2149 2150 2151 2152 # CM CM CM CM
+1655 5 2150 2151 2152 2153 # CM CM CM CM
+1656 6 2151 2152 2153 2154 # CM CM CM CM
+1657 7 2152 2153 2154 2155 # CM CM CM CM
+1658 8 2153 2154 2155 2156 # CM CM CM CM
+1659 9 2154 2155 2156 2157 # CM CM CM CM
+1660 10 2155 2156 2157 2158 # CM CM CM CT
+1661 1 2159 2160 2161 2162 # HG CM CM CM
+1662 2 2160 2161 2162 2163 # CM CM CM CM
+1663 3 2161 2162 2163 2164 # CM CM CM CM
+1664 4 2162 2163 2164 2165 # CM CM CM CM
+1665 5 2163 2164 2165 2166 # CM CM CM CM
+1666 6 2164 2165 2166 2167 # CM CM CM CM
+1667 7 2165 2166 2167 2168 # CM CM CM CM
+1668 8 2166 2167 2168 2169 # CM CM CM CM
+1669 9 2167 2168 2169 2170 # CM CM CM CM
+1670 10 2168 2169 2170 2171 # CM CM CM CT
+1671 1 2172 2173 2174 2175 # HG CM CM CM
+1672 2 2173 2174 2175 2176 # CM CM CM CM
+1673 3 2174 2175 2176 2177 # CM CM CM CM
+1674 4 2175 2176 2177 2178 # CM CM CM CM
+1675 5 2176 2177 2178 2179 # CM CM CM CM
+1676 6 2177 2178 2179 2180 # CM CM CM CM
+1677 7 2178 2179 2180 2181 # CM CM CM CM
+1678 8 2179 2180 2181 2182 # CM CM CM CM
+1679 9 2180 2181 2182 2183 # CM CM CM CM
+1680 10 2181 2182 2183 2184 # CM CM CM CT
+1681 1 2185 2186 2187 2188 # HG CM CM CM
+1682 2 2186 2187 2188 2189 # CM CM CM CM
+1683 3 2187 2188 2189 2190 # CM CM CM CM
+1684 4 2188 2189 2190 2191 # CM CM CM CM
+1685 5 2189 2190 2191 2192 # CM CM CM CM
+1686 6 2190 2191 2192 2193 # CM CM CM CM
+1687 7 2191 2192 2193 2194 # CM CM CM CM
+1688 8 2192 2193 2194 2195 # CM CM CM CM
+1689 9 2193 2194 2195 2196 # CM CM CM CM
+1690 10 2194 2195 2196 2197 # CM CM CM CT
+1691 1 2198 2199 2200 2201 # HG CM CM CM
+1692 2 2199 2200 2201 2202 # CM CM CM CM
+1693 3 2200 2201 2202 2203 # CM CM CM CM
+1694 4 2201 2202 2203 2204 # CM CM CM CM
+1695 5 2202 2203 2204 2205 # CM CM CM CM
+1696 6 2203 2204 2205 2206 # CM CM CM CM
+1697 7 2204 2205 2206 2207 # CM CM CM CM
+1698 8 2205 2206 2207 2208 # CM CM CM CM
+1699 9 2206 2207 2208 2209 # CM CM CM CM
+1700 10 2207 2208 2209 2210 # CM CM CM CT
+1701 1 2211 2212 2213 2214 # HG CM CM CM
+1702 2 2212 2213 2214 2215 # CM CM CM CM
+1703 3 2213 2214 2215 2216 # CM CM CM CM
+1704 4 2214 2215 2216 2217 # CM CM CM CM
+1705 5 2215 2216 2217 2218 # CM CM CM CM
+1706 6 2216 2217 2218 2219 # CM CM CM CM
+1707 7 2217 2218 2219 2220 # CM CM CM CM
+1708 8 2218 2219 2220 2221 # CM CM CM CM
+1709 9 2219 2220 2221 2222 # CM CM CM CM
+1710 10 2220 2221 2222 2223 # CM CM CM CT
+1711 1 2224 2225 2226 2227 # HG CM CM CM
+1712 2 2225 2226 2227 2228 # CM CM CM CM
+1713 3 2226 2227 2228 2229 # CM CM CM CM
+1714 4 2227 2228 2229 2230 # CM CM CM CM
+1715 5 2228 2229 2230 2231 # CM CM CM CM
+1716 6 2229 2230 2231 2232 # CM CM CM CM
+1717 7 2230 2231 2232 2233 # CM CM CM CM
+1718 8 2231 2232 2233 2234 # CM CM CM CM
+1719 9 2232 2233 2234 2235 # CM CM CM CM
+1720 10 2233 2234 2235 2236 # CM CM CM CT
+1721 1 2237 2238 2239 2240 # HG CM CM CM
+1722 2 2238 2239 2240 2241 # CM CM CM CM
+1723 3 2239 2240 2241 2242 # CM CM CM CM
+1724 4 2240 2241 2242 2243 # CM CM CM CM
+1725 5 2241 2242 2243 2244 # CM CM CM CM
+1726 6 2242 2243 2244 2245 # CM CM CM CM
+1727 7 2243 2244 2245 2246 # CM CM CM CM
+1728 8 2244 2245 2246 2247 # CM CM CM CM
+1729 9 2245 2246 2247 2248 # CM CM CM CM
+1730 10 2246 2247 2248 2249 # CM CM CM CT
+1731 1 2250 2251 2252 2253 # HG CM CM CM
+1732 2 2251 2252 2253 2254 # CM CM CM CM
+1733 3 2252 2253 2254 2255 # CM CM CM CM
+1734 4 2253 2254 2255 2256 # CM CM CM CM
+1735 5 2254 2255 2256 2257 # CM CM CM CM
+1736 6 2255 2256 2257 2258 # CM CM CM CM
+1737 7 2256 2257 2258 2259 # CM CM CM CM
+1738 8 2257 2258 2259 2260 # CM CM CM CM
+1739 9 2258 2259 2260 2261 # CM CM CM CM
+1740 10 2259 2260 2261 2262 # CM CM CM CT
+1741 1 2263 2264 2265 2266 # HG CM CM CM
+1742 2 2264 2265 2266 2267 # CM CM CM CM
+1743 3 2265 2266 2267 2268 # CM CM CM CM
+1744 4 2266 2267 2268 2269 # CM CM CM CM
+1745 5 2267 2268 2269 2270 # CM CM CM CM
+1746 6 2268 2269 2270 2271 # CM CM CM CM
+1747 7 2269 2270 2271 2272 # CM CM CM CM
+1748 8 2270 2271 2272 2273 # CM CM CM CM
+1749 9 2271 2272 2273 2274 # CM CM CM CM
+1750 10 2272 2273 2274 2275 # CM CM CM CT
+1751 1 2276 2277 2278 2279 # HG CM CM CM
+1752 2 2277 2278 2279 2280 # CM CM CM CM
+1753 3 2278 2279 2280 2281 # CM CM CM CM
+1754 4 2279 2280 2281 2282 # CM CM CM CM
+1755 5 2280 2281 2282 2283 # CM CM CM CM
+1756 6 2281 2282 2283 2284 # CM CM CM CM
+1757 7 2282 2283 2284 2285 # CM CM CM CM
+1758 8 2283 2284 2285 2286 # CM CM CM CM
+1759 9 2284 2285 2286 2287 # CM CM CM CM
+1760 10 2285 2286 2287 2288 # CM CM CM CT
+1761 1 2289 2290 2291 2292 # HG CM CM CM
+1762 2 2290 2291 2292 2293 # CM CM CM CM
+1763 3 2291 2292 2293 2294 # CM CM CM CM
+1764 4 2292 2293 2294 2295 # CM CM CM CM
+1765 5 2293 2294 2295 2296 # CM CM CM CM
+1766 6 2294 2295 2296 2297 # CM CM CM CM
+1767 7 2295 2296 2297 2298 # CM CM CM CM
+1768 8 2296 2297 2298 2299 # CM CM CM CM
+1769 9 2297 2298 2299 2300 # CM CM CM CM
+1770 10 2298 2299 2300 2301 # CM CM CM CT
+1771 1 2302 2303 2304 2305 # HG CM CM CM
+1772 2 2303 2304 2305 2306 # CM CM CM CM
+1773 3 2304 2305 2306 2307 # CM CM CM CM
+1774 4 2305 2306 2307 2308 # CM CM CM CM
+1775 5 2306 2307 2308 2309 # CM CM CM CM
+1776 6 2307 2308 2309 2310 # CM CM CM CM
+1777 7 2308 2309 2310 2311 # CM CM CM CM
+1778 8 2309 2310 2311 2312 # CM CM CM CM
+1779 9 2310 2311 2312 2313 # CM CM CM CM
+1780 10 2311 2312 2313 2314 # CM CM CM CT
+1781 1 2315 2316 2317 2318 # HG CM CM CM
+1782 2 2316 2317 2318 2319 # CM CM CM CM
+1783 3 2317 2318 2319 2320 # CM CM CM CM
+1784 4 2318 2319 2320 2321 # CM CM CM CM
+1785 5 2319 2320 2321 2322 # CM CM CM CM
+1786 6 2320 2321 2322 2323 # CM CM CM CM
+1787 7 2321 2322 2323 2324 # CM CM CM CM
+1788 8 2322 2323 2324 2325 # CM CM CM CM
+1789 9 2323 2324 2325 2326 # CM CM CM CM
+1790 10 2324 2325 2326 2327 # CM CM CM CT
+1791 1 2328 2329 2330 2331 # HG CM CM CM
+1792 2 2329 2330 2331 2332 # CM CM CM CM
+1793 3 2330 2331 2332 2333 # CM CM CM CM
+1794 4 2331 2332 2333 2334 # CM CM CM CM
+1795 5 2332 2333 2334 2335 # CM CM CM CM
+1796 6 2333 2334 2335 2336 # CM CM CM CM
+1797 7 2334 2335 2336 2337 # CM CM CM CM
+1798 8 2335 2336 2337 2338 # CM CM CM CM
+1799 9 2336 2337 2338 2339 # CM CM CM CM
+1800 10 2337 2338 2339 2340 # CM CM CM CT
+1801 1 2341 2342 2343 2344 # HG CM CM CM
+1802 2 2342 2343 2344 2345 # CM CM CM CM
+1803 3 2343 2344 2345 2346 # CM CM CM CM
+1804 4 2344 2345 2346 2347 # CM CM CM CM
+1805 5 2345 2346 2347 2348 # CM CM CM CM
+1806 6 2346 2347 2348 2349 # CM CM CM CM
+1807 7 2347 2348 2349 2350 # CM CM CM CM
+1808 8 2348 2349 2350 2351 # CM CM CM CM
+1809 9 2349 2350 2351 2352 # CM CM CM CM
+1810 10 2350 2351 2352 2353 # CM CM CM CT
+1811 1 2354 2355 2356 2357 # HG CM CM CM
+1812 2 2355 2356 2357 2358 # CM CM CM CM
+1813 3 2356 2357 2358 2359 # CM CM CM CM
+1814 4 2357 2358 2359 2360 # CM CM CM CM
+1815 5 2358 2359 2360 2361 # CM CM CM CM
+1816 6 2359 2360 2361 2362 # CM CM CM CM
+1817 7 2360 2361 2362 2363 # CM CM CM CM
+1818 8 2361 2362 2363 2364 # CM CM CM CM
+1819 9 2362 2363 2364 2365 # CM CM CM CM
+1820 10 2363 2364 2365 2366 # CM CM CM CT
+1821 1 2367 2368 2369 2370 # HG CM CM CM
+1822 2 2368 2369 2370 2371 # CM CM CM CM
+1823 3 2369 2370 2371 2372 # CM CM CM CM
+1824 4 2370 2371 2372 2373 # CM CM CM CM
+1825 5 2371 2372 2373 2374 # CM CM CM CM
+1826 6 2372 2373 2374 2375 # CM CM CM CM
+1827 7 2373 2374 2375 2376 # CM CM CM CM
+1828 8 2374 2375 2376 2377 # CM CM CM CM
+1829 9 2375 2376 2377 2378 # CM CM CM CM
+1830 10 2376 2377 2378 2379 # CM CM CM CT
+1831 1 2380 2381 2382 2383 # HG CM CM CM
+1832 2 2381 2382 2383 2384 # CM CM CM CM
+1833 3 2382 2383 2384 2385 # CM CM CM CM
+1834 4 2383 2384 2385 2386 # CM CM CM CM
+1835 5 2384 2385 2386 2387 # CM CM CM CM
+1836 6 2385 2386 2387 2388 # CM CM CM CM
+1837 7 2386 2387 2388 2389 # CM CM CM CM
+1838 8 2387 2388 2389 2390 # CM CM CM CM
+1839 9 2388 2389 2390 2391 # CM CM CM CM
+1840 10 2389 2390 2391 2392 # CM CM CM CT
+1841 1 2393 2394 2395 2396 # HG CM CM CM
+1842 2 2394 2395 2396 2397 # CM CM CM CM
+1843 3 2395 2396 2397 2398 # CM CM CM CM
+1844 4 2396 2397 2398 2399 # CM CM CM CM
+1845 5 2397 2398 2399 2400 # CM CM CM CM
+1846 6 2398 2399 2400 2401 # CM CM CM CM
+1847 7 2399 2400 2401 2402 # CM CM CM CM
+1848 8 2400 2401 2402 2403 # CM CM CM CM
+1849 9 2401 2402 2403 2404 # CM CM CM CM
+1850 10 2402 2403 2404 2405 # CM CM CM CT
+1851 1 2406 2407 2408 2409 # HG CM CM CM
+1852 2 2407 2408 2409 2410 # CM CM CM CM
+1853 3 2408 2409 2410 2411 # CM CM CM CM
+1854 4 2409 2410 2411 2412 # CM CM CM CM
+1855 5 2410 2411 2412 2413 # CM CM CM CM
+1856 6 2411 2412 2413 2414 # CM CM CM CM
+1857 7 2412 2413 2414 2415 # CM CM CM CM
+1858 8 2413 2414 2415 2416 # CM CM CM CM
+1859 9 2414 2415 2416 2417 # CM CM CM CM
+1860 10 2415 2416 2417 2418 # CM CM CM CT
+1861 1 2419 2420 2421 2422 # HG CM CM CM
+1862 2 2420 2421 2422 2423 # CM CM CM CM
+1863 3 2421 2422 2423 2424 # CM CM CM CM
+1864 4 2422 2423 2424 2425 # CM CM CM CM
+1865 5 2423 2424 2425 2426 # CM CM CM CM
+1866 6 2424 2425 2426 2427 # CM CM CM CM
+1867 7 2425 2426 2427 2428 # CM CM CM CM
+1868 8 2426 2427 2428 2429 # CM CM CM CM
+1869 9 2427 2428 2429 2430 # CM CM CM CM
+1870 10 2428 2429 2430 2431 # CM CM CM CT
+1871 1 2432 2433 2434 2435 # HG CM CM CM
+1872 2 2433 2434 2435 2436 # CM CM CM CM
+1873 3 2434 2435 2436 2437 # CM CM CM CM
+1874 4 2435 2436 2437 2438 # CM CM CM CM
+1875 5 2436 2437 2438 2439 # CM CM CM CM
+1876 6 2437 2438 2439 2440 # CM CM CM CM
+1877 7 2438 2439 2440 2441 # CM CM CM CM
+1878 8 2439 2440 2441 2442 # CM CM CM CM
+1879 9 2440 2441 2442 2443 # CM CM CM CM
+1880 10 2441 2442 2443 2444 # CM CM CM CT
+1881 1 2445 2446 2447 2448 # HG CM CM CM
+1882 2 2446 2447 2448 2449 # CM CM CM CM
+1883 3 2447 2448 2449 2450 # CM CM CM CM
+1884 4 2448 2449 2450 2451 # CM CM CM CM
+1885 5 2449 2450 2451 2452 # CM CM CM CM
+1886 6 2450 2451 2452 2453 # CM CM CM CM
+1887 7 2451 2452 2453 2454 # CM CM CM CM
+1888 8 2452 2453 2454 2455 # CM CM CM CM
+1889 9 2453 2454 2455 2456 # CM CM CM CM
+1890 10 2454 2455 2456 2457 # CM CM CM CT
+1891 1 2458 2459 2460 2461 # HG CM CM CM
+1892 2 2459 2460 2461 2462 # CM CM CM CM
+1893 3 2460 2461 2462 2463 # CM CM CM CM
+1894 4 2461 2462 2463 2464 # CM CM CM CM
+1895 5 2462 2463 2464 2465 # CM CM CM CM
+1896 6 2463 2464 2465 2466 # CM CM CM CM
+1897 7 2464 2465 2466 2467 # CM CM CM CM
+1898 8 2465 2466 2467 2468 # CM CM CM CM
+1899 9 2466 2467 2468 2469 # CM CM CM CM
+1900 10 2467 2468 2469 2470 # CM CM CM CT
+1901 1 2471 2472 2473 2474 # HG CM CM CM
+1902 2 2472 2473 2474 2475 # CM CM CM CM
+1903 3 2473 2474 2475 2476 # CM CM CM CM
+1904 4 2474 2475 2476 2477 # CM CM CM CM
+1905 5 2475 2476 2477 2478 # CM CM CM CM
+1906 6 2476 2477 2478 2479 # CM CM CM CM
+1907 7 2477 2478 2479 2480 # CM CM CM CM
+1908 8 2478 2479 2480 2481 # CM CM CM CM
+1909 9 2479 2480 2481 2482 # CM CM CM CM
+1910 10 2480 2481 2482 2483 # CM CM CM CT
+1911 1 2484 2485 2486 2487 # HG CM CM CM
+1912 2 2485 2486 2487 2488 # CM CM CM CM
+1913 3 2486 2487 2488 2489 # CM CM CM CM
+1914 4 2487 2488 2489 2490 # CM CM CM CM
+1915 5 2488 2489 2490 2491 # CM CM CM CM
+1916 6 2489 2490 2491 2492 # CM CM CM CM
+1917 7 2490 2491 2492 2493 # CM CM CM CM
+1918 8 2491 2492 2493 2494 # CM CM CM CM
+1919 9 2492 2493 2494 2495 # CM CM CM CM
+1920 10 2493 2494 2495 2496 # CM CM CM CT
+1921 1 2497 2498 2499 2500 # HG CM CM CM
+1922 2 2498 2499 2500 2501 # CM CM CM CM
+1923 3 2499 2500 2501 2502 # CM CM CM CM
+1924 4 2500 2501 2502 2503 # CM CM CM CM
+1925 5 2501 2502 2503 2504 # CM CM CM CM
+1926 6 2502 2503 2504 2505 # CM CM CM CM
+1927 7 2503 2504 2505 2506 # CM CM CM CM
+1928 8 2504 2505 2506 2507 # CM CM CM CM
+1929 9 2505 2506 2507 2508 # CM CM CM CM
+1930 10 2506 2507 2508 2509 # CM CM CM CT
+1931 1 2510 2511 2512 2513 # HG CM CM CM
+1932 2 2511 2512 2513 2514 # CM CM CM CM
+1933 3 2512 2513 2514 2515 # CM CM CM CM
+1934 4 2513 2514 2515 2516 # CM CM CM CM
+1935 5 2514 2515 2516 2517 # CM CM CM CM
+1936 6 2515 2516 2517 2518 # CM CM CM CM
+1937 7 2516 2517 2518 2519 # CM CM CM CM
+1938 8 2517 2518 2519 2520 # CM CM CM CM
+1939 9 2518 2519 2520 2521 # CM CM CM CM
+1940 10 2519 2520 2521 2522 # CM CM CM CT
+1941 1 2523 2524 2525 2526 # HG CM CM CM
+1942 2 2524 2525 2526 2527 # CM CM CM CM
+1943 3 2525 2526 2527 2528 # CM CM CM CM
+1944 4 2526 2527 2528 2529 # CM CM CM CM
+1945 5 2527 2528 2529 2530 # CM CM CM CM
+1946 6 2528 2529 2530 2531 # CM CM CM CM
+1947 7 2529 2530 2531 2532 # CM CM CM CM
+1948 8 2530 2531 2532 2533 # CM CM CM CM
+1949 9 2531 2532 2533 2534 # CM CM CM CM
+1950 10 2532 2533 2534 2535 # CM CM CM CT
+1951 1 2536 2537 2538 2539 # HG CM CM CM
+1952 2 2537 2538 2539 2540 # CM CM CM CM
+1953 3 2538 2539 2540 2541 # CM CM CM CM
+1954 4 2539 2540 2541 2542 # CM CM CM CM
+1955 5 2540 2541 2542 2543 # CM CM CM CM
+1956 6 2541 2542 2543 2544 # CM CM CM CM
+1957 7 2542 2543 2544 2545 # CM CM CM CM
+1958 8 2543 2544 2545 2546 # CM CM CM CM
+1959 9 2544 2545 2546 2547 # CM CM CM CM
+1960 10 2545 2546 2547 2548 # CM CM CM CT
+1961 1 2549 2550 2551 2552 # HG CM CM CM
+1962 2 2550 2551 2552 2553 # CM CM CM CM
+1963 3 2551 2552 2553 2554 # CM CM CM CM
+1964 4 2552 2553 2554 2555 # CM CM CM CM
+1965 5 2553 2554 2555 2556 # CM CM CM CM
+1966 6 2554 2555 2556 2557 # CM CM CM CM
+1967 7 2555 2556 2557 2558 # CM CM CM CM
+1968 8 2556 2557 2558 2559 # CM CM CM CM
+1969 9 2557 2558 2559 2560 # CM CM CM CM
+1970 10 2558 2559 2560 2561 # CM CM CM CT
+1971 1 2562 2563 2564 2565 # HG CM CM CM
+1972 2 2563 2564 2565 2566 # CM CM CM CM
+1973 3 2564 2565 2566 2567 # CM CM CM CM
+1974 4 2565 2566 2567 2568 # CM CM CM CM
+1975 5 2566 2567 2568 2569 # CM CM CM CM
+1976 6 2567 2568 2569 2570 # CM CM CM CM
+1977 7 2568 2569 2570 2571 # CM CM CM CM
+1978 8 2569 2570 2571 2572 # CM CM CM CM
+1979 9 2570 2571 2572 2573 # CM CM CM CM
+1980 10 2571 2572 2573 2574 # CM CM CM CT
+1981 1 2575 2576 2577 2578 # HG CM CM CM
+1982 2 2576 2577 2578 2579 # CM CM CM CM
+1983 3 2577 2578 2579 2580 # CM CM CM CM
+1984 4 2578 2579 2580 2581 # CM CM CM CM
+1985 5 2579 2580 2581 2582 # CM CM CM CM
+1986 6 2580 2581 2582 2583 # CM CM CM CM
+1987 7 2581 2582 2583 2584 # CM CM CM CM
+1988 8 2582 2583 2584 2585 # CM CM CM CM
+1989 9 2583 2584 2585 2586 # CM CM CM CM
+1990 10 2584 2585 2586 2587 # CM CM CM CT
+1991 1 2588 2589 2590 2591 # HG CM CM CM
+1992 2 2589 2590 2591 2592 # CM CM CM CM
+1993 3 2590 2591 2592 2593 # CM CM CM CM
+1994 4 2591 2592 2593 2594 # CM CM CM CM
+1995 5 2592 2593 2594 2595 # CM CM CM CM
+1996 6 2593 2594 2595 2596 # CM CM CM CM
+1997 7 2594 2595 2596 2597 # CM CM CM CM
+1998 8 2595 2596 2597 2598 # CM CM CM CM
+1999 9 2596 2597 2598 2599 # CM CM CM CM
+2000 10 2597 2598 2599 2600 # CM CM CM CT
+2001 1 2601 2602 2603 2604 # HG CM CM CM
+2002 2 2602 2603 2604 2605 # CM CM CM CM
+2003 3 2603 2604 2605 2606 # CM CM CM CM
+2004 4 2604 2605 2606 2607 # CM CM CM CM
+2005 5 2605 2606 2607 2608 # CM CM CM CM
+2006 6 2606 2607 2608 2609 # CM CM CM CM
+2007 7 2607 2608 2609 2610 # CM CM CM CM
+2008 8 2608 2609 2610 2611 # CM CM CM CM
+2009 9 2609 2610 2611 2612 # CM CM CM CM
+2010 10 2610 2611 2612 2613 # CM CM CM CT
+2011 1 2614 2615 2616 2617 # HG CM CM CM
+2012 2 2615 2616 2617 2618 # CM CM CM CM
+2013 3 2616 2617 2618 2619 # CM CM CM CM
+2014 4 2617 2618 2619 2620 # CM CM CM CM
+2015 5 2618 2619 2620 2621 # CM CM CM CM
+2016 6 2619 2620 2621 2622 # CM CM CM CM
+2017 7 2620 2621 2622 2623 # CM CM CM CM
+2018 8 2621 2622 2623 2624 # CM CM CM CM
+2019 9 2622 2623 2624 2625 # CM CM CM CM
+2020 10 2623 2624 2625 2626 # CM CM CM CT
+2021 1 2627 2628 2629 2630 # HG CM CM CM
+2022 2 2628 2629 2630 2631 # CM CM CM CM
+2023 3 2629 2630 2631 2632 # CM CM CM CM
+2024 4 2630 2631 2632 2633 # CM CM CM CM
+2025 5 2631 2632 2633 2634 # CM CM CM CM
+2026 6 2632 2633 2634 2635 # CM CM CM CM
+2027 7 2633 2634 2635 2636 # CM CM CM CM
+2028 8 2634 2635 2636 2637 # CM CM CM CM
+2029 9 2635 2636 2637 2638 # CM CM CM CM
+2030 10 2636 2637 2638 2639 # CM CM CM CT
+2031 1 2640 2641 2642 2643 # HG CM CM CM
+2032 2 2641 2642 2643 2644 # CM CM CM CM
+2033 3 2642 2643 2644 2645 # CM CM CM CM
+2034 4 2643 2644 2645 2646 # CM CM CM CM
+2035 5 2644 2645 2646 2647 # CM CM CM CM
+2036 6 2645 2646 2647 2648 # CM CM CM CM
+2037 7 2646 2647 2648 2649 # CM CM CM CM
+2038 8 2647 2648 2649 2650 # CM CM CM CM
+2039 9 2648 2649 2650 2651 # CM CM CM CM
+2040 10 2649 2650 2651 2652 # CM CM CM CT
+2041 1 2653 2654 2655 2656 # HG CM CM CM
+2042 2 2654 2655 2656 2657 # CM CM CM CM
+2043 3 2655 2656 2657 2658 # CM CM CM CM
+2044 4 2656 2657 2658 2659 # CM CM CM CM
+2045 5 2657 2658 2659 2660 # CM CM CM CM
+2046 6 2658 2659 2660 2661 # CM CM CM CM
+2047 7 2659 2660 2661 2662 # CM CM CM CM
+2048 8 2660 2661 2662 2663 # CM CM CM CM
+2049 9 2661 2662 2663 2664 # CM CM CM CM
+2050 10 2662 2663 2664 2665 # CM CM CM CT
+2051 1 2666 2667 2668 2669 # HG CM CM CM
+2052 2 2667 2668 2669 2670 # CM CM CM CM
+2053 3 2668 2669 2670 2671 # CM CM CM CM
+2054 4 2669 2670 2671 2672 # CM CM CM CM
+2055 5 2670 2671 2672 2673 # CM CM CM CM
+2056 6 2671 2672 2673 2674 # CM CM CM CM
+2057 7 2672 2673 2674 2675 # CM CM CM CM
+2058 8 2673 2674 2675 2676 # CM CM CM CM
+2059 9 2674 2675 2676 2677 # CM CM CM CM
+2060 10 2675 2676 2677 2678 # CM CM CM CT
+2061 1 2679 2680 2681 2682 # HG CM CM CM
+2062 2 2680 2681 2682 2683 # CM CM CM CM
+2063 3 2681 2682 2683 2684 # CM CM CM CM
+2064 4 2682 2683 2684 2685 # CM CM CM CM
+2065 5 2683 2684 2685 2686 # CM CM CM CM
+2066 6 2684 2685 2686 2687 # CM CM CM CM
+2067 7 2685 2686 2687 2688 # CM CM CM CM
+2068 8 2686 2687 2688 2689 # CM CM CM CM
+2069 9 2687 2688 2689 2690 # CM CM CM CM
+2070 10 2688 2689 2690 2691 # CM CM CM CT
+2071 1 2692 2693 2694 2695 # HG CM CM CM
+2072 2 2693 2694 2695 2696 # CM CM CM CM
+2073 3 2694 2695 2696 2697 # CM CM CM CM
+2074 4 2695 2696 2697 2698 # CM CM CM CM
+2075 5 2696 2697 2698 2699 # CM CM CM CM
+2076 6 2697 2698 2699 2700 # CM CM CM CM
+2077 7 2698 2699 2700 2701 # CM CM CM CM
+2078 8 2699 2700 2701 2702 # CM CM CM CM
+2079 9 2700 2701 2702 2703 # CM CM CM CM
+2080 10 2701 2702 2703 2704 # CM CM CM CT
+2081 1 2705 2706 2707 2708 # HG CM CM CM
+2082 2 2706 2707 2708 2709 # CM CM CM CM
+2083 3 2707 2708 2709 2710 # CM CM CM CM
+2084 4 2708 2709 2710 2711 # CM CM CM CM
+2085 5 2709 2710 2711 2712 # CM CM CM CM
+2086 6 2710 2711 2712 2713 # CM CM CM CM
+2087 7 2711 2712 2713 2714 # CM CM CM CM
+2088 8 2712 2713 2714 2715 # CM CM CM CM
+2089 9 2713 2714 2715 2716 # CM CM CM CM
+2090 10 2714 2715 2716 2717 # CM CM CM CT
+2091 1 2718 2719 2720 2721 # HG CM CM CM
+2092 2 2719 2720 2721 2722 # CM CM CM CM
+2093 3 2720 2721 2722 2723 # CM CM CM CM
+2094 4 2721 2722 2723 2724 # CM CM CM CM
+2095 5 2722 2723 2724 2725 # CM CM CM CM
+2096 6 2723 2724 2725 2726 # CM CM CM CM
+2097 7 2724 2725 2726 2727 # CM CM CM CM
+2098 8 2725 2726 2727 2728 # CM CM CM CM
+2099 9 2726 2727 2728 2729 # CM CM CM CM
+2100 10 2727 2728 2729 2730 # CM CM CM CT
+2101 1 2731 2732 2733 2734 # HG CM CM CM
+2102 2 2732 2733 2734 2735 # CM CM CM CM
+2103 3 2733 2734 2735 2736 # CM CM CM CM
+2104 4 2734 2735 2736 2737 # CM CM CM CM
+2105 5 2735 2736 2737 2738 # CM CM CM CM
+2106 6 2736 2737 2738 2739 # CM CM CM CM
+2107 7 2737 2738 2739 2740 # CM CM CM CM
+2108 8 2738 2739 2740 2741 # CM CM CM CM
+2109 9 2739 2740 2741 2742 # CM CM CM CM
+2110 10 2740 2741 2742 2743 # CM CM CM CT
+2111 1 2744 2745 2746 2747 # HG CM CM CM
+2112 2 2745 2746 2747 2748 # CM CM CM CM
+2113 3 2746 2747 2748 2749 # CM CM CM CM
+2114 4 2747 2748 2749 2750 # CM CM CM CM
+2115 5 2748 2749 2750 2751 # CM CM CM CM
+2116 6 2749 2750 2751 2752 # CM CM CM CM
+2117 7 2750 2751 2752 2753 # CM CM CM CM
+2118 8 2751 2752 2753 2754 # CM CM CM CM
+2119 9 2752 2753 2754 2755 # CM CM CM CM
+2120 10 2753 2754 2755 2756 # CM CM CM CT
+2121 1 2757 2758 2759 2760 # HG CM CM CM
+2122 2 2758 2759 2760 2761 # CM CM CM CM
+2123 3 2759 2760 2761 2762 # CM CM CM CM
+2124 4 2760 2761 2762 2763 # CM CM CM CM
+2125 5 2761 2762 2763 2764 # CM CM CM CM
+2126 6 2762 2763 2764 2765 # CM CM CM CM
+2127 7 2763 2764 2765 2766 # CM CM CM CM
+2128 8 2764 2765 2766 2767 # CM CM CM CM
+2129 9 2765 2766 2767 2768 # CM CM CM CM
+2130 10 2766 2767 2768 2769 # CM CM CM CT
+2131 1 2770 2771 2772 2773 # HG CM CM CM
+2132 2 2771 2772 2773 2774 # CM CM CM CM
+2133 3 2772 2773 2774 2775 # CM CM CM CM
+2134 4 2773 2774 2775 2776 # CM CM CM CM
+2135 5 2774 2775 2776 2777 # CM CM CM CM
+2136 6 2775 2776 2777 2778 # CM CM CM CM
+2137 7 2776 2777 2778 2779 # CM CM CM CM
+2138 8 2777 2778 2779 2780 # CM CM CM CM
+2139 9 2778 2779 2780 2781 # CM CM CM CM
+2140 10 2779 2780 2781 2782 # CM CM CM CT
+2141 1 2783 2784 2785 2786 # HG CM CM CM
+2142 2 2784 2785 2786 2787 # CM CM CM CM
+2143 3 2785 2786 2787 2788 # CM CM CM CM
+2144 4 2786 2787 2788 2789 # CM CM CM CM
+2145 5 2787 2788 2789 2790 # CM CM CM CM
+2146 6 2788 2789 2790 2791 # CM CM CM CM
+2147 7 2789 2790 2791 2792 # CM CM CM CM
+2148 8 2790 2791 2792 2793 # CM CM CM CM
+2149 9 2791 2792 2793 2794 # CM CM CM CM
+2150 10 2792 2793 2794 2795 # CM CM CM CT
+2151 1 2796 2797 2798 2799 # HG CM CM CM
+2152 2 2797 2798 2799 2800 # CM CM CM CM
+2153 3 2798 2799 2800 2801 # CM CM CM CM
+2154 4 2799 2800 2801 2802 # CM CM CM CM
+2155 5 2800 2801 2802 2803 # CM CM CM CM
+2156 6 2801 2802 2803 2804 # CM CM CM CM
+2157 7 2802 2803 2804 2805 # CM CM CM CM
+2158 8 2803 2804 2805 2806 # CM CM CM CM
+2159 9 2804 2805 2806 2807 # CM CM CM CM
+2160 10 2805 2806 2807 2808 # CM CM CM CT
+2161 1 2809 2810 2811 2812 # HG CM CM CM
+2162 2 2810 2811 2812 2813 # CM CM CM CM
+2163 3 2811 2812 2813 2814 # CM CM CM CM
+2164 4 2812 2813 2814 2815 # CM CM CM CM
+2165 5 2813 2814 2815 2816 # CM CM CM CM
+2166 6 2814 2815 2816 2817 # CM CM CM CM
+2167 7 2815 2816 2817 2818 # CM CM CM CM
+2168 8 2816 2817 2818 2819 # CM CM CM CM
+2169 9 2817 2818 2819 2820 # CM CM CM CM
+2170 10 2818 2819 2820 2821 # CM CM CM CT
+2171 1 2822 2823 2824 2825 # HG CM CM CM
+2172 2 2823 2824 2825 2826 # CM CM CM CM
+2173 3 2824 2825 2826 2827 # CM CM CM CM
+2174 4 2825 2826 2827 2828 # CM CM CM CM
+2175 5 2826 2827 2828 2829 # CM CM CM CM
+2176 6 2827 2828 2829 2830 # CM CM CM CM
+2177 7 2828 2829 2830 2831 # CM CM CM CM
+2178 8 2829 2830 2831 2832 # CM CM CM CM
+2179 9 2830 2831 2832 2833 # CM CM CM CM
+2180 10 2831 2832 2833 2834 # CM CM CM CT
+2181 1 2835 2836 2837 2838 # HG CM CM CM
+2182 2 2836 2837 2838 2839 # CM CM CM CM
+2183 3 2837 2838 2839 2840 # CM CM CM CM
+2184 4 2838 2839 2840 2841 # CM CM CM CM
+2185 5 2839 2840 2841 2842 # CM CM CM CM
+2186 6 2840 2841 2842 2843 # CM CM CM CM
+2187 7 2841 2842 2843 2844 # CM CM CM CM
+2188 8 2842 2843 2844 2845 # CM CM CM CM
+2189 9 2843 2844 2845 2846 # CM CM CM CM
+2190 10 2844 2845 2846 2847 # CM CM CM CT
+2191 1 2848 2849 2850 2851 # HG CM CM CM
+2192 2 2849 2850 2851 2852 # CM CM CM CM
+2193 3 2850 2851 2852 2853 # CM CM CM CM
+2194 4 2851 2852 2853 2854 # CM CM CM CM
+2195 5 2852 2853 2854 2855 # CM CM CM CM
+2196 6 2853 2854 2855 2856 # CM CM CM CM
+2197 7 2854 2855 2856 2857 # CM CM CM CM
+2198 8 2855 2856 2857 2858 # CM CM CM CM
+2199 9 2856 2857 2858 2859 # CM CM CM CM
+2200 10 2857 2858 2859 2860 # CM CM CM CT
+2201 1 2861 2862 2863 2864 # HG CM CM CM
+2202 2 2862 2863 2864 2865 # CM CM CM CM
+2203 3 2863 2864 2865 2866 # CM CM CM CM
+2204 4 2864 2865 2866 2867 # CM CM CM CM
+2205 5 2865 2866 2867 2868 # CM CM CM CM
+2206 6 2866 2867 2868 2869 # CM CM CM CM
+2207 7 2867 2868 2869 2870 # CM CM CM CM
+2208 8 2868 2869 2870 2871 # CM CM CM CM
+2209 9 2869 2870 2871 2872 # CM CM CM CM
+2210 10 2870 2871 2872 2873 # CM CM CM CT
+2211 1 2874 2875 2876 2877 # HG CM CM CM
+2212 2 2875 2876 2877 2878 # CM CM CM CM
+2213 3 2876 2877 2878 2879 # CM CM CM CM
+2214 4 2877 2878 2879 2880 # CM CM CM CM
+2215 5 2878 2879 2880 2881 # CM CM CM CM
+2216 6 2879 2880 2881 2882 # CM CM CM CM
+2217 7 2880 2881 2882 2883 # CM CM CM CM
+2218 8 2881 2882 2883 2884 # CM CM CM CM
+2219 9 2882 2883 2884 2885 # CM CM CM CM
+2220 10 2883 2884 2885 2886 # CM CM CM CT
+2221 1 2887 2888 2889 2890 # HG CM CM CM
+2222 2 2888 2889 2890 2891 # CM CM CM CM
+2223 3 2889 2890 2891 2892 # CM CM CM CM
+2224 4 2890 2891 2892 2893 # CM CM CM CM
+2225 5 2891 2892 2893 2894 # CM CM CM CM
+2226 6 2892 2893 2894 2895 # CM CM CM CM
+2227 7 2893 2894 2895 2896 # CM CM CM CM
+2228 8 2894 2895 2896 2897 # CM CM CM CM
+2229 9 2895 2896 2897 2898 # CM CM CM CM
+2230 10 2896 2897 2898 2899 # CM CM CM CT
+2231 1 2900 2901 2902 2903 # HG CM CM CM
+2232 2 2901 2902 2903 2904 # CM CM CM CM
+2233 3 2902 2903 2904 2905 # CM CM CM CM
+2234 4 2903 2904 2905 2906 # CM CM CM CM
+2235 5 2904 2905 2906 2907 # CM CM CM CM
+2236 6 2905 2906 2907 2908 # CM CM CM CM
+2237 7 2906 2907 2908 2909 # CM CM CM CM
+2238 8 2907 2908 2909 2910 # CM CM CM CM
+2239 9 2908 2909 2910 2911 # CM CM CM CM
+2240 10 2909 2910 2911 2912 # CM CM CM CT
+2241 1 2913 2914 2915 2916 # HG CM CM CM
+2242 2 2914 2915 2916 2917 # CM CM CM CM
+2243 3 2915 2916 2917 2918 # CM CM CM CM
+2244 4 2916 2917 2918 2919 # CM CM CM CM
+2245 5 2917 2918 2919 2920 # CM CM CM CM
+2246 6 2918 2919 2920 2921 # CM CM CM CM
+2247 7 2919 2920 2921 2922 # CM CM CM CM
+2248 8 2920 2921 2922 2923 # CM CM CM CM
+2249 9 2921 2922 2923 2924 # CM CM CM CM
+2250 10 2922 2923 2924 2925 # CM CM CM CT
+2251 1 2926 2927 2928 2929 # HG CM CM CM
+2252 2 2927 2928 2929 2930 # CM CM CM CM
+2253 3 2928 2929 2930 2931 # CM CM CM CM
+2254 4 2929 2930 2931 2932 # CM CM CM CM
+2255 5 2930 2931 2932 2933 # CM CM CM CM
+2256 6 2931 2932 2933 2934 # CM CM CM CM
+2257 7 2932 2933 2934 2935 # CM CM CM CM
+2258 8 2933 2934 2935 2936 # CM CM CM CM
+2259 9 2934 2935 2936 2937 # CM CM CM CM
+2260 10 2935 2936 2937 2938 # CM CM CM CT
+2261 1 2939 2940 2941 2942 # HG CM CM CM
+2262 2 2940 2941 2942 2943 # CM CM CM CM
+2263 3 2941 2942 2943 2944 # CM CM CM CM
+2264 4 2942 2943 2944 2945 # CM CM CM CM
+2265 5 2943 2944 2945 2946 # CM CM CM CM
+2266 6 2944 2945 2946 2947 # CM CM CM CM
+2267 7 2945 2946 2947 2948 # CM CM CM CM
+2268 8 2946 2947 2948 2949 # CM CM CM CM
+2269 9 2947 2948 2949 2950 # CM CM CM CM
+2270 10 2948 2949 2950 2951 # CM CM CM CT
+2271 1 2952 2953 2954 2955 # HG CM CM CM
+2272 2 2953 2954 2955 2956 # CM CM CM CM
+2273 3 2954 2955 2956 2957 # CM CM CM CM
+2274 4 2955 2956 2957 2958 # CM CM CM CM
+2275 5 2956 2957 2958 2959 # CM CM CM CM
+2276 6 2957 2958 2959 2960 # CM CM CM CM
+2277 7 2958 2959 2960 2961 # CM CM CM CM
+2278 8 2959 2960 2961 2962 # CM CM CM CM
+2279 9 2960 2961 2962 2963 # CM CM CM CM
+2280 10 2961 2962 2963 2964 # CM CM CM CT
+2281 1 2965 2966 2967 2968 # HG CM CM CM
+2282 2 2966 2967 2968 2969 # CM CM CM CM
+2283 3 2967 2968 2969 2970 # CM CM CM CM
+2284 4 2968 2969 2970 2971 # CM CM CM CM
+2285 5 2969 2970 2971 2972 # CM CM CM CM
+2286 6 2970 2971 2972 2973 # CM CM CM CM
+2287 7 2971 2972 2973 2974 # CM CM CM CM
+2288 8 2972 2973 2974 2975 # CM CM CM CM
+2289 9 2973 2974 2975 2976 # CM CM CM CM
+2290 10 2974 2975 2976 2977 # CM CM CM CT
+2291 1 2978 2979 2980 2981 # HG CM CM CM
+2292 2 2979 2980 2981 2982 # CM CM CM CM
+2293 3 2980 2981 2982 2983 # CM CM CM CM
+2294 4 2981 2982 2983 2984 # CM CM CM CM
+2295 5 2982 2983 2984 2985 # CM CM CM CM
+2296 6 2983 2984 2985 2986 # CM CM CM CM
+2297 7 2984 2985 2986 2987 # CM CM CM CM
+2298 8 2985 2986 2987 2988 # CM CM CM CM
+2299 9 2986 2987 2988 2989 # CM CM CM CM
+2300 10 2987 2988 2989 2990 # CM CM CM CT
+2301 1 2991 2992 2993 2994 # HG CM CM CM
+2302 2 2992 2993 2994 2995 # CM CM CM CM
+2303 3 2993 2994 2995 2996 # CM CM CM CM
+2304 4 2994 2995 2996 2997 # CM CM CM CM
+2305 5 2995 2996 2997 2998 # CM CM CM CM
+2306 6 2996 2997 2998 2999 # CM CM CM CM
+2307 7 2997 2998 2999 3000 # CM CM CM CM
+2308 8 2998 2999 3000 3001 # CM CM CM CM
+2309 9 2999 3000 3001 3002 # CM CM CM CM
+2310 10 3000 3001 3002 3003 # CM CM CM CT
+2311 1 3004 3005 3006 3007 # HG CM CM CM
+2312 2 3005 3006 3007 3008 # CM CM CM CM
+2313 3 3006 3007 3008 3009 # CM CM CM CM
+2314 4 3007 3008 3009 3010 # CM CM CM CM
+2315 5 3008 3009 3010 3011 # CM CM CM CM
+2316 6 3009 3010 3011 3012 # CM CM CM CM
+2317 7 3010 3011 3012 3013 # CM CM CM CM
+2318 8 3011 3012 3013 3014 # CM CM CM CM
+2319 9 3012 3013 3014 3015 # CM CM CM CM
+2320 10 3013 3014 3015 3016 # CM CM CM CT
+2321 1 3017 3018 3019 3020 # HG CM CM CM
+2322 2 3018 3019 3020 3021 # CM CM CM CM
+2323 3 3019 3020 3021 3022 # CM CM CM CM
+2324 4 3020 3021 3022 3023 # CM CM CM CM
+2325 5 3021 3022 3023 3024 # CM CM CM CM
+2326 6 3022 3023 3024 3025 # CM CM CM CM
+2327 7 3023 3024 3025 3026 # CM CM CM CM
+2328 8 3024 3025 3026 3027 # CM CM CM CM
+2329 9 3025 3026 3027 3028 # CM CM CM CM
+2330 10 3026 3027 3028 3029 # CM CM CM CT
+2331 1 3030 3031 3032 3033 # HG CM CM CM
+2332 2 3031 3032 3033 3034 # CM CM CM CM
+2333 3 3032 3033 3034 3035 # CM CM CM CM
+2334 4 3033 3034 3035 3036 # CM CM CM CM
+2335 5 3034 3035 3036 3037 # CM CM CM CM
+2336 6 3035 3036 3037 3038 # CM CM CM CM
+2337 7 3036 3037 3038 3039 # CM CM CM CM
+2338 8 3037 3038 3039 3040 # CM CM CM CM
+2339 9 3038 3039 3040 3041 # CM CM CM CM
+2340 10 3039 3040 3041 3042 # CM CM CM CT
+2341 1 3043 3044 3045 3046 # HG CM CM CM
+2342 2 3044 3045 3046 3047 # CM CM CM CM
+2343 3 3045 3046 3047 3048 # CM CM CM CM
+2344 4 3046 3047 3048 3049 # CM CM CM CM
+2345 5 3047 3048 3049 3050 # CM CM CM CM
+2346 6 3048 3049 3050 3051 # CM CM CM CM
+2347 7 3049 3050 3051 3052 # CM CM CM CM
+2348 8 3050 3051 3052 3053 # CM CM CM CM
+2349 9 3051 3052 3053 3054 # CM CM CM CM
+2350 10 3052 3053 3054 3055 # CM CM CM CT
+2351 1 3056 3057 3058 3059 # HG CM CM CM
+2352 2 3057 3058 3059 3060 # CM CM CM CM
+2353 3 3058 3059 3060 3061 # CM CM CM CM
+2354 4 3059 3060 3061 3062 # CM CM CM CM
+2355 5 3060 3061 3062 3063 # CM CM CM CM
+2356 6 3061 3062 3063 3064 # CM CM CM CM
+2357 7 3062 3063 3064 3065 # CM CM CM CM
+2358 8 3063 3064 3065 3066 # CM CM CM CM
+2359 9 3064 3065 3066 3067 # CM CM CM CM
+2360 10 3065 3066 3067 3068 # CM CM CM CT
+2361 1 3069 3070 3071 3072 # HG CM CM CM
+2362 2 3070 3071 3072 3073 # CM CM CM CM
+2363 3 3071 3072 3073 3074 # CM CM CM CM
+2364 4 3072 3073 3074 3075 # CM CM CM CM
+2365 5 3073 3074 3075 3076 # CM CM CM CM
+2366 6 3074 3075 3076 3077 # CM CM CM CM
+2367 7 3075 3076 3077 3078 # CM CM CM CM
+2368 8 3076 3077 3078 3079 # CM CM CM CM
+2369 9 3077 3078 3079 3080 # CM CM CM CM
+2370 10 3078 3079 3080 3081 # CM CM CM CT
+2371 1 3082 3083 3084 3085 # HG CM CM CM
+2372 2 3083 3084 3085 3086 # CM CM CM CM
+2373 3 3084 3085 3086 3087 # CM CM CM CM
+2374 4 3085 3086 3087 3088 # CM CM CM CM
+2375 5 3086 3087 3088 3089 # CM CM CM CM
+2376 6 3087 3088 3089 3090 # CM CM CM CM
+2377 7 3088 3089 3090 3091 # CM CM CM CM
+2378 8 3089 3090 3091 3092 # CM CM CM CM
+2379 9 3090 3091 3092 3093 # CM CM CM CM
+2380 10 3091 3092 3093 3094 # CM CM CM CT
+2381 1 3095 3096 3097 3098 # HG CM CM CM
+2382 2 3096 3097 3098 3099 # CM CM CM CM
+2383 3 3097 3098 3099 3100 # CM CM CM CM
+2384 4 3098 3099 3100 3101 # CM CM CM CM
+2385 5 3099 3100 3101 3102 # CM CM CM CM
+2386 6 3100 3101 3102 3103 # CM CM CM CM
+2387 7 3101 3102 3103 3104 # CM CM CM CM
+2388 8 3102 3103 3104 3105 # CM CM CM CM
+2389 9 3103 3104 3105 3106 # CM CM CM CM
+2390 10 3104 3105 3106 3107 # CM CM CM CT
+2391 1 3108 3109 3110 3111 # HG CM CM CM
+2392 2 3109 3110 3111 3112 # CM CM CM CM
+2393 3 3110 3111 3112 3113 # CM CM CM CM
+2394 4 3111 3112 3113 3114 # CM CM CM CM
+2395 5 3112 3113 3114 3115 # CM CM CM CM
+2396 6 3113 3114 3115 3116 # CM CM CM CM
+2397 7 3114 3115 3116 3117 # CM CM CM CM
+2398 8 3115 3116 3117 3118 # CM CM CM CM
+2399 9 3116 3117 3118 3119 # CM CM CM CM
+2400 10 3117 3118 3119 3120 # CM CM CM CT
+2401 1 3121 3122 3123 3124 # HG CM CM CM
+2402 2 3122 3123 3124 3125 # CM CM CM CM
+2403 3 3123 3124 3125 3126 # CM CM CM CM
+2404 4 3124 3125 3126 3127 # CM CM CM CM
+2405 5 3125 3126 3127 3128 # CM CM CM CM
+2406 6 3126 3127 3128 3129 # CM CM CM CM
+2407 7 3127 3128 3129 3130 # CM CM CM CM
+2408 8 3128 3129 3130 3131 # CM CM CM CM
+2409 9 3129 3130 3131 3132 # CM CM CM CM
+2410 10 3130 3131 3132 3133 # CM CM CM CT
+2411 1 3134 3135 3136 3137 # HG CM CM CM
+2412 2 3135 3136 3137 3138 # CM CM CM CM
+2413 3 3136 3137 3138 3139 # CM CM CM CM
+2414 4 3137 3138 3139 3140 # CM CM CM CM
+2415 5 3138 3139 3140 3141 # CM CM CM CM
+2416 6 3139 3140 3141 3142 # CM CM CM CM
+2417 7 3140 3141 3142 3143 # CM CM CM CM
+2418 8 3141 3142 3143 3144 # CM CM CM CM
+2419 9 3142 3143 3144 3145 # CM CM CM CM
+2420 10 3143 3144 3145 3146 # CM CM CM CT
+2421 1 3147 3148 3149 3150 # HG CM CM CM
+2422 2 3148 3149 3150 3151 # CM CM CM CM
+2423 3 3149 3150 3151 3152 # CM CM CM CM
+2424 4 3150 3151 3152 3153 # CM CM CM CM
+2425 5 3151 3152 3153 3154 # CM CM CM CM
+2426 6 3152 3153 3154 3155 # CM CM CM CM
+2427 7 3153 3154 3155 3156 # CM CM CM CM
+2428 8 3154 3155 3156 3157 # CM CM CM CM
+2429 9 3155 3156 3157 3158 # CM CM CM CM
+2430 10 3156 3157 3158 3159 # CM CM CM CT
+2431 1 3160 3161 3162 3163 # HG CM CM CM
+2432 2 3161 3162 3163 3164 # CM CM CM CM
+2433 3 3162 3163 3164 3165 # CM CM CM CM
+2434 4 3163 3164 3165 3166 # CM CM CM CM
+2435 5 3164 3165 3166 3167 # CM CM CM CM
+2436 6 3165 3166 3167 3168 # CM CM CM CM
+2437 7 3166 3167 3168 3169 # CM CM CM CM
+2438 8 3167 3168 3169 3170 # CM CM CM CM
+2439 9 3168 3169 3170 3171 # CM CM CM CM
+2440 10 3169 3170 3171 3172 # CM CM CM CT
+2441 1 3173 3174 3175 3176 # HG CM CM CM
+2442 2 3174 3175 3176 3177 # CM CM CM CM
+2443 3 3175 3176 3177 3178 # CM CM CM CM
+2444 4 3176 3177 3178 3179 # CM CM CM CM
+2445 5 3177 3178 3179 3180 # CM CM CM CM
+2446 6 3178 3179 3180 3181 # CM CM CM CM
+2447 7 3179 3180 3181 3182 # CM CM CM CM
+2448 8 3180 3181 3182 3183 # CM CM CM CM
+2449 9 3181 3182 3183 3184 # CM CM CM CM
+2450 10 3182 3183 3184 3185 # CM CM CM CT
+2451 1 3186 3187 3188 3189 # HG CM CM CM
+2452 2 3187 3188 3189 3190 # CM CM CM CM
+2453 3 3188 3189 3190 3191 # CM CM CM CM
+2454 4 3189 3190 3191 3192 # CM CM CM CM
+2455 5 3190 3191 3192 3193 # CM CM CM CM
+2456 6 3191 3192 3193 3194 # CM CM CM CM
+2457 7 3192 3193 3194 3195 # CM CM CM CM
+2458 8 3193 3194 3195 3196 # CM CM CM CM
+2459 9 3194 3195 3196 3197 # CM CM CM CM
+2460 10 3195 3196 3197 3198 # CM CM CM CT
+2461 1 3199 3200 3201 3202 # HG CM CM CM
+2462 2 3200 3201 3202 3203 # CM CM CM CM
+2463 3 3201 3202 3203 3204 # CM CM CM CM
+2464 4 3202 3203 3204 3205 # CM CM CM CM
+2465 5 3203 3204 3205 3206 # CM CM CM CM
+2466 6 3204 3205 3206 3207 # CM CM CM CM
+2467 7 3205 3206 3207 3208 # CM CM CM CM
+2468 8 3206 3207 3208 3209 # CM CM CM CM
+2469 9 3207 3208 3209 3210 # CM CM CM CM
+2470 10 3208 3209 3210 3211 # CM CM CM CT
+2471 1 3212 3213 3214 3215 # HG CM CM CM
+2472 2 3213 3214 3215 3216 # CM CM CM CM
+2473 3 3214 3215 3216 3217 # CM CM CM CM
+2474 4 3215 3216 3217 3218 # CM CM CM CM
+2475 5 3216 3217 3218 3219 # CM CM CM CM
+2476 6 3217 3218 3219 3220 # CM CM CM CM
+2477 7 3218 3219 3220 3221 # CM CM CM CM
+2478 8 3219 3220 3221 3222 # CM CM CM CM
+2479 9 3220 3221 3222 3223 # CM CM CM CM
+2480 10 3221 3222 3223 3224 # CM CM CM CT
+2481 1 3225 3226 3227 3228 # HG CM CM CM
+2482 2 3226 3227 3228 3229 # CM CM CM CM
+2483 3 3227 3228 3229 3230 # CM CM CM CM
+2484 4 3228 3229 3230 3231 # CM CM CM CM
+2485 5 3229 3230 3231 3232 # CM CM CM CM
+2486 6 3230 3231 3232 3233 # CM CM CM CM
+2487 7 3231 3232 3233 3234 # CM CM CM CM
+2488 8 3232 3233 3234 3235 # CM CM CM CM
+2489 9 3233 3234 3235 3236 # CM CM CM CM
+2490 10 3234 3235 3236 3237 # CM CM CM CT
+2491 1 3238 3239 3240 3241 # HG CM CM CM
+2492 2 3239 3240 3241 3242 # CM CM CM CM
+2493 3 3240 3241 3242 3243 # CM CM CM CM
+2494 4 3241 3242 3243 3244 # CM CM CM CM
+2495 5 3242 3243 3244 3245 # CM CM CM CM
+2496 6 3243 3244 3245 3246 # CM CM CM CM
+2497 7 3244 3245 3246 3247 # CM CM CM CM
+2498 8 3245 3246 3247 3248 # CM CM CM CM
+2499 9 3246 3247 3248 3249 # CM CM CM CM
+2500 10 3247 3248 3249 3250 # CM CM CM CT
+2501 1 3251 3252 3253 3254 # HG CM CM CM
+2502 2 3252 3253 3254 3255 # CM CM CM CM
+2503 3 3253 3254 3255 3256 # CM CM CM CM
+2504 4 3254 3255 3256 3257 # CM CM CM CM
+2505 5 3255 3256 3257 3258 # CM CM CM CM
+2506 6 3256 3257 3258 3259 # CM CM CM CM
+2507 7 3257 3258 3259 3260 # CM CM CM CM
+2508 8 3258 3259 3260 3261 # CM CM CM CM
+2509 9 3259 3260 3261 3262 # CM CM CM CM
+2510 10 3260 3261 3262 3263 # CM CM CM CT
+2511 1 3264 3265 3266 3267 # HG CM CM CM
+2512 2 3265 3266 3267 3268 # CM CM CM CM
+2513 3 3266 3267 3268 3269 # CM CM CM CM
+2514 4 3267 3268 3269 3270 # CM CM CM CM
+2515 5 3268 3269 3270 3271 # CM CM CM CM
+2516 6 3269 3270 3271 3272 # CM CM CM CM
+2517 7 3270 3271 3272 3273 # CM CM CM CM
+2518 8 3271 3272 3273 3274 # CM CM CM CM
+2519 9 3272 3273 3274 3275 # CM CM CM CM
+2520 10 3273 3274 3275 3276 # CM CM CM CT
+2521 1 3277 3278 3279 3280 # HG CM CM CM
+2522 2 3278 3279 3280 3281 # CM CM CM CM
+2523 3 3279 3280 3281 3282 # CM CM CM CM
+2524 4 3280 3281 3282 3283 # CM CM CM CM
+2525 5 3281 3282 3283 3284 # CM CM CM CM
+2526 6 3282 3283 3284 3285 # CM CM CM CM
+2527 7 3283 3284 3285 3286 # CM CM CM CM
+2528 8 3284 3285 3286 3287 # CM CM CM CM
+2529 9 3285 3286 3287 3288 # CM CM CM CM
+2530 10 3286 3287 3288 3289 # CM CM CM CT
+2531 1 3290 3291 3292 3293 # HG CM CM CM
+2532 2 3291 3292 3293 3294 # CM CM CM CM
+2533 3 3292 3293 3294 3295 # CM CM CM CM
+2534 4 3293 3294 3295 3296 # CM CM CM CM
+2535 5 3294 3295 3296 3297 # CM CM CM CM
+2536 6 3295 3296 3297 3298 # CM CM CM CM
+2537 7 3296 3297 3298 3299 # CM CM CM CM
+2538 8 3297 3298 3299 3300 # CM CM CM CM
+2539 9 3298 3299 3300 3301 # CM CM CM CM
+2540 10 3299 3300 3301 3302 # CM CM CM CT
+2541 1 3303 3304 3305 3306 # HG CM CM CM
+2542 2 3304 3305 3306 3307 # CM CM CM CM
+2543 3 3305 3306 3307 3308 # CM CM CM CM
+2544 4 3306 3307 3308 3309 # CM CM CM CM
+2545 5 3307 3308 3309 3310 # CM CM CM CM
+2546 6 3308 3309 3310 3311 # CM CM CM CM
+2547 7 3309 3310 3311 3312 # CM CM CM CM
+2548 8 3310 3311 3312 3313 # CM CM CM CM
+2549 9 3311 3312 3313 3314 # CM CM CM CM
+2550 10 3312 3313 3314 3315 # CM CM CM CT
+2551 1 3316 3317 3318 3319 # HG CM CM CM
+2552 2 3317 3318 3319 3320 # CM CM CM CM
+2553 3 3318 3319 3320 3321 # CM CM CM CM
+2554 4 3319 3320 3321 3322 # CM CM CM CM
+2555 5 3320 3321 3322 3323 # CM CM CM CM
+2556 6 3321 3322 3323 3324 # CM CM CM CM
+2557 7 3322 3323 3324 3325 # CM CM CM CM
+2558 8 3323 3324 3325 3326 # CM CM CM CM
+2559 9 3324 3325 3326 3327 # CM CM CM CM
+2560 10 3325 3326 3327 3328 # CM CM CM CT
+2561 1 3329 3330 3331 3332 # HG CM CM CM
+2562 2 3330 3331 3332 3333 # CM CM CM CM
+2563 3 3331 3332 3333 3334 # CM CM CM CM
+2564 4 3332 3333 3334 3335 # CM CM CM CM
+2565 5 3333 3334 3335 3336 # CM CM CM CM
+2566 6 3334 3335 3336 3337 # CM CM CM CM
+2567 7 3335 3336 3337 3338 # CM CM CM CM
+2568 8 3336 3337 3338 3339 # CM CM CM CM
+2569 9 3337 3338 3339 3340 # CM CM CM CM
+2570 10 3338 3339 3340 3341 # CM CM CM CT
+2571 1 3342 3343 3344 3345 # HG CM CM CM
+2572 2 3343 3344 3345 3346 # CM CM CM CM
+2573 3 3344 3345 3346 3347 # CM CM CM CM
+2574 4 3345 3346 3347 3348 # CM CM CM CM
+2575 5 3346 3347 3348 3349 # CM CM CM CM
+2576 6 3347 3348 3349 3350 # CM CM CM CM
+2577 7 3348 3349 3350 3351 # CM CM CM CM
+2578 8 3349 3350 3351 3352 # CM CM CM CM
+2579 9 3350 3351 3352 3353 # CM CM CM CM
+2580 10 3351 3352 3353 3354 # CM CM CM CT
+2581 1 3355 3356 3357 3358 # HG CM CM CM
+2582 2 3356 3357 3358 3359 # CM CM CM CM
+2583 3 3357 3358 3359 3360 # CM CM CM CM
+2584 4 3358 3359 3360 3361 # CM CM CM CM
+2585 5 3359 3360 3361 3362 # CM CM CM CM
+2586 6 3360 3361 3362 3363 # CM CM CM CM
+2587 7 3361 3362 3363 3364 # CM CM CM CM
+2588 8 3362 3363 3364 3365 # CM CM CM CM
+2589 9 3363 3364 3365 3366 # CM CM CM CM
+2590 10 3364 3365 3366 3367 # CM CM CM CT
+2591 1 3368 3369 3370 3371 # HG CM CM CM
+2592 2 3369 3370 3371 3372 # CM CM CM CM
+2593 3 3370 3371 3372 3373 # CM CM CM CM
+2594 4 3371 3372 3373 3374 # CM CM CM CM
+2595 5 3372 3373 3374 3375 # CM CM CM CM
+2596 6 3373 3374 3375 3376 # CM CM CM CM
+2597 7 3374 3375 3376 3377 # CM CM CM CM
+2598 8 3375 3376 3377 3378 # CM CM CM CM
+2599 9 3376 3377 3378 3379 # CM CM CM CM
+2600 10 3377 3378 3379 3380 # CM CM CM CT
+2601 1 3381 3382 3383 3384 # HG CM CM CM
+2602 2 3382 3383 3384 3385 # CM CM CM CM
+2603 3 3383 3384 3385 3386 # CM CM CM CM
+2604 4 3384 3385 3386 3387 # CM CM CM CM
+2605 5 3385 3386 3387 3388 # CM CM CM CM
+2606 6 3386 3387 3388 3389 # CM CM CM CM
+2607 7 3387 3388 3389 3390 # CM CM CM CM
+2608 8 3388 3389 3390 3391 # CM CM CM CM
+2609 9 3389 3390 3391 3392 # CM CM CM CM
+2610 10 3390 3391 3392 3393 # CM CM CM CT
+2611 1 3394 3395 3396 3397 # HG CM CM CM
+2612 2 3395 3396 3397 3398 # CM CM CM CM
+2613 3 3396 3397 3398 3399 # CM CM CM CM
+2614 4 3397 3398 3399 3400 # CM CM CM CM
+2615 5 3398 3399 3400 3401 # CM CM CM CM
+2616 6 3399 3400 3401 3402 # CM CM CM CM
+2617 7 3400 3401 3402 3403 # CM CM CM CM
+2618 8 3401 3402 3403 3404 # CM CM CM CM
+2619 9 3402 3403 3404 3405 # CM CM CM CM
+2620 10 3403 3404 3405 3406 # CM CM CM CT
+2621 1 3407 3408 3409 3410 # HG CM CM CM
+2622 2 3408 3409 3410 3411 # CM CM CM CM
+2623 3 3409 3410 3411 3412 # CM CM CM CM
+2624 4 3410 3411 3412 3413 # CM CM CM CM
+2625 5 3411 3412 3413 3414 # CM CM CM CM
+2626 6 3412 3413 3414 3415 # CM CM CM CM
+2627 7 3413 3414 3415 3416 # CM CM CM CM
+2628 8 3414 3415 3416 3417 # CM CM CM CM
+2629 9 3415 3416 3417 3418 # CM CM CM CM
+2630 10 3416 3417 3418 3419 # CM CM CM CT
+2631 1 3420 3421 3422 3423 # HG CM CM CM
+2632 2 3421 3422 3423 3424 # CM CM CM CM
+2633 3 3422 3423 3424 3425 # CM CM CM CM
+2634 4 3423 3424 3425 3426 # CM CM CM CM
+2635 5 3424 3425 3426 3427 # CM CM CM CM
+2636 6 3425 3426 3427 3428 # CM CM CM CM
+2637 7 3426 3427 3428 3429 # CM CM CM CM
+2638 8 3427 3428 3429 3430 # CM CM CM CM
+2639 9 3428 3429 3430 3431 # CM CM CM CM
+2640 10 3429 3430 3431 3432 # CM CM CM CT
+2641 1 3433 3434 3435 3436 # HG CM CM CM
+2642 2 3434 3435 3436 3437 # CM CM CM CM
+2643 3 3435 3436 3437 3438 # CM CM CM CM
+2644 4 3436 3437 3438 3439 # CM CM CM CM
+2645 5 3437 3438 3439 3440 # CM CM CM CM
+2646 6 3438 3439 3440 3441 # CM CM CM CM
+2647 7 3439 3440 3441 3442 # CM CM CM CM
+2648 8 3440 3441 3442 3443 # CM CM CM CM
+2649 9 3441 3442 3443 3444 # CM CM CM CM
+2650 10 3442 3443 3444 3445 # CM CM CM CT
+2651 1 3446 3447 3448 3449 # HG CM CM CM
+2652 2 3447 3448 3449 3450 # CM CM CM CM
+2653 3 3448 3449 3450 3451 # CM CM CM CM
+2654 4 3449 3450 3451 3452 # CM CM CM CM
+2655 5 3450 3451 3452 3453 # CM CM CM CM
+2656 6 3451 3452 3453 3454 # CM CM CM CM
+2657 7 3452 3453 3454 3455 # CM CM CM CM
+2658 8 3453 3454 3455 3456 # CM CM CM CM
+2659 9 3454 3455 3456 3457 # CM CM CM CM
+2660 10 3455 3456 3457 3458 # CM CM CM CT
+2661 1 3459 3460 3461 3462 # HG CM CM CM
+2662 2 3460 3461 3462 3463 # CM CM CM CM
+2663 3 3461 3462 3463 3464 # CM CM CM CM
+2664 4 3462 3463 3464 3465 # CM CM CM CM
+2665 5 3463 3464 3465 3466 # CM CM CM CM
+2666 6 3464 3465 3466 3467 # CM CM CM CM
+2667 7 3465 3466 3467 3468 # CM CM CM CM
+2668 8 3466 3467 3468 3469 # CM CM CM CM
+2669 9 3467 3468 3469 3470 # CM CM CM CM
+2670 10 3468 3469 3470 3471 # CM CM CM CT
+2671 1 3472 3473 3474 3475 # HG CM CM CM
+2672 2 3473 3474 3475 3476 # CM CM CM CM
+2673 3 3474 3475 3476 3477 # CM CM CM CM
+2674 4 3475 3476 3477 3478 # CM CM CM CM
+2675 5 3476 3477 3478 3479 # CM CM CM CM
+2676 6 3477 3478 3479 3480 # CM CM CM CM
+2677 7 3478 3479 3480 3481 # CM CM CM CM
+2678 8 3479 3480 3481 3482 # CM CM CM CM
+2679 9 3480 3481 3482 3483 # CM CM CM CM
+2680 10 3481 3482 3483 3484 # CM CM CM CT
+2681 1 3485 3486 3487 3488 # HG CM CM CM
+2682 2 3486 3487 3488 3489 # CM CM CM CM
+2683 3 3487 3488 3489 3490 # CM CM CM CM
+2684 4 3488 3489 3490 3491 # CM CM CM CM
+2685 5 3489 3490 3491 3492 # CM CM CM CM
+2686 6 3490 3491 3492 3493 # CM CM CM CM
+2687 7 3491 3492 3493 3494 # CM CM CM CM
+2688 8 3492 3493 3494 3495 # CM CM CM CM
+2689 9 3493 3494 3495 3496 # CM CM CM CM
+2690 10 3494 3495 3496 3497 # CM CM CM CT
+2691 1 3498 3499 3500 3501 # HG CM CM CM
+2692 2 3499 3500 3501 3502 # CM CM CM CM
+2693 3 3500 3501 3502 3503 # CM CM CM CM
+2694 4 3501 3502 3503 3504 # CM CM CM CM
+2695 5 3502 3503 3504 3505 # CM CM CM CM
+2696 6 3503 3504 3505 3506 # CM CM CM CM
+2697 7 3504 3505 3506 3507 # CM CM CM CM
+2698 8 3505 3506 3507 3508 # CM CM CM CM
+2699 9 3506 3507 3508 3509 # CM CM CM CM
+2700 10 3507 3508 3509 3510 # CM CM CM CT
+2701 1 3511 3512 3513 3514 # HG CM CM CM
+2702 2 3512 3513 3514 3515 # CM CM CM CM
+2703 3 3513 3514 3515 3516 # CM CM CM CM
+2704 4 3514 3515 3516 3517 # CM CM CM CM
+2705 5 3515 3516 3517 3518 # CM CM CM CM
+2706 6 3516 3517 3518 3519 # CM CM CM CM
+2707 7 3517 3518 3519 3520 # CM CM CM CM
+2708 8 3518 3519 3520 3521 # CM CM CM CM
+2709 9 3519 3520 3521 3522 # CM CM CM CM
+2710 10 3520 3521 3522 3523 # CM CM CM CT
+2711 1 3524 3525 3526 3527 # HG CM CM CM
+2712 2 3525 3526 3527 3528 # CM CM CM CM
+2713 3 3526 3527 3528 3529 # CM CM CM CM
+2714 4 3527 3528 3529 3530 # CM CM CM CM
+2715 5 3528 3529 3530 3531 # CM CM CM CM
+2716 6 3529 3530 3531 3532 # CM CM CM CM
+2717 7 3530 3531 3532 3533 # CM CM CM CM
+2718 8 3531 3532 3533 3534 # CM CM CM CM
+2719 9 3532 3533 3534 3535 # CM CM CM CM
+2720 10 3533 3534 3535 3536 # CM CM CM CT
+2721 1 3537 3538 3539 3540 # HG CM CM CM
+2722 2 3538 3539 3540 3541 # CM CM CM CM
+2723 3 3539 3540 3541 3542 # CM CM CM CM
+2724 4 3540 3541 3542 3543 # CM CM CM CM
+2725 5 3541 3542 3543 3544 # CM CM CM CM
+2726 6 3542 3543 3544 3545 # CM CM CM CM
+2727 7 3543 3544 3545 3546 # CM CM CM CM
+2728 8 3544 3545 3546 3547 # CM CM CM CM
+2729 9 3545 3546 3547 3548 # CM CM CM CM
+2730 10 3546 3547 3548 3549 # CM CM CM CT
+2731 1 3550 3551 3552 3553 # HG CM CM CM
+2732 2 3551 3552 3553 3554 # CM CM CM CM
+2733 3 3552 3553 3554 3555 # CM CM CM CM
+2734 4 3553 3554 3555 3556 # CM CM CM CM
+2735 5 3554 3555 3556 3557 # CM CM CM CM
+2736 6 3555 3556 3557 3558 # CM CM CM CM
+2737 7 3556 3557 3558 3559 # CM CM CM CM
+2738 8 3557 3558 3559 3560 # CM CM CM CM
+2739 9 3558 3559 3560 3561 # CM CM CM CM
+2740 10 3559 3560 3561 3562 # CM CM CM CT
+2741 1 3563 3564 3565 3566 # HG CM CM CM
+2742 2 3564 3565 3566 3567 # CM CM CM CM
+2743 3 3565 3566 3567 3568 # CM CM CM CM
+2744 4 3566 3567 3568 3569 # CM CM CM CM
+2745 5 3567 3568 3569 3570 # CM CM CM CM
+2746 6 3568 3569 3570 3571 # CM CM CM CM
+2747 7 3569 3570 3571 3572 # CM CM CM CM
+2748 8 3570 3571 3572 3573 # CM CM CM CM
+2749 9 3571 3572 3573 3574 # CM CM CM CM
+2750 10 3572 3573 3574 3575 # CM CM CM CT
+2751 1 3576 3577 3578 3579 # HG CM CM CM
+2752 2 3577 3578 3579 3580 # CM CM CM CM
+2753 3 3578 3579 3580 3581 # CM CM CM CM
+2754 4 3579 3580 3581 3582 # CM CM CM CM
+2755 5 3580 3581 3582 3583 # CM CM CM CM
+2756 6 3581 3582 3583 3584 # CM CM CM CM
+2757 7 3582 3583 3584 3585 # CM CM CM CM
+2758 8 3583 3584 3585 3586 # CM CM CM CM
+2759 9 3584 3585 3586 3587 # CM CM CM CM
+2760 10 3585 3586 3587 3588 # CM CM CM CT
+2761 1 3589 3590 3591 3592 # HG CM CM CM
+2762 2 3590 3591 3592 3593 # CM CM CM CM
+2763 3 3591 3592 3593 3594 # CM CM CM CM
+2764 4 3592 3593 3594 3595 # CM CM CM CM
+2765 5 3593 3594 3595 3596 # CM CM CM CM
+2766 6 3594 3595 3596 3597 # CM CM CM CM
+2767 7 3595 3596 3597 3598 # CM CM CM CM
+2768 8 3596 3597 3598 3599 # CM CM CM CM
+2769 9 3597 3598 3599 3600 # CM CM CM CM
+2770 10 3598 3599 3600 3601 # CM CM CM CT
+2771 1 3602 3603 3604 3605 # HG CM CM CM
+2772 2 3603 3604 3605 3606 # CM CM CM CM
+2773 3 3604 3605 3606 3607 # CM CM CM CM
+2774 4 3605 3606 3607 3608 # CM CM CM CM
+2775 5 3606 3607 3608 3609 # CM CM CM CM
+2776 6 3607 3608 3609 3610 # CM CM CM CM
+2777 7 3608 3609 3610 3611 # CM CM CM CM
+2778 8 3609 3610 3611 3612 # CM CM CM CM
+2779 9 3610 3611 3612 3613 # CM CM CM CM
+2780 10 3611 3612 3613 3614 # CM CM CM CT
+2781 1 3615 3616 3617 3618 # HG CM CM CM
+2782 2 3616 3617 3618 3619 # CM CM CM CM
+2783 3 3617 3618 3619 3620 # CM CM CM CM
+2784 4 3618 3619 3620 3621 # CM CM CM CM
+2785 5 3619 3620 3621 3622 # CM CM CM CM
+2786 6 3620 3621 3622 3623 # CM CM CM CM
+2787 7 3621 3622 3623 3624 # CM CM CM CM
+2788 8 3622 3623 3624 3625 # CM CM CM CM
+2789 9 3623 3624 3625 3626 # CM CM CM CM
+2790 10 3624 3625 3626 3627 # CM CM CM CT
+2791 1 3628 3629 3630 3631 # HG CM CM CM
+2792 2 3629 3630 3631 3632 # CM CM CM CM
+2793 3 3630 3631 3632 3633 # CM CM CM CM
+2794 4 3631 3632 3633 3634 # CM CM CM CM
+2795 5 3632 3633 3634 3635 # CM CM CM CM
+2796 6 3633 3634 3635 3636 # CM CM CM CM
+2797 7 3634 3635 3636 3637 # CM CM CM CM
+2798 8 3635 3636 3637 3638 # CM CM CM CM
+2799 9 3636 3637 3638 3639 # CM CM CM CM
+2800 10 3637 3638 3639 3640 # CM CM CM CT
+2801 1 3641 3642 3643 3644 # HG CM CM CM
+2802 2 3642 3643 3644 3645 # CM CM CM CM
+2803 3 3643 3644 3645 3646 # CM CM CM CM
+2804 4 3644 3645 3646 3647 # CM CM CM CM
+2805 5 3645 3646 3647 3648 # CM CM CM CM
+2806 6 3646 3647 3648 3649 # CM CM CM CM
+2807 7 3647 3648 3649 3650 # CM CM CM CM
+2808 8 3648 3649 3650 3651 # CM CM CM CM
+2809 9 3649 3650 3651 3652 # CM CM CM CM
+2810 10 3650 3651 3652 3653 # CM CM CM CT
+2811 1 3654 3655 3656 3657 # HG CM CM CM
+2812 2 3655 3656 3657 3658 # CM CM CM CM
+2813 3 3656 3657 3658 3659 # CM CM CM CM
+2814 4 3657 3658 3659 3660 # CM CM CM CM
+2815 5 3658 3659 3660 3661 # CM CM CM CM
+2816 6 3659 3660 3661 3662 # CM CM CM CM
+2817 7 3660 3661 3662 3663 # CM CM CM CM
+2818 8 3661 3662 3663 3664 # CM CM CM CM
+2819 9 3662 3663 3664 3665 # CM CM CM CM
+2820 10 3663 3664 3665 3666 # CM CM CM CT
+2821 1 3667 3668 3669 3670 # HG CM CM CM
+2822 2 3668 3669 3670 3671 # CM CM CM CM
+2823 3 3669 3670 3671 3672 # CM CM CM CM
+2824 4 3670 3671 3672 3673 # CM CM CM CM
+2825 5 3671 3672 3673 3674 # CM CM CM CM
+2826 6 3672 3673 3674 3675 # CM CM CM CM
+2827 7 3673 3674 3675 3676 # CM CM CM CM
+2828 8 3674 3675 3676 3677 # CM CM CM CM
+2829 9 3675 3676 3677 3678 # CM CM CM CM
+2830 10 3676 3677 3678 3679 # CM CM CM CT
+2831 1 3680 3681 3682 3683 # HG CM CM CM
+2832 2 3681 3682 3683 3684 # CM CM CM CM
+2833 3 3682 3683 3684 3685 # CM CM CM CM
+2834 4 3683 3684 3685 3686 # CM CM CM CM
+2835 5 3684 3685 3686 3687 # CM CM CM CM
+2836 6 3685 3686 3687 3688 # CM CM CM CM
+2837 7 3686 3687 3688 3689 # CM CM CM CM
+2838 8 3687 3688 3689 3690 # CM CM CM CM
+2839 9 3688 3689 3690 3691 # CM CM CM CM
+2840 10 3689 3690 3691 3692 # CM CM CM CT
+2841 1 3693 3694 3695 3696 # HG CM CM CM
+2842 2 3694 3695 3696 3697 # CM CM CM CM
+2843 3 3695 3696 3697 3698 # CM CM CM CM
+2844 4 3696 3697 3698 3699 # CM CM CM CM
+2845 5 3697 3698 3699 3700 # CM CM CM CM
+2846 6 3698 3699 3700 3701 # CM CM CM CM
+2847 7 3699 3700 3701 3702 # CM CM CM CM
+2848 8 3700 3701 3702 3703 # CM CM CM CM
+2849 9 3701 3702 3703 3704 # CM CM CM CM
+2850 10 3702 3703 3704 3705 # CM CM CM CT
+2851 1 3706 3707 3708 3709 # HG CM CM CM
+2852 2 3707 3708 3709 3710 # CM CM CM CM
+2853 3 3708 3709 3710 3711 # CM CM CM CM
+2854 4 3709 3710 3711 3712 # CM CM CM CM
+2855 5 3710 3711 3712 3713 # CM CM CM CM
+2856 6 3711 3712 3713 3714 # CM CM CM CM
+2857 7 3712 3713 3714 3715 # CM CM CM CM
+2858 8 3713 3714 3715 3716 # CM CM CM CM
+2859 9 3714 3715 3716 3717 # CM CM CM CM
+2860 10 3715 3716 3717 3718 # CM CM CM CT
+2861 1 3719 3720 3721 3722 # HG CM CM CM
+2862 2 3720 3721 3722 3723 # CM CM CM CM
+2863 3 3721 3722 3723 3724 # CM CM CM CM
+2864 4 3722 3723 3724 3725 # CM CM CM CM
+2865 5 3723 3724 3725 3726 # CM CM CM CM
+2866 6 3724 3725 3726 3727 # CM CM CM CM
+2867 7 3725 3726 3727 3728 # CM CM CM CM
+2868 8 3726 3727 3728 3729 # CM CM CM CM
+2869 9 3727 3728 3729 3730 # CM CM CM CM
+2870 10 3728 3729 3730 3731 # CM CM CM CT
+2871 1 3732 3733 3734 3735 # HG CM CM CM
+2872 2 3733 3734 3735 3736 # CM CM CM CM
+2873 3 3734 3735 3736 3737 # CM CM CM CM
+2874 4 3735 3736 3737 3738 # CM CM CM CM
+2875 5 3736 3737 3738 3739 # CM CM CM CM
+2876 6 3737 3738 3739 3740 # CM CM CM CM
+2877 7 3738 3739 3740 3741 # CM CM CM CM
+2878 8 3739 3740 3741 3742 # CM CM CM CM
+2879 9 3740 3741 3742 3743 # CM CM CM CM
+2880 10 3741 3742 3743 3744 # CM CM CM CT
+2881 1 3745 3746 3747 3748 # HG CM CM CM
+2882 2 3746 3747 3748 3749 # CM CM CM CM
+2883 3 3747 3748 3749 3750 # CM CM CM CM
+2884 4 3748 3749 3750 3751 # CM CM CM CM
+2885 5 3749 3750 3751 3752 # CM CM CM CM
+2886 6 3750 3751 3752 3753 # CM CM CM CM
+2887 7 3751 3752 3753 3754 # CM CM CM CM
+2888 8 3752 3753 3754 3755 # CM CM CM CM
+2889 9 3753 3754 3755 3756 # CM CM CM CM
+2890 10 3754 3755 3756 3757 # CM CM CM CT
+2891 1 3758 3759 3760 3761 # HG CM CM CM
+2892 2 3759 3760 3761 3762 # CM CM CM CM
+2893 3 3760 3761 3762 3763 # CM CM CM CM
+2894 4 3761 3762 3763 3764 # CM CM CM CM
+2895 5 3762 3763 3764 3765 # CM CM CM CM
+2896 6 3763 3764 3765 3766 # CM CM CM CM
+2897 7 3764 3765 3766 3767 # CM CM CM CM
+2898 8 3765 3766 3767 3768 # CM CM CM CM
+2899 9 3766 3767 3768 3769 # CM CM CM CM
+2900 10 3767 3768 3769 3770 # CM CM CM CT
+2901 1 3771 3772 3773 3774 # HG CM CM CM
+2902 2 3772 3773 3774 3775 # CM CM CM CM
+2903 3 3773 3774 3775 3776 # CM CM CM CM
+2904 4 3774 3775 3776 3777 # CM CM CM CM
+2905 5 3775 3776 3777 3778 # CM CM CM CM
+2906 6 3776 3777 3778 3779 # CM CM CM CM
+2907 7 3777 3778 3779 3780 # CM CM CM CM
+2908 8 3778 3779 3780 3781 # CM CM CM CM
+2909 9 3779 3780 3781 3782 # CM CM CM CM
+2910 10 3780 3781 3782 3783 # CM CM CM CT
+2911 1 3784 3785 3786 3787 # HG CM CM CM
+2912 2 3785 3786 3787 3788 # CM CM CM CM
+2913 3 3786 3787 3788 3789 # CM CM CM CM
+2914 4 3787 3788 3789 3790 # CM CM CM CM
+2915 5 3788 3789 3790 3791 # CM CM CM CM
+2916 6 3789 3790 3791 3792 # CM CM CM CM
+2917 7 3790 3791 3792 3793 # CM CM CM CM
+2918 8 3791 3792 3793 3794 # CM CM CM CM
+2919 9 3792 3793 3794 3795 # CM CM CM CM
+2920 10 3793 3794 3795 3796 # CM CM CM CT
+2921 1 3797 3798 3799 3800 # HG CM CM CM
+2922 2 3798 3799 3800 3801 # CM CM CM CM
+2923 3 3799 3800 3801 3802 # CM CM CM CM
+2924 4 3800 3801 3802 3803 # CM CM CM CM
+2925 5 3801 3802 3803 3804 # CM CM CM CM
+2926 6 3802 3803 3804 3805 # CM CM CM CM
+2927 7 3803 3804 3805 3806 # CM CM CM CM
+2928 8 3804 3805 3806 3807 # CM CM CM CM
+2929 9 3805 3806 3807 3808 # CM CM CM CM
+2930 10 3806 3807 3808 3809 # CM CM CM CT
+2931 1 3810 3811 3812 3813 # HG CM CM CM
+2932 2 3811 3812 3813 3814 # CM CM CM CM
+2933 3 3812 3813 3814 3815 # CM CM CM CM
+2934 4 3813 3814 3815 3816 # CM CM CM CM
+2935 5 3814 3815 3816 3817 # CM CM CM CM
+2936 6 3815 3816 3817 3818 # CM CM CM CM
+2937 7 3816 3817 3818 3819 # CM CM CM CM
+2938 8 3817 3818 3819 3820 # CM CM CM CM
+2939 9 3818 3819 3820 3821 # CM CM CM CM
+2940 10 3819 3820 3821 3822 # CM CM CM CT
+2941 1 3823 3824 3825 3826 # HG CM CM CM
+2942 2 3824 3825 3826 3827 # CM CM CM CM
+2943 3 3825 3826 3827 3828 # CM CM CM CM
+2944 4 3826 3827 3828 3829 # CM CM CM CM
+2945 5 3827 3828 3829 3830 # CM CM CM CM
+2946 6 3828 3829 3830 3831 # CM CM CM CM
+2947 7 3829 3830 3831 3832 # CM CM CM CM
+2948 8 3830 3831 3832 3833 # CM CM CM CM
+2949 9 3831 3832 3833 3834 # CM CM CM CM
+2950 10 3832 3833 3834 3835 # CM CM CM CT
+2951 1 3836 3837 3838 3839 # HG CM CM CM
+2952 2 3837 3838 3839 3840 # CM CM CM CM
+2953 3 3838 3839 3840 3841 # CM CM CM CM
+2954 4 3839 3840 3841 3842 # CM CM CM CM
+2955 5 3840 3841 3842 3843 # CM CM CM CM
+2956 6 3841 3842 3843 3844 # CM CM CM CM
+2957 7 3842 3843 3844 3845 # CM CM CM CM
+2958 8 3843 3844 3845 3846 # CM CM CM CM
+2959 9 3844 3845 3846 3847 # CM CM CM CM
+2960 10 3845 3846 3847 3848 # CM CM CM CT
+2961 1 3849 3850 3851 3852 # HG CM CM CM
+2962 2 3850 3851 3852 3853 # CM CM CM CM
+2963 3 3851 3852 3853 3854 # CM CM CM CM
+2964 4 3852 3853 3854 3855 # CM CM CM CM
+2965 5 3853 3854 3855 3856 # CM CM CM CM
+2966 6 3854 3855 3856 3857 # CM CM CM CM
+2967 7 3855 3856 3857 3858 # CM CM CM CM
+2968 8 3856 3857 3858 3859 # CM CM CM CM
+2969 9 3857 3858 3859 3860 # CM CM CM CM
+2970 10 3858 3859 3860 3861 # CM CM CM CT
+2971 1 3862 3863 3864 3865 # HG CM CM CM
+2972 2 3863 3864 3865 3866 # CM CM CM CM
+2973 3 3864 3865 3866 3867 # CM CM CM CM
+2974 4 3865 3866 3867 3868 # CM CM CM CM
+2975 5 3866 3867 3868 3869 # CM CM CM CM
+2976 6 3867 3868 3869 3870 # CM CM CM CM
+2977 7 3868 3869 3870 3871 # CM CM CM CM
+2978 8 3869 3870 3871 3872 # CM CM CM CM
+2979 9 3870 3871 3872 3873 # CM CM CM CM
+2980 10 3871 3872 3873 3874 # CM CM CM CT
+2981 1 3875 3876 3877 3878 # HG CM CM CM
+2982 2 3876 3877 3878 3879 # CM CM CM CM
+2983 3 3877 3878 3879 3880 # CM CM CM CM
+2984 4 3878 3879 3880 3881 # CM CM CM CM
+2985 5 3879 3880 3881 3882 # CM CM CM CM
+2986 6 3880 3881 3882 3883 # CM CM CM CM
+2987 7 3881 3882 3883 3884 # CM CM CM CM
+2988 8 3882 3883 3884 3885 # CM CM CM CM
+2989 9 3883 3884 3885 3886 # CM CM CM CM
+2990 10 3884 3885 3886 3887 # CM CM CM CT
+2991 1 3888 3889 3890 3891 # HG CM CM CM
+2992 2 3889 3890 3891 3892 # CM CM CM CM
+2993 3 3890 3891 3892 3893 # CM CM CM CM
+2994 4 3891 3892 3893 3894 # CM CM CM CM
+2995 5 3892 3893 3894 3895 # CM CM CM CM
+2996 6 3893 3894 3895 3896 # CM CM CM CM
+2997 7 3894 3895 3896 3897 # CM CM CM CM
+2998 8 3895 3896 3897 3898 # CM CM CM CM
+2999 9 3896 3897 3898 3899 # CM CM CM CM
+3000 10 3897 3898 3899 3900 # CM CM CM CT
diff --git a/examples/USER/gauss-diel/in.gauss-diel b/examples/USER/gauss-diel/in.gauss-diel
new file mode 100644
index 000000000..3e2be5b4d
--- /dev/null
+++ b/examples/USER/gauss-diel/in.gauss-diel
@@ -0,0 +1,93 @@
+# Ionic surfactant system: S12S
+
+units lj
+dimension 3
+atom_style full
+
+read_data data.gauss-diel
+
+pair_style hybrid/overlay &
+ lj/cut 3.5 &
+ lj/cut/coul/long 8.0 &
+ gauss/cut 3.4 &
+ coul/diel 2.5
+pair_modify shift yes
+
+dielectric 0.4255
+kspace_style pppm 0.0001
+kspace_modify mesh 30 30 30 order 3
+
+bond_style harmonic
+angle_style harmonic
+dihedral_style opls
+
+pair_coeff 1 1 lj/cut/coul/long 0.5 1.775 3.268 # HG HG
+pair_coeff 1 1 gauss/cut 0.1 2.549 0.1525
+pair_coeff 1 2 lj/cut 0.31623 1.5329 1.7206 # HG CM
+pair_coeff 1 3 lj/cut 0.31623 1.5329 1.7206 # HG CT
+pair_coeff 1 4 lj/cut/coul/long 0.05 1.75 4.375 # HG CI
+pair_coeff 1 4 gauss/cut 0.2805 1.45 0.112
+pair_coeff 1 4 coul/diel 78. 1.375 0.112
+pair_coeff 2 2 lj/cut 0.2000 1.2910 3.2275 # CM CM
+pair_coeff 2 3 lj/cut 0.2000 1.2910 3.2275 # CM CT
+pair_coeff 2 4 lj/cut 0.4472 1.1455 1.28585 # CM CI
+pair_coeff 3 3 lj/cut 1.95 1.291 3.2275 # CT CT
+pair_coeff 3 4 lj/cut 0.4472 1.1455 1.28585 # CT CI
+pair_coeff 4 4 lj/cut/coul/long 1.0 10. 1.12246 # CI CI
+
+bond_coeff 1 12650.0000 0.7500 # HG CM FROM TOP
+bond_coeff 2 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 3 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 4 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 5 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 6 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 7 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 8 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 9 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 10 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 11 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 12 12650.0000 0.5000 # CM CT FROM TOP
+
+angle_coeff 1 85.7600 109.5000 # HG CM CM FROM TOP
+angle_coeff 2 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 3 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 4 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 5 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 6 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 7 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 8 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 9 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 10 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 11 85.7600 111.0000 # CM CM CT FROM TOP
+
+dihedral_coeff 1 5.7431 -2.53241 5.0742 0.0 # HG CM CM CM FROM TOP
+dihedral_coeff 2 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 3 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 4 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 5 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 6 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 7 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 8 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 9 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 10 5.7431 -2.53241 5.0742 0.0 # CM CM CM CT FROM TOP
+
+timestep 0.002
+
+reset_timestep 0
+
+group cions type 4
+group sds subtract all cions
+
+velocity all create 1. 87287 dist gaussian
+
+neighbor 1.5 multi
+neigh_modify exclude molecule sds
+neigh_modify every 5 delay 0 check yes
+
+fix 1 all nve/limit 0.2
+fix 2 all langevin 1.0 1.0 0.05 18273
+
+thermo_style multi
+thermo 500
+
+run 2000
diff --git a/examples/USER/gauss-diel/in.gauss-diel-cg b/examples/USER/gauss-diel/in.gauss-diel-cg
new file mode 100644
index 000000000..ed2101622
--- /dev/null
+++ b/examples/USER/gauss-diel/in.gauss-diel-cg
@@ -0,0 +1,93 @@
+# Ionic surfactant system: S12S
+
+units lj
+dimension 3
+atom_style full
+
+read_data data.gauss-diel
+
+pair_style hybrid/overlay &
+ lj/cut 3.5 &
+ lj/cut/coul/long 8.0 18.0 &
+ gauss/cut 3.4 &
+ coul/diel 2.5
+pair_modify shift yes
+
+dielectric 0.4255
+kspace_style pppm/cg 0.0001
+kspace_modify mesh 12 12 12 order 3
+
+bond_style harmonic
+angle_style harmonic
+dihedral_style opls
+
+pair_coeff 1 1 lj/cut/coul/long 0.5 1.775 3.268 # HG HG
+pair_coeff 1 1 gauss/cut 0.1 2.549 0.1525
+pair_coeff 1 2 lj/cut 0.31623 1.5329 1.7206 # HG CM
+pair_coeff 1 3 lj/cut 0.31623 1.5329 1.7206 # HG CT
+pair_coeff 1 4 lj/cut/coul/long 0.05 1.75 4.375 # HG CI
+pair_coeff 1 4 gauss/cut 0.2805 1.45 0.112
+pair_coeff 1 4 coul/diel 78. 1.375 0.112
+pair_coeff 2 2 lj/cut 0.2000 1.2910 3.2275 # CM CM
+pair_coeff 2 3 lj/cut 0.2000 1.2910 3.2275 # CM CT
+pair_coeff 2 4 lj/cut 0.4472 1.1455 1.28585 # CM CI
+pair_coeff 3 3 lj/cut 1.95 1.291 3.2275 # CT CT
+pair_coeff 3 4 lj/cut 0.4472 1.1455 1.28585 # CT CI
+pair_coeff 4 4 lj/cut/coul/long 1.0 10. 1.12246 # CI CI
+
+bond_coeff 1 12650.0000 0.7500 # HG CM FROM TOP
+bond_coeff 2 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 3 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 4 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 5 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 6 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 7 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 8 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 9 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 10 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 11 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 12 12650.0000 0.5000 # CM CT FROM TOP
+
+angle_coeff 1 85.7600 109.5000 # HG CM CM FROM TOP
+angle_coeff 2 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 3 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 4 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 5 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 6 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 7 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 8 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 9 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 10 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 11 85.7600 111.0000 # CM CM CT FROM TOP
+
+dihedral_coeff 1 5.7431 -2.53241 5.0742 0.0 # HG CM CM CM FROM TOP
+dihedral_coeff 2 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 3 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 4 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 5 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 6 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 7 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 8 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 9 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 10 5.7431 -2.53241 5.0742 0.0 # CM CM CM CT FROM TOP
+
+timestep 0.002
+
+reset_timestep 0
+
+group cions type 4
+group sds subtract all cions
+
+velocity all create 1. 87287 dist gaussian
+
+neighbor 1.5 multi
+neigh_modify exclude molecule sds
+neigh_modify every 5 delay 0 check yes
+
+fix 1 all nve/limit 0.2
+fix 2 all langevin 1.0 1.0 0.05 18273
+
+thermo_style multi
+thermo 500
+
+run 2000
diff --git a/examples/USER/gauss-diel/in.gauss-diel-split b/examples/USER/gauss-diel/in.gauss-diel-split
new file mode 100644
index 000000000..f13859863
--- /dev/null
+++ b/examples/USER/gauss-diel/in.gauss-diel-split
@@ -0,0 +1,96 @@
+# Ionic surfactant system: S12S
+
+units lj
+dimension 3
+atom_style full
+
+read_data data.gauss-diel
+
+pair_style hybrid/overlay &
+ lj/cut 3.5 &
+ coul/long 18.0 &
+ gauss/cut 3.4 &
+ coul/diel 2.5
+pair_modify shift yes
+
+dielectric 0.4255
+kspace_style pppm/cg 0.0001
+kspace_modify mesh 12 12 12 order 3
+
+bond_style harmonic
+angle_style harmonic
+dihedral_style opls
+
+pair_coeff 1 1 lj/cut 0.5 1.775 3.268 # HG HG
+pair_coeff 1 1 coul/long # HG HG
+pair_coeff 1 1 gauss/cut 0.1 2.549 0.1525
+pair_coeff 1 2 lj/cut 0.31623 1.5329 1.7206 # HG CM
+pair_coeff 1 3 lj/cut 0.31623 1.5329 1.7206 # HG CT
+pair_coeff 1 4 lj/cut 0.05 1.75 4.375 # HG CI
+pair_coeff 1 4 coul/long # HG CI
+pair_coeff 1 4 gauss/cut 0.2805 1.45 0.112
+pair_coeff 1 4 coul/diel 78. 1.375 0.112
+pair_coeff 2 2 lj/cut 0.2000 1.2910 3.2275 # CM CM
+pair_coeff 2 3 lj/cut 0.2000 1.2910 3.2275 # CM CT
+pair_coeff 2 4 lj/cut 0.4472 1.1455 1.28585 # CM CI
+pair_coeff 3 3 lj/cut 1.95 1.291 3.2275 # CT CT
+pair_coeff 3 4 lj/cut 0.4472 1.1455 1.28585 # CT CI
+pair_coeff 4 4 lj/cut 1.0 10. 1.12246 # CI CI
+pair_coeff 4 4 coul/long # CI CI
+
+bond_coeff 1 12650.0000 0.7500 # HG CM FROM TOP
+bond_coeff 2 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 3 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 4 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 5 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 6 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 7 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 8 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 9 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 10 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 11 12650.0000 0.5000 # CM CM FROM TOP
+bond_coeff 12 12650.0000 0.5000 # CM CT FROM TOP
+
+angle_coeff 1 85.7600 109.5000 # HG CM CM FROM TOP
+angle_coeff 2 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 3 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 4 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 5 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 6 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 7 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 8 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 9 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 10 85.7600 111.0000 # CM CM CM FROM TOP
+angle_coeff 11 85.7600 111.0000 # CM CM CT FROM TOP
+
+dihedral_coeff 1 5.7431 -2.53241 5.0742 0.0 # HG CM CM CM FROM TOP
+dihedral_coeff 2 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 3 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 4 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 5 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 6 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 7 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 8 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 9 5.7431 -2.53241 5.0742 0.0 # CM CM CM CM FROM TOP
+dihedral_coeff 10 5.7431 -2.53241 5.0742 0.0 # CM CM CM CT FROM TOP
+
+timestep 0.002
+
+reset_timestep 0
+
+group cions type 4
+group sds subtract all cions
+
+velocity all create 1. 87287 dist gaussian
+
+neighbor 1.5 multi
+neigh_modify exclude molecule sds
+neigh_modify every 5 delay 0 check yes
+
+fix 1 all nve/limit 0.2
+fix 2 all langevin 1.0 1.0 0.05 18273
+
+thermo_style multi
+thermo 500
+
+run 2000
diff --git a/examples/USER/gauss-diel/log.gauss-diel b/examples/USER/gauss-diel/log.gauss-diel
new file mode 100644
index 000000000..ba38c7f96
--- /dev/null
+++ b/examples/USER/gauss-diel/log.gauss-diel
@@ -0,0 +1,75 @@
+LAMMPS (29 Nov 2011)
+ 1 = max bonds/atom
+ 1 = max angles/atom
+ 1 = max dihedrals/atom
+ orthogonal box = (-35 -35 -35) to (35 35 35)
+ 2 by 2 by 2 MPI processor grid
+ 4200 atoms
+ 3600 bonds
+ 3300 angles
+ 3000 dihedrals
+ 2 = max # of 1-2 neighbors
+ 2 = max # of 1-3 neighbors
+ 4 = max # of 1-4 neighbors
+ 6 = max # of special neighbors
+300 atoms in group cions
+3900 atoms in group sds
+PPPM initialization ...
+ G vector = 0.25544
+ grid = 30 30 30
+ stencil order = 3
+ RMS precision = 0.000403643
+ using single precision FFTs
+ brick FFT buffer size/proc = 5832 3600 1944
+Memory usage per processor = 6.84746 Mbytes
+---------------- Step 0 ----- CPU = 0.0000 (sec) ----------------
+TotEng = 9.9401 KinEng = 1.4996 Temp = 1.0000
+PotEng = 8.4405 E_bond = 0.0036 E_angle = 0.1237
+E_dihed = 0.3185 E_impro = 0.0000 E_vdwl = 8.0100
+E_coul = -0.0127 E_long = -0.0025 Press = 0.4086
+---------------- Step 500 ----- CPU = 1.0851 (sec) ----------------
+TotEng = 2.7534 KinEng = 1.4930 Temp = 0.9956
+PotEng = 1.2604 E_bond = 0.4577 E_angle = 0.3876
+E_dihed = 0.4193 E_impro = 0.0000 E_vdwl = -0.0025
+E_coul = 0.0004 E_long = -0.0021 Press = 0.0065
+---------------- Step 1000 ----- CPU = 2.1498 (sec) ----------------
+TotEng = 2.7370 KinEng = 1.4592 Temp = 0.9731
+PotEng = 1.2778 E_bond = 0.4499 E_angle = 0.3944
+E_dihed = 0.4387 E_impro = 0.0000 E_vdwl = -0.0032
+E_coul = 0.0004 E_long = -0.0023 Press = 0.0181
+---------------- Step 1500 ----- CPU = 3.2197 (sec) ----------------
+TotEng = 2.8177 KinEng = 1.4932 Temp = 0.9957
+PotEng = 1.3245 E_bond = 0.4712 E_angle = 0.3840
+E_dihed = 0.4761 E_impro = 0.0000 E_vdwl = -0.0048
+E_coul = 0.0002 E_long = -0.0024 Press = 0.0038
+---------------- Step 2000 ----- CPU = 4.2883 (sec) ----------------
+TotEng = 2.8437 KinEng = 1.5229 Temp = 1.0155
+PotEng = 1.3208 E_bond = 0.4463 E_angle = 0.3939
+E_dihed = 0.4881 E_impro = 0.0000 E_vdwl = -0.0051
+E_coul = 0.0002 E_long = -0.0027 Press = -0.0019
+Loop time of 4.28834 on 8 procs for 2000 steps with 4200 atoms
+
+ Pair time (%) = 0.0716868 (1.67167)
+ Bond time (%) = 0.527554 (12.302)
+Kspace time (%) = 3.19648 (74.5388)
+Neigh time (%) = 0.0167304 (0.390136)
+ Comm time (%) = 0.359536 (8.38402)
+Output time (%) = 0.000303894 (0.00708652)
+Modify time (%) = 0.0936236 (2.18321)
+Other time (%) = 0.022429 (0.523024)
+
+FFT time (% of Kspce) = 2.18 (68.2001)
+FFT Gflps 3d (1d only) = 5.05498 7.6769
+
+Nlocal: 525 ave 625 max 428 min
+Histogram: 1 1 0 2 0 1 1 1 0 1
+Nghost: 1405.5 ave 1627 max 1279 min
+Histogram: 2 0 1 3 1 0 0 0 0 1
+Neighs: 1338.88 ave 1773 max 916 min
+Histogram: 1 1 1 1 0 0 1 1 1 1
+
+Total # of neighbors = 10711
+Ave neighs/atom = 2.55024
+Ave special neighs/atom = 4.71429
+Neighbor list builds = 14
+Dangerous builds = 2
diff --git a/examples/USER/gauss-diel/log.gauss-diel-cg b/examples/USER/gauss-diel/log.gauss-diel-cg
new file mode 100644
index 000000000..0fac7068f
--- /dev/null
+++ b/examples/USER/gauss-diel/log.gauss-diel-cg
@@ -0,0 +1,78 @@
+LAMMPS (29 Nov 2011)
+ 1 = max bonds/atom
+ 1 = max angles/atom
+ 1 = max dihedrals/atom
+ orthogonal box = (-35 -35 -35) to (35 35 35)
+ 2 by 2 by 2 MPI processor grid
+ 4200 atoms
+ 3600 bonds
+ 3300 angles
+ 3000 dihedrals
+ 2 = max # of 1-2 neighbors
+ 2 = max # of 1-3 neighbors
+ 4 = max # of 1-4 neighbors
+ 6 = max # of special neighbors
+300 atoms in group cions
+3900 atoms in group sds
+PPPM initialization ...
+ G vector = 0.109922
+ grid = 12 12 12
+ stencil order = 3
+ RMS precision = 0.000349313
+ using single precision FFTs
+ brick FFT buffer size/proc = 729 288 486
+ PPPM/cg optimization cutoff: 1e-05
+ Total charged atoms: 14.3%
+ Min/max charged atoms/proc: 11.3% 16.9%
+Memory usage per processor = 8.09396 Mbytes
+---------------- Step 0 ----- CPU = 0.0000 (sec) ----------------
+TotEng = 9.9401 KinEng = 1.4996 Temp = 1.0000
+PotEng = 8.4405 E_bond = 0.0036 E_angle = 0.1237
+E_dihed = 0.3185 E_impro = 0.0000 E_vdwl = 8.0100
+E_coul = -0.0116 E_long = -0.0036 Press = 0.4086
+---------------- Step 500 ----- CPU = 0.4412 (sec) ----------------
+TotEng = 2.7881 KinEng = 1.5273 Temp = 1.0184
+PotEng = 1.2608 E_bond = 0.4529 E_angle = 0.3844
+E_dihed = 0.4277 E_impro = 0.0000 E_vdwl = -0.0022
+E_coul = 0.0016 E_long = -0.0035 Press = -0.0027
+---------------- Step 1000 ----- CPU = 0.8284 (sec) ----------------
+TotEng = 2.7685 KinEng = 1.4797 Temp = 0.9867
+PotEng = 1.2888 E_bond = 0.4669 E_angle = 0.3879
+E_dihed = 0.4388 E_impro = 0.0000 E_vdwl = -0.0020
+E_coul = 0.0011 E_long = -0.0038 Press = -0.0003
+---------------- Step 1500 ----- CPU = 1.2143 (sec) ----------------
+TotEng = 2.8092 KinEng = 1.5019 Temp = 1.0015
+PotEng = 1.3073 E_bond = 0.4716 E_angle = 0.3748
+E_dihed = 0.4673 E_impro = 0.0000 E_vdwl = -0.0034
+E_coul = 0.0010 E_long = -0.0039 Press = -0.0056
+---------------- Step 2000 ----- CPU = 1.7053 (sec) ----------------
+TotEng = 2.8481 KinEng = 1.5096 Temp = 1.0066
+PotEng = 1.3386 E_bond = 0.4741 E_angle = 0.3764
+E_dihed = 0.4952 E_impro = 0.0000 E_vdwl = -0.0037
+E_coul = 0.0005 E_long = -0.0040 Press = 0.0018
+Loop time of 1.70533 on 8 procs for 2000 steps with 4200 atoms
+
+ Pair time (%) = 0.203692 (11.9444)
+ Bond time (%) = 0.484542 (28.4133)
+Kspace time (%) = 0.45694 (26.7948)
+Neigh time (%) = 0.045952 (2.6946)
+ Comm time (%) = 0.402121 (23.5802)
+Output time (%) = 0.000266433 (0.0156235)
+Modify time (%) = 0.0844524 (4.95225)
+Other time (%) = 0.0273688 (1.60489)
+
+FFT time (% of Kspce) = 0.153959 (33.6934)
+FFT Gflps 3d (1d only) = 3.34681 9.67846
+
+Nlocal: 525 ave 625 max 427 min
+Histogram: 1 1 0 2 0 1 0 2 0 1
+Nghost: 4466 ave 4640 max 4345 min
+Histogram: 2 1 0 0 1 2 1 0 0 1
+Neighs: 3141.38 ave 3956 max 2489 min
+Histogram: 1 2 1 1 0 0 0 1 0 2
+
+Total # of neighbors = 25131
+Ave neighs/atom = 5.98357
+Ave special neighs/atom = 4.71429
+Neighbor list builds = 14
+Dangerous builds = 2
diff --git a/examples/USER/gauss-diel/log.gauss-diel-split b/examples/USER/gauss-diel/log.gauss-diel-split
new file mode 100644
index 000000000..1072d5289
--- /dev/null
+++ b/examples/USER/gauss-diel/log.gauss-diel-split
@@ -0,0 +1,78 @@
+LAMMPS (29 Nov 2011)
+ 1 = max bonds/atom
+ 1 = max angles/atom
+ 1 = max dihedrals/atom
+ orthogonal box = (-35 -35 -35) to (35 35 35)
+ 2 by 2 by 2 MPI processor grid
+ 4200 atoms
+ 3600 bonds
+ 3300 angles
+ 3000 dihedrals
+ 2 = max # of 1-2 neighbors
+ 2 = max # of 1-3 neighbors
+ 4 = max # of 1-4 neighbors
+ 6 = max # of special neighbors
+300 atoms in group cions
+3900 atoms in group sds
+PPPM initialization ...
+ G vector = 0.109922
+ grid = 12 12 12
+ stencil order = 3
+ RMS precision = 0.000349313
+ using single precision FFTs
+ brick FFT buffer size/proc = 729 288 486
+ PPPM/cg optimization cutoff: 1e-05
+ Total charged atoms: 14.3%
+ Min/max charged atoms/proc: 11.3% 16.9%
+Memory usage per processor = 7.70368 Mbytes
+---------------- Step 0 ----- CPU = 0.0000 (sec) ----------------
+TotEng = 9.9401 KinEng = 1.4996 Temp = 1.0000
+PotEng = 8.4405 E_bond = 0.0036 E_angle = 0.1237
+E_dihed = 0.3185 E_impro = 0.0000 E_vdwl = 8.0100
+E_coul = -0.0116 E_long = -0.0036 Press = 0.4086
+---------------- Step 500 ----- CPU = 0.4192 (sec) ----------------
+TotEng = 2.7881 KinEng = 1.5273 Temp = 1.0184
+PotEng = 1.2608 E_bond = 0.4529 E_angle = 0.3844
+E_dihed = 0.4277 E_impro = 0.0000 E_vdwl = -0.0022
+E_coul = 0.0016 E_long = -0.0035 Press = -0.0027
+---------------- Step 1000 ----- CPU = 0.8205 (sec) ----------------
+TotEng = 2.7685 KinEng = 1.4797 Temp = 0.9867
+PotEng = 1.2888 E_bond = 0.4669 E_angle = 0.3879
+E_dihed = 0.4388 E_impro = 0.0000 E_vdwl = -0.0020
+E_coul = 0.0011 E_long = -0.0038 Press = -0.0003
+---------------- Step 1500 ----- CPU = 1.2196 (sec) ----------------
+TotEng = 2.8092 KinEng = 1.5019 Temp = 1.0015
+PotEng = 1.3073 E_bond = 0.4716 E_angle = 0.3748
+E_dihed = 0.4673 E_impro = 0.0000 E_vdwl = -0.0034
+E_coul = 0.0010 E_long = -0.0039 Press = -0.0056
+---------------- Step 2000 ----- CPU = 1.6195 (sec) ----------------
+TotEng = 2.8481 KinEng = 1.5096 Temp = 1.0066
+PotEng = 1.3386 E_bond = 0.4741 E_angle = 0.3764
+E_dihed = 0.4952 E_impro = 0.0000 E_vdwl = -0.0037
+E_coul = 0.0005 E_long = -0.0040 Press = 0.0018
+Loop time of 1.61955 on 8 procs for 2000 steps with 4200 atoms
+
+ Pair time (%) = 0.224105 (13.8375)
+ Bond time (%) = 0.474754 (29.314)
+Kspace time (%) = 0.386537 (23.867)
+Neigh time (%) = 0.042553 (2.62747)
+ Comm time (%) = 0.380482 (23.4931)
+Output time (%) = 0.00026536 (0.0163848)
+Modify time (%) = 0.0842355 (5.20117)
+Other time (%) = 0.0266142 (1.64331)
+
+FFT time (% of Kspce) = 0.115633 (29.9151)
+FFT Gflps 3d (1d only) = 4.45608 14.0703
+
+Nlocal: 525 ave 625 max 427 min
+Histogram: 1 1 0 2 0 1 0 2 0 1
+Nghost: 4466 ave 4640 max 4345 min
+Histogram: 2 1 0 0 1 2 1 0 0 1
+Neighs: 3141.38 ave 3956 max 2489 min
+Histogram: 1 2 1 1 0 0 0 1 0 2
+
+Total # of neighbors = 25131
+Ave neighs/atom = 5.98357
+Ave special neighs/atom = 4.71429
+Neighbor list builds = 14
+Dangerous builds = 2
diff --git a/lib/gpu/Makefile.firefly b/lib/gpu/Makefile.firefly
deleted file mode 100644
index 079d0cb1c..000000000
--- a/lib/gpu/Makefile.firefly
+++ /dev/null
@@ -1,24 +0,0 @@
-CUDA_HOME = /usr/local/cuda
-NVCC = nvcc
-
-CUDA_ARCH = -arch=sm_20
-CUDA_PRECISION = -D_SINGLE_DOUBLE
-CUDA_INCLUDE = -I/usr/local/cuda/include
-CUDA_LIB = -L/usr/local/cuda/lib64
-CUDA_OPTS = -DUNIX -O3 -Xptxas -v --use_fast_math
-#CUDA_OPTS = -DUNIX -g -G
-
-CUDR_CPP = mpic++ -DMPI_GERYON -DMPICH_IGNORE_CXX_SEEK -fopenmp
-CUDR_OPTS = -g -Wall -O2 -DUCL_NO_EXIT # -xHost -no-prec-div -ansi-alias
-#CUDR_OPTS = -g -Wall -DUCL_SYNC_DEBUG
-
-BIN_DIR = /home/wb8/bin
-OBJ_DIR = /home/wb8/obj/lammps
-LIB_DIR = /home/wb8/obj/lammps
-AR = ar
-BSH = /bin/sh
-
-CUDPP_OPT = -DUSE_CUDPP -Icudpp_mini
-
-include Nvidia.makefile
-
diff --git a/lib/gpu/Makefile.firefly_opencl b/lib/gpu/Makefile.firefly_opencl
deleted file mode 100644
index d035a4d29..000000000
--- a/lib/gpu/Makefile.firefly_opencl
+++ /dev/null
@@ -1,12 +0,0 @@
-OCL_CPP = mpic++ -O3 -g -DFERMI_OCL -DMPI_GERYON -DMPICH_IGNORE_CXX_SEEK -I/usr/local/cuda/include/
-OCL_LINK = -lOpenCL
-OCL_PREC = -D_SINGLE_SINGLE
-
-BIN_DIR = /home/wb8/bin
-OBJ_DIR = /home/wb8/obj/lammps
-LIB_DIR = /home/wb8/obj/lammps
-AR = ar
-BSH = /bin/sh
-
-include Opencl.makefile
-
diff --git a/lib/gpu/Makefile.serial b/lib/gpu/Makefile.serial
new file mode 100644
index 000000000..0fa824642
--- /dev/null
+++ b/lib/gpu/Makefile.serial
@@ -0,0 +1,31 @@
+# /* ----------------------------------------------------------------------
+# Generic Makefile for CUDA using MPI STUBS library
+# - Change CUDA_ARCH for your GPU
+# ------------------------------------------------------------------------- */
+
+CUDA_HOME = $(HOME)/cuda
+NVCC = nvcc
+
+# Tesla CUDA
+CUDA_ARCH = -arch=sm_20
+# newer CUDA
+#CUDA_ARCH = -arch=sm_13
+# older CUDA
+#CUDA_ARCH = -arch=sm_10 -DCUDA_PRE_THREE
+
+CUDA_PRECISION = -D_SINGLE_DOUBLE
+CUDA_INCLUDE = -I$(CUDA_HOME)/include
+CUDA_LIB = -L$(CUDA_HOME)/lib64 -L../../src/STUBS -lmpi
+CUDA_OPTS = -DUNIX -O3 -Xptxas -v --use_fast_math
+
+CUDR_CPP = g++ -DMPI_GERYON -DUCL_NO_EXIT -I../../src/STUBS
+CUDR_OPTS = -O2
+
+BIN_DIR = ./
+OBJ_DIR = ./
+LIB_DIR = ./
+AR = ar
+BSH = /bin/sh
+
+include Nvidia.makefile
+
diff --git a/lib/gpu/Makefile.serial_opencl b/lib/gpu/Makefile.serial_opencl
new file mode 100644
index 000000000..4b6aa5b1f
--- /dev/null
+++ b/lib/gpu/Makefile.serial_opencl
@@ -0,0 +1,19 @@
+# /* ----------------------------------------------------------------------
+# Generic Makefile for OpenCL for use with MPI STUBS library
+# ------------------------------------------------------------------------- */
+OCL_HOME = $(HOME)/intelocl
+OCL_CPP = g++ -O3 -DMPI_GERYON -DUCL_NO_EXIT -I../../src/STUBS -I$(OCL_HOME)/include/
+# available tuned parameter sets: FERMI_OCL, CYPRESS_OCL
+#OCL_TUNE = -DFERMI_OCL
+OCL_TUNE = -DCYPRESS_OCL
+OCL_LINK = -lOpenCL -L../../src/STUBS -lmpi
+OCL_PREC = -D_SINGLE_DOUBLE
+
+BIN_DIR = ./
+OBJ_DIR = ./
+LIB_DIR = ./
+AR = ar
+BSH = /bin/sh
+
+include Opencl.makefile
+
diff --git a/lib/gpu/Opencl.makefile b/lib/gpu/Opencl.makefile
index 3f0838032..203e04de1 100644
--- a/lib/gpu/Opencl.makefile
+++ b/lib/gpu/Opencl.makefile
@@ -1,233 +1,233 @@
-OCL = $(OCL_CPP) $(OCL_PREC) -DUSE_OPENCL
+OCL = $(OCL_CPP) $(OCL_PREC) $(OCL_TUNE) -DUSE_OPENCL
OCL_LIB = $(LIB_DIR)/libgpu.a
# Headers for Geryon
UCL_H = $(wildcard ./geryon/ucl*.h)
OCL_H = $(wildcard ./geryon/ocl*.h) $(UCL_H)
# Headers for Pair Stuff
PAIR_H = lal_atom.h lal_answer.h lal_neighbor_shared.h \
lal_neighbor.h lal_precision.h lal_device.h \
lal_balance.h lal_pppm.h
# Headers for Preprocessor/Auxiliary Functions
PRE1_H = lal_preprocessor.h lal_aux_fun1.h
ALL_H = $(OCL_H) $(PAIR_H)
EXECS = $(BIN_DIR)/ocl_get_devices
OBJS = $(OBJ_DIR)/lal_atom.o $(OBJ_DIR)/lal_answer.o \
$(OBJ_DIR)/lal_neighbor_shared.o $(OBJ_DIR)/lal_neighbor.o \
$(OBJ_DIR)/lal_device.o $(OBJ_DIR)/lal_base_atomic.o \
$(OBJ_DIR)/lal_base_charge.o $(OBJ_DIR)/lal_base_ellipsoid.o \
$(OBJ_DIR)/lal_pppm.o $(OBJ_DIR)/lal_pppm_ext.o \
$(OBJ_DIR)/lal_gayberne.o $(OBJ_DIR)/lal_gayberne_ext.o \
$(OBJ_DIR)/lal_re_squared.o $(OBJ_DIR)/lal_re_squared_ext.o \
$(OBJ_DIR)/lal_lj.o $(OBJ_DIR)/lal_lj_ext.o \
$(OBJ_DIR)/lal_lj96.o $(OBJ_DIR)/lal_lj96_ext.o \
$(OBJ_DIR)/lal_lj_expand.o $(OBJ_DIR)/lal_lj_expand_ext.o \
$(OBJ_DIR)/lal_lj_coul.o $(OBJ_DIR)/lal_lj_coul_ext.o \
$(OBJ_DIR)/lal_lj_coul_long.o $(OBJ_DIR)/lal_lj_coul_long_ext.o \
$(OBJ_DIR)/lal_lj_class2_long.o $(OBJ_DIR)/lal_lj_class2_long_ext.o \
$(OBJ_DIR)/lal_coul_long.o $(OBJ_DIR)/lal_coul_long_ext.o \
$(OBJ_DIR)/lal_morse.o $(OBJ_DIR)/lal_morse_ext.o \
$(OBJ_DIR)/lal_charmm_long.o $(OBJ_DIR)/lal_charmm_long_ext.o \
$(OBJ_DIR)/lal_cg_cmm.o $(OBJ_DIR)/lal_cg_cmm_ext.o \
$(OBJ_DIR)/lal_cg_cmm_long.o $(OBJ_DIR)/lal_cg_cmm_long_ext.o
KERS = $(OBJ_DIR)/device_cl.h $(OBJ_DIR)/atom_cl.h \
$(OBJ_DIR)/neighbor_cpu_cl.h $(OBJ_DIR)/pppm_cl.h \
$(OBJ_DIR)/ellipsoid_nbor_cl.h $(OBJ_DIR)/gayberne_cl.h \
$(OBJ_DIR)/gayberne_lj_cl.h $(OBJ_DIR)/re_squared_cl.h \
$(OBJ_DIR)/re_squared_lj_cl.h $(OBJ_DIR)/lj_cl.h $(OBJ_DIR)/lj96_cl.h \
$(OBJ_DIR)/lj_expand_cl.h $(OBJ_DIR)/lj_coul_cl.h \
$(OBJ_DIR)/lj_coul_long_cl.h $(OBJ_DIR)/lj_class2_long_cl.h \
$(OBJ_DIR)/coul_long_cl.h $(OBJ_DIR)/morse_cl.h \
$(OBJ_DIR)/charmm_long_cl.h $(OBJ_DIR)/cg_cmm_cl.h \
$(OBJ_DIR)/cg_cmm_long_cl.h $(OBJ_DIR)/neighbor_gpu_cl.h
OCL_EXECS = $(BIN_DIR)/ocl_get_devices
all: $(OCL_LIB) $(EXECS)
$(OBJ_DIR)/atom_cl.h: lal_atom.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh atom lal_preprocessor.h lal_atom.cu $(OBJ_DIR)/atom_cl.h
$(OBJ_DIR)/lal_atom.o: lal_atom.cpp lal_atom.h $(OCL_H) $(OBJ_DIR)/atom_cl.h
$(OCL) -o $@ -c lal_atom.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_answer.o: lal_answer.cpp lal_answer.h $(OCL_H)
$(OCL) -o $@ -c lal_answer.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/neighbor_cpu_cl.h: lal_neighbor_cpu.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh neighbor_cpu lal_preprocessor.h lal_neighbor_cpu.cu $(OBJ_DIR)/neighbor_cpu_cl.h
$(OBJ_DIR)/neighbor_gpu_cl.h: lal_neighbor_gpu.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh neighbor_gpu lal_preprocessor.h lal_neighbor_gpu.cu $(OBJ_DIR)/neighbor_gpu_cl.h
$(OBJ_DIR)/lal_neighbor_shared.o: lal_neighbor_shared.cpp lal_neighbor_shared.h $(OCL_H) $(OBJ_DIR)/neighbor_cpu_cl.h $(OBJ_DIR)/neighbor_gpu_cl.h
$(OCL) -o $@ -c lal_neighbor_shared.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_neighbor.o: lal_neighbor.cpp lal_neighbor.h $(OCL_H) lal_neighbor_shared.h
$(OCL) -o $@ -c lal_neighbor.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/device_cl.h: lal_device.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh device lal_preprocessor.h lal_device.cu $(OBJ_DIR)/device_cl.h
$(OBJ_DIR)/lal_device.o: lal_device.cpp lal_device.h $(ALL_H) $(OBJ_DIR)/device_cl.h
$(OCL) -o $@ -c lal_device.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_base_atomic.o: $(OCL_H) lal_base_atomic.h lal_base_atomic.cpp
$(OCL) -o $@ -c lal_base_atomic.cpp
$(OBJ_DIR)/lal_base_charge.o: $(OCL_H) lal_base_charge.h lal_base_charge.cpp
$(OCL) -o $@ -c lal_base_charge.cpp
$(OBJ_DIR)/lal_base_ellipsoid.o: $(OCL_H) lal_base_ellipsoid.h lal_base_ellipsoid.cpp $(OBJ_DIR)/ellipsoid_nbor_cl.h
$(OCL) -o $@ -c lal_base_ellipsoid.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/pppm_cl.h: lal_pppm.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh pppm lal_preprocessor.h lal_pppm.cu $(OBJ_DIR)/pppm_cl.h;
$(OBJ_DIR)/lal_pppm.o: $(ALL_H) lal_pppm.h lal_pppm.cpp $(OBJ_DIR)/pppm_cl.h $(OBJ_DIR)/pppm_cl.h
$(OCL) -o $@ -c lal_pppm.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_pppm_ext.o: $(ALL_H) lal_pppm.h lal_pppm_ext.cpp
$(OCL) -o $@ -c lal_pppm_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/ellipsoid_nbor_cl.h: lal_ellipsoid_nbor.cu lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh ellipsoid_nbor lal_preprocessor.h lal_ellipsoid_nbor.cu $(OBJ_DIR)/ellipsoid_nbor_cl.h
$(OBJ_DIR)/gayberne_cl.h: lal_gayberne.cu lal_ellipsoid_extra.h lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh gayberne lal_preprocessor.h lal_ellipsoid_extra.h lal_gayberne.cu $(OBJ_DIR)/gayberne_cl.h;
$(OBJ_DIR)/gayberne_lj_cl.h: lal_gayberne_lj.cu lal_ellipsoid_extra.h lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh gayberne_lj lal_preprocessor.h lal_ellipsoid_extra.h lal_gayberne_lj.cu $(OBJ_DIR)/gayberne_lj_cl.h;
$(OBJ_DIR)/lal_gayberne.o: $(ALL_H) lal_gayberne.h lal_gayberne.cpp $(OBJ_DIR)/gayberne_cl.h $(OBJ_DIR)/gayberne_lj_cl.h $(OBJ_DIR)/lal_base_ellipsoid.o
$(OCL) -o $@ -c lal_gayberne.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_gayberne_ext.o: $(ALL_H) $(OBJ_DIR)/lal_gayberne.o lal_gayberne_ext.cpp
$(OCL) -o $@ -c lal_gayberne_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/re_squared_cl.h: lal_re_squared.cu lal_ellipsoid_extra.h lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh re_squared lal_preprocessor.h lal_ellipsoid_extra.h lal_re_squared.cu $(OBJ_DIR)/re_squared_cl.h;
$(OBJ_DIR)/re_squared_lj_cl.h: lal_re_squared_lj.cu lal_ellipsoid_extra.h lal_preprocessor.h
$(BSH) ./geryon/file_to_cstr.sh re_squared_lj lal_preprocessor.h lal_ellipsoid_extra.h lal_re_squared_lj.cu $(OBJ_DIR)/re_squared_lj_cl.h;
$(OBJ_DIR)/lal_re_squared.o: $(ALL_H) lal_re_squared.h lal_re_squared.cpp $(OBJ_DIR)/re_squared_cl.h $(OBJ_DIR)/re_squared_lj_cl.h $(OBJ_DIR)/lal_base_ellipsoid.o
$(OCL) -o $@ -c lal_re_squared.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_re_squared_ext.o: $(ALL_H) $(OBJ_DIR)/lal_re_squared.o lal_re_squared_ext.cpp
$(OCL) -o $@ -c lal_re_squared_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj_cl.h: lal_lj.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj $(PRE1_H) lal_lj.cu $(OBJ_DIR)/lj_cl.h;
$(OBJ_DIR)/lal_lj.o: $(ALL_H) lal_lj.h lal_lj.cpp $(OBJ_DIR)/lj_cl.h $(OBJ_DIR)/lj_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_lj.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj_ext.o: $(ALL_H) lal_lj.h lal_lj_ext.cpp lal_base_atomic.h
$(OCL) -o $@ -c lal_lj_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj_coul_cl.h: lal_lj_coul.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj_coul $(PRE1_H) lal_lj_coul.cu $(OBJ_DIR)/lj_coul_cl.h;
$(OBJ_DIR)/lal_lj_coul.o: $(ALL_H) lal_lj_coul.h lal_lj_coul.cpp $(OBJ_DIR)/lj_coul_cl.h $(OBJ_DIR)/lj_coul_cl.h $(OBJ_DIR)/lal_base_charge.o
$(OCL) -o $@ -c lal_lj_coul.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj_coul_ext.o: $(ALL_H) lal_lj_coul.h lal_lj_coul_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_lj_coul_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj_coul_long_cl.h: lal_lj_coul_long.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj_coul_long $(PRE1_H) lal_lj_coul_long.cu $(OBJ_DIR)/lj_coul_long_cl.h;
$(OBJ_DIR)/lal_lj_coul_long.o: $(ALL_H) lal_lj_coul_long.h lal_lj_coul_long.cpp $(OBJ_DIR)/lj_coul_long_cl.h $(OBJ_DIR)/lal_base_charge.o
$(OCL) -o $@ -c lal_lj_coul_long.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj_coul_long_ext.o: $(ALL_H) lal_lj_coul_long.h lal_lj_coul_long_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_lj_coul_long_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj_class2_long_cl.h: lal_lj_class2_long.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj_class2_long $(PRE1_H) lal_lj_class2_long.cu $(OBJ_DIR)/lj_class2_long_cl.h;
$(OBJ_DIR)/lal_lj_class2_long.o: $(ALL_H) lal_lj_class2_long.h lal_lj_class2_long.cpp $(OBJ_DIR)/lj_class2_long_cl.h $(OBJ_DIR)/lal_base_charge.o
$(OCL) -o $@ -c lal_lj_class2_long.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj_class2_long_ext.o: $(ALL_H) lal_lj_class2_long.h lal_lj_class2_long_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_lj_class2_long_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/coul_long_cl.h: lal_coul_long.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh coul_long $(PRE1_H) lal_coul_long.cu $(OBJ_DIR)/coul_long_cl.h;
$(OBJ_DIR)/lal_coul_long.o: $(ALL_H) lal_coul_long.h lal_coul_long.cpp $(OBJ_DIR)/coul_long_cl.h $(OBJ_DIR)/lal_base_charge.o
$(OCL) -o $@ -c lal_coul_long.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_coul_long_ext.o: $(ALL_H) lal_coul_long.h lal_coul_long_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_coul_long_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/morse_cl.h: lal_morse.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh morse $(PRE1_H) lal_morse.cu $(OBJ_DIR)/morse_cl.h;
$(OBJ_DIR)/lal_morse.o: $(ALL_H) lal_morse.h lal_morse.cpp $(OBJ_DIR)/morse_cl.h $(OBJ_DIR)/morse_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_morse.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_morse_ext.o: $(ALL_H) lal_morse.h lal_morse_ext.cpp lal_base_atomic.h
$(OCL) -o $@ -c lal_morse_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/charmm_long_cl.h: lal_charmm_long.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh charmm_long $(PRE1_H) lal_charmm_long.cu $(OBJ_DIR)/charmm_long_cl.h;
$(OBJ_DIR)/lal_charmm_long.o: $(ALL_H) lal_charmm_long.h lal_charmm_long.cpp $(OBJ_DIR)/charmm_long_cl.h $(OBJ_DIR)/charmm_long_cl.h $(OBJ_DIR)/lal_base_charge.o
$(OCL) -o $@ -c lal_charmm_long.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_charmm_long_ext.o: $(ALL_H) lal_charmm_long.h lal_charmm_long_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_charmm_long_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj96_cl.h: lal_lj96.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj96 $(PRE1_H) lal_lj96.cu $(OBJ_DIR)/lj96_cl.h;
$(OBJ_DIR)/lal_lj96.o: $(ALL_H) lal_lj96.h lal_lj96.cpp $(OBJ_DIR)/lj96_cl.h $(OBJ_DIR)/lj96_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_lj96.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj96_ext.o: $(ALL_H) lal_lj96.h lal_lj96_ext.cpp lal_base_atomic.h
$(OCL) -o $@ -c lal_lj96_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lj_expand_cl.h: lal_lj_expand.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh lj_expand $(PRE1_H) lal_lj_expand.cu $(OBJ_DIR)/lj_expand_cl.h;
$(OBJ_DIR)/lal_lj_expand.o: $(ALL_H) lal_lj_expand.h lal_lj_expand.cpp $(OBJ_DIR)/lj_expand_cl.h $(OBJ_DIR)/lj_expand_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_lj_expand.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_lj_expand_ext.o: $(ALL_H) lal_lj_expand.h lal_lj_expand_ext.cpp lal_base_atomic.h
$(OCL) -o $@ -c lal_lj_expand_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/cg_cmm_cl.h: lal_cg_cmm.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh cg_cmm $(PRE1_H) lal_cg_cmm.cu $(OBJ_DIR)/cg_cmm_cl.h;
$(OBJ_DIR)/lal_cg_cmm.o: $(ALL_H) lal_cg_cmm.h lal_cg_cmm.cpp $(OBJ_DIR)/cg_cmm_cl.h $(OBJ_DIR)/cg_cmm_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_cg_cmm.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_cg_cmm_ext.o: $(ALL_H) lal_cg_cmm.h lal_cg_cmm_ext.cpp lal_base_atomic.h
$(OCL) -o $@ -c lal_cg_cmm_ext.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/cg_cmm_long_cl.h: lal_cg_cmm_long.cu $(PRE1_H)
$(BSH) ./geryon/file_to_cstr.sh cg_cmm_long $(PRE1_H) lal_cg_cmm_long.cu $(OBJ_DIR)/cg_cmm_long_cl.h;
$(OBJ_DIR)/lal_cg_cmm_long.o: $(ALL_H) lal_cg_cmm_long.h lal_cg_cmm_long.cpp $(OBJ_DIR)/cg_cmm_long_cl.h $(OBJ_DIR)/cg_cmm_long_cl.h $(OBJ_DIR)/lal_base_atomic.o
$(OCL) -o $@ -c lal_cg_cmm_long.cpp -I$(OBJ_DIR)
$(OBJ_DIR)/lal_cg_cmm_long_ext.o: $(ALL_H) lal_cg_cmm_long.h lal_cg_cmm_long_ext.cpp lal_base_charge.h
$(OCL) -o $@ -c lal_cg_cmm_long_ext.cpp -I$(OBJ_DIR)
$(BIN_DIR)/ocl_get_devices: ./geryon/ucl_get_devices.cpp
$(OCL) -o $@ ./geryon/ucl_get_devices.cpp -DUCL_OPENCL $(OCL_LINK)
$(OCL_LIB): $(OBJS) $(PTXS)
$(AR) -crusv $(OCL_LIB) $(OBJS)
opencl: $(OCL_EXECS)
clean:
rm -rf $(EXECS) $(OCL_EXECS) $(OCL_LIB) $(OBJS) $(KERS) *.linkinfo
veryclean: clean
rm -rf *~ *.linkinfo
diff --git a/lib/gpu/geryon/opencl/CL/cl.h b/lib/gpu/geryon/opencl/CL/cl.h
deleted file mode 100644
index 6d4a6f255..000000000
--- a/lib/gpu/geryon/opencl/CL/cl.h
+++ /dev/null
@@ -1,997 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- ******************************************************************************/
-
-/* $Revision: 11708 $ on $Date: 2010-06-14 12:06:24 +0530 (Mon, 14 Jun 2010) $ */
-
-#ifndef __OPENCL_CL_H
-#define __OPENCL_CL_H
-
-#ifdef __APPLE__
-#include <OpenCL/cl_platform.h>
-#else
-#include <CL/cl_platform.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/******************************************************************************/
-
-typedef struct _cl_platform_id * cl_platform_id;
-typedef struct _cl_device_id * cl_device_id;
-typedef struct _cl_context * cl_context;
-typedef struct _cl_command_queue * cl_command_queue;
-typedef struct _cl_mem * cl_mem;
-typedef struct _cl_program * cl_program;
-typedef struct _cl_kernel * cl_kernel;
-typedef struct _cl_event * cl_event;
-typedef struct _cl_sampler * cl_sampler;
-
-typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */
-typedef cl_ulong cl_bitfield;
-typedef cl_bitfield cl_device_type;
-typedef cl_uint cl_platform_info;
-typedef cl_uint cl_device_info;
-typedef cl_bitfield cl_device_fp_config;
-typedef cl_uint cl_device_mem_cache_type;
-typedef cl_uint cl_device_local_mem_type;
-typedef cl_bitfield cl_device_exec_capabilities;
-typedef cl_bitfield cl_command_queue_properties;
-
-typedef intptr_t cl_context_properties;
-typedef cl_uint cl_context_info;
-typedef cl_uint cl_command_queue_info;
-typedef cl_uint cl_channel_order;
-typedef cl_uint cl_channel_type;
-typedef cl_bitfield cl_mem_flags;
-typedef cl_uint cl_mem_object_type;
-typedef cl_uint cl_mem_info;
-typedef cl_uint cl_image_info;
-typedef cl_uint cl_buffer_create_type;
-typedef cl_uint cl_addressing_mode;
-typedef cl_uint cl_filter_mode;
-typedef cl_uint cl_sampler_info;
-typedef cl_bitfield cl_map_flags;
-typedef cl_uint cl_program_info;
-typedef cl_uint cl_program_build_info;
-typedef cl_int cl_build_status;
-typedef cl_uint cl_kernel_info;
-typedef cl_uint cl_kernel_work_group_info;
-typedef cl_uint cl_event_info;
-typedef cl_uint cl_command_type;
-typedef cl_uint cl_profiling_info;
-
-typedef struct _cl_image_format {
- cl_channel_order image_channel_order;
- cl_channel_type image_channel_data_type;
-} cl_image_format;
-
-
-typedef struct _cl_buffer_region {
- size_t origin;
- size_t size;
-} cl_buffer_region;
-
-/******************************************************************************/
-
-/* Error Codes */
-#define CL_SUCCESS 0
-#define CL_DEVICE_NOT_FOUND -1
-#define CL_DEVICE_NOT_AVAILABLE -2
-#define CL_COMPILER_NOT_AVAILABLE -3
-#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4
-#define CL_OUT_OF_RESOURCES -5
-#define CL_OUT_OF_HOST_MEMORY -6
-#define CL_PROFILING_INFO_NOT_AVAILABLE -7
-#define CL_MEM_COPY_OVERLAP -8
-#define CL_IMAGE_FORMAT_MISMATCH -9
-#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10
-#define CL_BUILD_PROGRAM_FAILURE -11
-#define CL_MAP_FAILURE -12
-#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13
-#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14
-
-#define CL_INVALID_VALUE -30
-#define CL_INVALID_DEVICE_TYPE -31
-#define CL_INVALID_PLATFORM -32
-#define CL_INVALID_DEVICE -33
-#define CL_INVALID_CONTEXT -34
-#define CL_INVALID_QUEUE_PROPERTIES -35
-#define CL_INVALID_COMMAND_QUEUE -36
-#define CL_INVALID_HOST_PTR -37
-#define CL_INVALID_MEM_OBJECT -38
-#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39
-#define CL_INVALID_IMAGE_SIZE -40
-#define CL_INVALID_SAMPLER -41
-#define CL_INVALID_BINARY -42
-#define CL_INVALID_BUILD_OPTIONS -43
-#define CL_INVALID_PROGRAM -44
-#define CL_INVALID_PROGRAM_EXECUTABLE -45
-#define CL_INVALID_KERNEL_NAME -46
-#define CL_INVALID_KERNEL_DEFINITION -47
-#define CL_INVALID_KERNEL -48
-#define CL_INVALID_ARG_INDEX -49
-#define CL_INVALID_ARG_VALUE -50
-#define CL_INVALID_ARG_SIZE -51
-#define CL_INVALID_KERNEL_ARGS -52
-#define CL_INVALID_WORK_DIMENSION -53
-#define CL_INVALID_WORK_GROUP_SIZE -54
-#define CL_INVALID_WORK_ITEM_SIZE -55
-#define CL_INVALID_GLOBAL_OFFSET -56
-#define CL_INVALID_EVENT_WAIT_LIST -57
-#define CL_INVALID_EVENT -58
-#define CL_INVALID_OPERATION -59
-#define CL_INVALID_GL_OBJECT -60
-#define CL_INVALID_BUFFER_SIZE -61
-#define CL_INVALID_MIP_LEVEL -62
-#define CL_INVALID_GLOBAL_WORK_SIZE -63
-
-/* OpenCL Version */
-#define CL_VERSION_1_0 1
-#define CL_VERSION_1_1 1
-
-/* cl_bool */
-#define CL_FALSE 0
-#define CL_TRUE 1
-
-/* cl_platform_info */
-#define CL_PLATFORM_PROFILE 0x0900
-#define CL_PLATFORM_VERSION 0x0901
-#define CL_PLATFORM_NAME 0x0902
-#define CL_PLATFORM_VENDOR 0x0903
-#define CL_PLATFORM_EXTENSIONS 0x0904
-
-/* cl_device_type - bitfield */
-#define CL_DEVICE_TYPE_DEFAULT (1 << 0)
-#define CL_DEVICE_TYPE_CPU (1 << 1)
-#define CL_DEVICE_TYPE_GPU (1 << 2)
-#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3)
-#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF
-
-/* cl_device_info */
-#define CL_DEVICE_TYPE 0x1000
-#define CL_DEVICE_VENDOR_ID 0x1001
-#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002
-#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003
-#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004
-#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B
-#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C
-#define CL_DEVICE_ADDRESS_BITS 0x100D
-#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E
-#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F
-#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010
-#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011
-#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012
-#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013
-#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014
-#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015
-#define CL_DEVICE_IMAGE_SUPPORT 0x1016
-#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017
-#define CL_DEVICE_MAX_SAMPLERS 0x1018
-#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019
-#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A
-#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B
-#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C
-#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D
-#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E
-#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F
-#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020
-#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021
-#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022
-#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023
-#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024
-#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025
-#define CL_DEVICE_ENDIAN_LITTLE 0x1026
-#define CL_DEVICE_AVAILABLE 0x1027
-#define CL_DEVICE_COMPILER_AVAILABLE 0x1028
-#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029
-#define CL_DEVICE_QUEUE_PROPERTIES 0x102A
-#define CL_DEVICE_NAME 0x102B
-#define CL_DEVICE_VENDOR 0x102C
-#define CL_DRIVER_VERSION 0x102D
-#define CL_DEVICE_PROFILE 0x102E
-#define CL_DEVICE_VERSION 0x102F
-#define CL_DEVICE_EXTENSIONS 0x1030
-#define CL_DEVICE_PLATFORM 0x1031
-/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */
-/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034
-#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B
-#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C
-#define CL_DEVICE_OPENCL_C_VERSION 0x103D
-
-/* cl_device_fp_config - bitfield */
-#define CL_FP_DENORM (1 << 0)
-#define CL_FP_INF_NAN (1 << 1)
-#define CL_FP_ROUND_TO_NEAREST (1 << 2)
-#define CL_FP_ROUND_TO_ZERO (1 << 3)
-#define CL_FP_ROUND_TO_INF (1 << 4)
-#define CL_FP_FMA (1 << 5)
-#define CL_FP_SOFT_FLOAT (1 << 6)
-
-/* cl_device_mem_cache_type */
-#define CL_NONE 0x0
-#define CL_READ_ONLY_CACHE 0x1
-#define CL_READ_WRITE_CACHE 0x2
-
-/* cl_device_local_mem_type */
-#define CL_LOCAL 0x1
-#define CL_GLOBAL 0x2
-
-/* cl_device_exec_capabilities - bitfield */
-#define CL_EXEC_KERNEL (1 << 0)
-#define CL_EXEC_NATIVE_KERNEL (1 << 1)
-
-/* cl_command_queue_properties - bitfield */
-#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0)
-#define CL_QUEUE_PROFILING_ENABLE (1 << 1)
-
-/* cl_context_info */
-#define CL_CONTEXT_REFERENCE_COUNT 0x1080
-#define CL_CONTEXT_DEVICES 0x1081
-#define CL_CONTEXT_PROPERTIES 0x1082
-#define CL_CONTEXT_NUM_DEVICES 0x1083
-
-/* cl_context_info + cl_context_properties */
-#define CL_CONTEXT_PLATFORM 0x1084
-
-/* cl_command_queue_info */
-#define CL_QUEUE_CONTEXT 0x1090
-#define CL_QUEUE_DEVICE 0x1091
-#define CL_QUEUE_REFERENCE_COUNT 0x1092
-#define CL_QUEUE_PROPERTIES 0x1093
-
-/* cl_mem_flags - bitfield */
-#define CL_MEM_READ_WRITE (1 << 0)
-#define CL_MEM_WRITE_ONLY (1 << 1)
-#define CL_MEM_READ_ONLY (1 << 2)
-#define CL_MEM_USE_HOST_PTR (1 << 3)
-#define CL_MEM_ALLOC_HOST_PTR (1 << 4)
-#define CL_MEM_COPY_HOST_PTR (1 << 5)
-
-/* cl_channel_order */
-#define CL_R 0x10B0
-#define CL_A 0x10B1
-#define CL_RG 0x10B2
-#define CL_RA 0x10B3
-#define CL_RGB 0x10B4
-#define CL_RGBA 0x10B5
-#define CL_BGRA 0x10B6
-#define CL_ARGB 0x10B7
-#define CL_INTENSITY 0x10B8
-#define CL_LUMINANCE 0x10B9
-#define CL_Rx 0x10BA
-#define CL_RGx 0x10BB
-#define CL_RGBx 0x10BC
-
-/* cl_channel_type */
-#define CL_SNORM_INT8 0x10D0
-#define CL_SNORM_INT16 0x10D1
-#define CL_UNORM_INT8 0x10D2
-#define CL_UNORM_INT16 0x10D3
-#define CL_UNORM_SHORT_565 0x10D4
-#define CL_UNORM_SHORT_555 0x10D5
-#define CL_UNORM_INT_101010 0x10D6
-#define CL_SIGNED_INT8 0x10D7
-#define CL_SIGNED_INT16 0x10D8
-#define CL_SIGNED_INT32 0x10D9
-#define CL_UNSIGNED_INT8 0x10DA
-#define CL_UNSIGNED_INT16 0x10DB
-#define CL_UNSIGNED_INT32 0x10DC
-#define CL_HALF_FLOAT 0x10DD
-#define CL_FLOAT 0x10DE
-
-/* cl_mem_object_type */
-#define CL_MEM_OBJECT_BUFFER 0x10F0
-#define CL_MEM_OBJECT_IMAGE2D 0x10F1
-#define CL_MEM_OBJECT_IMAGE3D 0x10F2
-
-/* cl_mem_info */
-#define CL_MEM_TYPE 0x1100
-#define CL_MEM_FLAGS 0x1101
-#define CL_MEM_SIZE 0x1102
-#define CL_MEM_HOST_PTR 0x1103
-#define CL_MEM_MAP_COUNT 0x1104
-#define CL_MEM_REFERENCE_COUNT 0x1105
-#define CL_MEM_CONTEXT 0x1106
-#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107
-#define CL_MEM_OFFSET 0x1108
-
-/* cl_image_info */
-#define CL_IMAGE_FORMAT 0x1110
-#define CL_IMAGE_ELEMENT_SIZE 0x1111
-#define CL_IMAGE_ROW_PITCH 0x1112
-#define CL_IMAGE_SLICE_PITCH 0x1113
-#define CL_IMAGE_WIDTH 0x1114
-#define CL_IMAGE_HEIGHT 0x1115
-#define CL_IMAGE_DEPTH 0x1116
-
-/* cl_addressing_mode */
-#define CL_ADDRESS_NONE 0x1130
-#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131
-#define CL_ADDRESS_CLAMP 0x1132
-#define CL_ADDRESS_REPEAT 0x1133
-#define CL_ADDRESS_MIRRORED_REPEAT 0x1134
-
-/* cl_filter_mode */
-#define CL_FILTER_NEAREST 0x1140
-#define CL_FILTER_LINEAR 0x1141
-
-/* cl_sampler_info */
-#define CL_SAMPLER_REFERENCE_COUNT 0x1150
-#define CL_SAMPLER_CONTEXT 0x1151
-#define CL_SAMPLER_NORMALIZED_COORDS 0x1152
-#define CL_SAMPLER_ADDRESSING_MODE 0x1153
-#define CL_SAMPLER_FILTER_MODE 0x1154
-
-/* cl_map_flags - bitfield */
-#define CL_MAP_READ (1 << 0)
-#define CL_MAP_WRITE (1 << 1)
-
-/* cl_program_info */
-#define CL_PROGRAM_REFERENCE_COUNT 0x1160
-#define CL_PROGRAM_CONTEXT 0x1161
-#define CL_PROGRAM_NUM_DEVICES 0x1162
-#define CL_PROGRAM_DEVICES 0x1163
-#define CL_PROGRAM_SOURCE 0x1164
-#define CL_PROGRAM_BINARY_SIZES 0x1165
-#define CL_PROGRAM_BINARIES 0x1166
-
-/* cl_program_build_info */
-#define CL_PROGRAM_BUILD_STATUS 0x1181
-#define CL_PROGRAM_BUILD_OPTIONS 0x1182
-#define CL_PROGRAM_BUILD_LOG 0x1183
-
-/* cl_build_status */
-#define CL_BUILD_SUCCESS 0
-#define CL_BUILD_NONE -1
-#define CL_BUILD_ERROR -2
-#define CL_BUILD_IN_PROGRESS -3
-
-/* cl_kernel_info */
-#define CL_KERNEL_FUNCTION_NAME 0x1190
-#define CL_KERNEL_NUM_ARGS 0x1191
-#define CL_KERNEL_REFERENCE_COUNT 0x1192
-#define CL_KERNEL_CONTEXT 0x1193
-#define CL_KERNEL_PROGRAM 0x1194
-
-/* cl_kernel_work_group_info */
-#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0
-#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1
-#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2
-#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3
-#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4
-
-/* cl_event_info */
-#define CL_EVENT_COMMAND_QUEUE 0x11D0
-#define CL_EVENT_COMMAND_TYPE 0x11D1
-#define CL_EVENT_REFERENCE_COUNT 0x11D2
-#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3
-#define CL_EVENT_CONTEXT 0x11D4
-
-/* cl_command_type */
-#define CL_COMMAND_NDRANGE_KERNEL 0x11F0
-#define CL_COMMAND_TASK 0x11F1
-#define CL_COMMAND_NATIVE_KERNEL 0x11F2
-#define CL_COMMAND_READ_BUFFER 0x11F3
-#define CL_COMMAND_WRITE_BUFFER 0x11F4
-#define CL_COMMAND_COPY_BUFFER 0x11F5
-#define CL_COMMAND_READ_IMAGE 0x11F6
-#define CL_COMMAND_WRITE_IMAGE 0x11F7
-#define CL_COMMAND_COPY_IMAGE 0x11F8
-#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9
-#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA
-#define CL_COMMAND_MAP_BUFFER 0x11FB
-#define CL_COMMAND_MAP_IMAGE 0x11FC
-#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD
-#define CL_COMMAND_MARKER 0x11FE
-#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF
-#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200
-#define CL_COMMAND_READ_BUFFER_RECT 0x1201
-#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202
-#define CL_COMMAND_COPY_BUFFER_RECT 0x1203
-#define CL_COMMAND_USER 0x1204
-
-/* command execution status */
-#define CL_COMPLETE 0x0
-#define CL_RUNNING 0x1
-#define CL_SUBMITTED 0x2
-#define CL_QUEUED 0x3
-
-/* cl_buffer_create_type */
-#define CL_BUFFER_CREATE_TYPE_REGION 0x1220
-
-/* cl_profiling_info */
-#define CL_PROFILING_COMMAND_QUEUED 0x1280
-#define CL_PROFILING_COMMAND_SUBMIT 0x1281
-#define CL_PROFILING_COMMAND_START 0x1282
-#define CL_PROFILING_COMMAND_END 0x1283
-
-/********************************************************************************************************/
-
-/* Platform API */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetPlatformIDs(cl_uint /* num_entries */,
- cl_platform_id * /* platforms */,
- cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetPlatformInfo(cl_platform_id /* platform */,
- cl_platform_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Device APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetDeviceIDs(cl_platform_id /* platform */,
- cl_device_type /* device_type */,
- cl_uint /* num_entries */,
- cl_device_id * /* devices */,
- cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetDeviceInfo(cl_device_id /* device */,
- cl_device_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Context APIs */
-extern CL_API_ENTRY cl_context CL_API_CALL
-clCreateContext(const cl_context_properties * /* properties */,
- cl_uint /* num_devices */,
- const cl_device_id * /* devices */,
- void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *),
- void * /* user_data */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_context CL_API_CALL
-clCreateContextFromType(const cl_context_properties * /* properties */,
- cl_device_type /* device_type */,
- void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *),
- void * /* user_data */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetContextInfo(cl_context /* context */,
- cl_context_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Command Queue APIs */
-extern CL_API_ENTRY cl_command_queue CL_API_CALL
-clCreateCommandQueue(cl_context /* context */,
- cl_device_id /* device */,
- cl_command_queue_properties /* properties */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetCommandQueueInfo(cl_command_queue /* command_queue */,
- cl_command_queue_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS
-#warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1!
-/*
- * WARNING:
- * This API introduces mutable state into the OpenCL implementation. It has been REMOVED
- * to better facilitate thread safety. The 1.0 API is not thread safe. It is not tested by the
- * OpenCL 1.1 conformance test, and consequently may not work or may not work dependably.
- * It is likely to be non-performant. Use of this API is not advised. Use at your own risk.
- *
- * Software developers previously relying on this API are instructed to set the command queue
- * properties when creating the queue, instead.
- */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetCommandQueueProperty(cl_command_queue /* command_queue */,
- cl_command_queue_properties /* properties */,
- cl_bool /* enable */,
- cl_command_queue_properties * /* old_properties */) CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED;
-#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */
-
-/* Memory Object APIs */
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateBuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- size_t /* size */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateSubBuffer(cl_mem /* buffer */,
- cl_mem_flags /* flags */,
- cl_buffer_create_type /* buffer_create_type */,
- const void * /* buffer_create_info */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateImage2D(cl_context /* context */,
- cl_mem_flags /* flags */,
- const cl_image_format * /* image_format */,
- size_t /* image_width */,
- size_t /* image_height */,
- size_t /* image_row_pitch */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateImage3D(cl_context /* context */,
- cl_mem_flags /* flags */,
- const cl_image_format * /* image_format */,
- size_t /* image_width */,
- size_t /* image_height */,
- size_t /* image_depth */,
- size_t /* image_row_pitch */,
- size_t /* image_slice_pitch */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetSupportedImageFormats(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_mem_object_type /* image_type */,
- cl_uint /* num_entries */,
- cl_image_format * /* image_formats */,
- cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetMemObjectInfo(cl_mem /* memobj */,
- cl_mem_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetImageInfo(cl_mem /* image */,
- cl_image_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetMemObjectDestructorCallback( cl_mem /* memobj */,
- void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
- void * /*user_data */ ) CL_API_SUFFIX__VERSION_1_1;
-
-/* Sampler APIs */
-extern CL_API_ENTRY cl_sampler CL_API_CALL
-clCreateSampler(cl_context /* context */,
- cl_bool /* normalized_coords */,
- cl_addressing_mode /* addressing_mode */,
- cl_filter_mode /* filter_mode */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetSamplerInfo(cl_sampler /* sampler */,
- cl_sampler_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Program Object APIs */
-extern CL_API_ENTRY cl_program CL_API_CALL
-clCreateProgramWithSource(cl_context /* context */,
- cl_uint /* count */,
- const char ** /* strings */,
- const size_t * /* lengths */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_program CL_API_CALL
-clCreateProgramWithBinary(cl_context /* context */,
- cl_uint /* num_devices */,
- const cl_device_id * /* device_list */,
- const size_t * /* lengths */,
- const unsigned char ** /* binaries */,
- cl_int * /* binary_status */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clBuildProgram(cl_program /* program */,
- cl_uint /* num_devices */,
- const cl_device_id * /* device_list */,
- const char * /* options */,
- void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */),
- void * /* user_data */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetProgramInfo(cl_program /* program */,
- cl_program_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetProgramBuildInfo(cl_program /* program */,
- cl_device_id /* device */,
- cl_program_build_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Kernel Object APIs */
-extern CL_API_ENTRY cl_kernel CL_API_CALL
-clCreateKernel(cl_program /* program */,
- const char * /* kernel_name */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clCreateKernelsInProgram(cl_program /* program */,
- cl_uint /* num_kernels */,
- cl_kernel * /* kernels */,
- cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetKernelArg(cl_kernel /* kernel */,
- cl_uint /* arg_index */,
- size_t /* arg_size */,
- const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetKernelInfo(cl_kernel /* kernel */,
- cl_kernel_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetKernelWorkGroupInfo(cl_kernel /* kernel */,
- cl_device_id /* device */,
- cl_kernel_work_group_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Event Object APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clWaitForEvents(cl_uint /* num_events */,
- const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetEventInfo(cl_event /* event */,
- cl_event_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_event CL_API_CALL
-clCreateUserEvent(cl_context /* context */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetUserEventStatus(cl_event /* event */,
- cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetEventCallback( cl_event /* event */,
- cl_int /* command_exec_callback_type */,
- void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *),
- void * /* user_data */) CL_API_SUFFIX__VERSION_1_1;
-
-/* Profiling APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetEventProfilingInfo(cl_event /* event */,
- cl_profiling_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Flush and Finish APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clFlush(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clFinish(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Enqueued Commands APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReadBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_read */,
- size_t /* offset */,
- size_t /* cb */,
- void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReadBufferRect(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_read */,
- const size_t * /* buffer_offset */,
- const size_t * /* host_offset */,
- const size_t * /* region */,
- size_t /* buffer_row_pitch */,
- size_t /* buffer_slice_pitch */,
- size_t /* host_row_pitch */,
- size_t /* host_slice_pitch */,
- void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWriteBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_write */,
- size_t /* offset */,
- size_t /* cb */,
- const void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWriteBufferRect(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_read */,
- const size_t * /* buffer_offset */,
- const size_t * /* host_offset */,
- const size_t * /* region */,
- size_t /* buffer_row_pitch */,
- size_t /* buffer_slice_pitch */,
- size_t /* host_row_pitch */,
- size_t /* host_slice_pitch */,
- const void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyBuffer(cl_command_queue /* command_queue */,
- cl_mem /* src_buffer */,
- cl_mem /* dst_buffer */,
- size_t /* src_offset */,
- size_t /* dst_offset */,
- size_t /* cb */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyBufferRect(cl_command_queue /* command_queue */,
- cl_mem /* src_buffer */,
- cl_mem /* dst_buffer */,
- const size_t * /* src_origin */,
- const size_t * /* dst_origin */,
- const size_t * /* region */,
- size_t /* src_row_pitch */,
- size_t /* src_slice_pitch */,
- size_t /* dst_row_pitch */,
- size_t /* dst_slice_pitch */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReadImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_read */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t /* row_pitch */,
- size_t /* slice_pitch */,
- void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWriteImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_write */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t /* input_row_pitch */,
- size_t /* input_slice_pitch */,
- const void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyImage(cl_command_queue /* command_queue */,
- cl_mem /* src_image */,
- cl_mem /* dst_image */,
- const size_t * /* src_origin[3] */,
- const size_t * /* dst_origin[3] */,
- const size_t * /* region[3] */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyImageToBuffer(cl_command_queue /* command_queue */,
- cl_mem /* src_image */,
- cl_mem /* dst_buffer */,
- const size_t * /* src_origin[3] */,
- const size_t * /* region[3] */,
- size_t /* dst_offset */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyBufferToImage(cl_command_queue /* command_queue */,
- cl_mem /* src_buffer */,
- cl_mem /* dst_image */,
- size_t /* src_offset */,
- const size_t * /* dst_origin[3] */,
- const size_t * /* region[3] */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY void * CL_API_CALL
-clEnqueueMapBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_map */,
- cl_map_flags /* map_flags */,
- size_t /* offset */,
- size_t /* cb */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY void * CL_API_CALL
-clEnqueueMapImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_map */,
- cl_map_flags /* map_flags */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t * /* image_row_pitch */,
- size_t * /* image_slice_pitch */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueUnmapMemObject(cl_command_queue /* command_queue */,
- cl_mem /* memobj */,
- void * /* mapped_ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueNDRangeKernel(cl_command_queue /* command_queue */,
- cl_kernel /* kernel */,
- cl_uint /* work_dim */,
- const size_t * /* global_work_offset */,
- const size_t * /* global_work_size */,
- const size_t * /* local_work_size */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueTask(cl_command_queue /* command_queue */,
- cl_kernel /* kernel */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueNativeKernel(cl_command_queue /* command_queue */,
- void (*user_func)(void *),
- void * /* args */,
- size_t /* cb_args */,
- cl_uint /* num_mem_objects */,
- const cl_mem * /* mem_list */,
- const void ** /* args_mem_loc */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueMarker(cl_command_queue /* command_queue */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWaitForEvents(cl_command_queue /* command_queue */,
- cl_uint /* num_events */,
- const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Extension function access
- *
- * Returns the extension function address for the given function name,
- * or NULL if a valid function can not be found. The client must
- * check to make sure the address is not NULL, before using or
- * calling the returned function address.
- */
-extern CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_CL_H */
-
diff --git a/lib/gpu/geryon/opencl/CL/cl_ext.h b/lib/gpu/geryon/opencl/CL/cl_ext.h
deleted file mode 100644
index 2d6e64e9d..000000000
--- a/lib/gpu/geryon/opencl/CL/cl_ext.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- ******************************************************************************/
-
-/* $Revision: 11687 $ on $Date: 2010-06-12 03:47:22 +0530 (Sat, 12 Jun 2010) $ */
-
-/* cl_ext.h contains OpenCL extensions which don't have external */
-/* (OpenGL, D3D) dependencies. */
-
-#ifndef __CL_EXT_H
-#define __CL_EXT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __APPLE__
- #include <OpenCL/cl.h>
- #include <AvailabilityMacros.h>
-#else
- #include <CL/cl.h>
-#endif
-
-/* cl_khr_fp64 extension - no extension #define since it has no functions */
-#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032
-
-/* cl_khr_fp16 extension - no extension #define since it has no functions */
-#define CL_DEVICE_HALF_FP_CONFIG 0x1033
-
-/* Memory object destruction
- *
- * Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR
- *
- * Registers a user callback function that will be called when the memory object is deleted and its resources
- * freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback
- * stack associated with memobj. The registered user callback functions are called in the reverse order in
- * which they were registered. The user callback functions are called and then the memory object is deleted
- * and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be
- * notified when the memory referenced by host_ptr, specified when the memory object is created and used as
- * the storage bits for the memory object, can be reused or freed.
- *
- * The application may not call CL api's with the cl_mem object passed to the pfn_notify.
- *
- * Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
- * before using.
- */
-#define cl_APPLE_SetMemObjectDestructor 1
-cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */,
- void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
- void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
-
-
-/* Context Logging Functions
- *
- * The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext().
- * Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
- * before using.
- *
- * clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger
- */
-#define cl_APPLE_ContextLoggingFunctions 1
-extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */,
- const void * /* private_info */,
- size_t /* cb */,
- void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
-
-/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */
-extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */,
- const void * /* private_info */,
- size_t /* cb */,
- void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
-
-/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */
-extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */,
- const void * /* private_info */,
- size_t /* cb */,
- void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
-
-
-/************************
-* cl_khr_icd extension *
-************************/
-#define cl_khr_icd 1
-
-/* cl_platform_info */
-#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
-
-/* Additional Error Codes */
-#define CL_PLATFORM_NOT_FOUND_KHR -1001
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clIcdGetPlatformIDsKHR(cl_uint /* num_entries */,
- cl_platform_id * /* platforms */,
- cl_uint * /* num_platforms */);
-
-typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)(
- cl_uint /* num_entries */,
- cl_platform_id * /* platforms */,
- cl_uint * /* num_platforms */);
-
-
-/******************************************
-* cl_nv_device_attribute_query extension *
-******************************************/
-/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */
-#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
-#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
-#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002
-#define CL_DEVICE_WARP_SIZE_NV 0x4003
-#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
-#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
-#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
-
-
-/*********************************
-* cl_amd_device_attribute_query *
-*********************************/
-#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036
-
-
-#ifdef CL_VERSION_1_1
- /***********************************
- * cl_ext_device_fission extension *
- ***********************************/
- #define cl_ext_device_fission 1
-
- extern CL_API_ENTRY cl_int CL_API_CALL
- clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- typedef CL_API_ENTRY cl_int
- (CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- extern CL_API_ENTRY cl_int CL_API_CALL
- clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- typedef CL_API_ENTRY cl_int
- (CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- typedef cl_ulong cl_device_partition_property_ext;
- extern CL_API_ENTRY cl_int CL_API_CALL
- clCreateSubDevicesEXT( cl_device_id /*in_device*/,
- const cl_device_partition_property_ext * /* properties */,
- cl_uint /*num_entries*/,
- cl_device_id * /*out_devices*/,
- cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- extern CL_API_ENTRY cl_int
- ( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/,
- const cl_device_partition_property_ext * /* properties */,
- cl_uint /*num_entries*/,
- cl_device_id * /*out_devices*/,
- cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
-
- /* cl_device_partition_property_ext */
- #define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050
- #define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051
- #define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052
- #define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053
-
- /* clDeviceGetInfo selectors */
- #define CL_DEVICE_PARENT_DEVICE_EXT 0x4054
- #define CL_DEVICE_PARTITION_TYPES_EXT 0x4055
- #define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056
- #define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057
- #define CL_DEVICE_PARTITION_STYLE_EXT 0x4058
-
- /* error codes */
- #define CL_DEVICE_PARTITION_FAILED_EXT -1057
- #define CL_INVALID_PARTITION_COUNT_EXT -1058
- #define CL_INVALID_PARTITION_NAME_EXT -1059
-
- /* CL_AFFINITY_DOMAINs */
- #define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1
- #define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2
- #define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3
- #define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4
- #define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10
- #define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100
-
- /* cl_device_partition_property_ext list terminators */
- #define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0)
- #define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0)
- #define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1)
-
-
-
-#endif /* CL_VERSION_1_1 */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __CL_EXT_H */
diff --git a/lib/gpu/geryon/opencl/CL/cl_gl.h b/lib/gpu/geryon/opencl/CL/cl_gl.h
deleted file mode 100644
index 6eeae1e16..000000000
--- a/lib/gpu/geryon/opencl/CL/cl_gl.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/**********************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- **********************************************************************************/
-
-/* $Revision: 11708 $ on $Date: 2010-06-14 12:06:24 +0530 (Mon, 14 Jun 2010) $ */
-
-/*
- * cl_gl.h contains Khronos-approved (KHR) OpenCL extensions which have
- * OpenGL dependencies. The application is responsible for #including
- * OpenGL or OpenGL ES headers before #including cl_gl.h.
- */
-
-#ifndef __OPENCL_CL_GL_H
-#define __OPENCL_CL_GL_H
-
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#include <OpenGL/CGLDevice.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef cl_uint cl_gl_object_type;
-typedef cl_uint cl_gl_texture_info;
-typedef cl_uint cl_gl_platform_info;
-typedef struct __GLsync *cl_GLsync;
-
-/* cl_gl_object_type */
-#define CL_GL_OBJECT_BUFFER 0x2000
-#define CL_GL_OBJECT_TEXTURE2D 0x2001
-#define CL_GL_OBJECT_TEXTURE3D 0x2002
-#define CL_GL_OBJECT_RENDERBUFFER 0x2003
-
-/* cl_gl_texture_info */
-#define CL_GL_TEXTURE_TARGET 0x2004
-#define CL_GL_MIPMAP_LEVEL 0x2005
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLBuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLuint /* bufobj */,
- int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLTexture2D(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLenum /* target */,
- cl_GLint /* miplevel */,
- cl_GLuint /* texture */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLTexture3D(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLenum /* target */,
- cl_GLint /* miplevel */,
- cl_GLuint /* texture */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLRenderbuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLuint /* renderbuffer */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLObjectInfo(cl_mem /* memobj */,
- cl_gl_object_type * /* gl_object_type */,
- cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLTextureInfo(cl_mem /* memobj */,
- cl_gl_texture_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */,
- cl_uint /* num_objects */,
- const cl_mem * /* mem_objects */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */,
- cl_uint /* num_objects */,
- const cl_mem * /* mem_objects */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-/* cl_khr_gl_sharing extension */
-
-#define cl_khr_gl_sharing 1
-
-typedef cl_uint cl_gl_context_info;
-
-/* Additional Error Codes */
-#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000
-
-/* cl_gl_context_info */
-#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006
-#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007
-
-/* Additional cl_context_properties */
-#define CL_GL_CONTEXT_KHR 0x2008
-#define CL_EGL_DISPLAY_KHR 0x2009
-#define CL_GLX_DISPLAY_KHR 0x200A
-#define CL_WGL_HDC_KHR 0x200B
-#define CL_CGL_SHAREGROUP_KHR 0x200C
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLContextInfoKHR(const cl_context_properties * /* properties */,
- cl_gl_context_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
- const cl_context_properties * properties,
- cl_gl_context_info param_name,
- size_t param_value_size,
- void * param_value,
- size_t * param_value_size_ret);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_CL_GL_H */
diff --git a/lib/gpu/geryon/opencl/CL/cl_gl_ext.h b/lib/gpu/geryon/opencl/CL/cl_gl_ext.h
deleted file mode 100644
index 90996f2e0..000000000
--- a/lib/gpu/geryon/opencl/CL/cl_gl_ext.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**********************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- **********************************************************************************/
-
-/* $Revision: 11708 $ on $Date: 2010-06-14 12:06:24 +0530 (Mon, 14 Jun 2010) $ */
-
-/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */
-/* OpenGL dependencies. */
-
-#ifndef __OPENCL_CL_GL_EXT_H
-#define __OPENCL_CL_GL_EXT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __APPLE__
- #include <OpenCL/cl_gl.h>
-#else
- #include <CL/cl_gl.h>
-#endif
-
-/*
- * For each extension, follow this template
- * /* cl_VEN_extname extension */
-/* #define cl_VEN_extname 1
- * ... define new types, if any
- * ... define new tokens, if any
- * ... define new APIs, if any
- *
- * If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header
- * This allows us to avoid having to decide whether to include GL headers or GLES here.
- */
-
-/*
- * cl_khr_gl_event extension
- * See section 9.9 in the OpenCL 1.1 spec for more information
- */
-#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D
-
-extern CL_API_ENTRY cl_event CL_API_CALL
-clCreateEventFromGLsyncKHR(cl_context /* context */,
- cl_GLsync /* cl_GLsync */,
- cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_CL_GL_EXT_H */
diff --git a/lib/gpu/geryon/opencl/CL/cl_platform.h b/lib/gpu/geryon/opencl/CL/cl_platform.h
deleted file mode 100644
index 337d12033..000000000
--- a/lib/gpu/geryon/opencl/CL/cl_platform.h
+++ /dev/null
@@ -1,1198 +0,0 @@
-/**********************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- **********************************************************************************/
-
-/* $Revision: 11803 $ on $Date: 2010-06-25 22:32:12 +0530 (Fri, 25 Jun 2010) $ */
-
-#ifndef __CL_PLATFORM_H
-#define __CL_PLATFORM_H
-
-#ifdef __APPLE__
- /* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */
- #include <AvailabilityMacros.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_WIN32)
-#define CL_API_ENTRY
-#define CL_API_CALL __stdcall
-#define CL_CALLBACK __stdcall
-#else
-#define CL_API_ENTRY
-#define CL_API_CALL
-#define CL_CALLBACK
-#endif
-
-#ifdef __APPLE__
- #define CL_EXTENSION_WEAK_LINK __attribute__((weak_import))
- #define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
- #define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
- #define CL_API_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK
- #define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK
- #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
-#else
- #define CL_EXTENSION_WEAK_LINK
- #define CL_API_SUFFIX__VERSION_1_0
- #define CL_EXT_SUFFIX__VERSION_1_0
- #define CL_API_SUFFIX__VERSION_1_1
- #define CL_EXT_SUFFIX__VERSION_1_1
- #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED
-#endif
-
-#if (defined (_WIN32) && defined(_MSC_VER))
-
-/* scalar types */
-typedef signed __int8 cl_char;
-typedef unsigned __int8 cl_uchar;
-typedef signed __int16 cl_short;
-typedef unsigned __int16 cl_ushort;
-typedef signed __int32 cl_int;
-typedef unsigned __int32 cl_uint;
-typedef signed __int64 cl_long;
-typedef unsigned __int64 cl_ulong;
-
-typedef unsigned __int16 cl_half;
-typedef float cl_float;
-typedef double cl_double;
-
-/* Macro names and corresponding values defined by OpenCL */
-#define CL_CHAR_BIT 8
-#define CL_SCHAR_MAX 127
-#define CL_SCHAR_MIN (-127-1)
-#define CL_CHAR_MAX CL_SCHAR_MAX
-#define CL_CHAR_MIN CL_SCHAR_MIN
-#define CL_UCHAR_MAX 255
-#define CL_SHRT_MAX 32767
-#define CL_SHRT_MIN (-32767-1)
-#define CL_USHRT_MAX 65535
-#define CL_INT_MAX 2147483647
-#define CL_INT_MIN (-2147483647-1)
-#define CL_UINT_MAX 0xffffffffU
-#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL)
-#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
-#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)
-
-#define CL_FLT_DIG 6
-#define CL_FLT_MANT_DIG 24
-#define CL_FLT_MAX_10_EXP +38
-#define CL_FLT_MAX_EXP +128
-#define CL_FLT_MIN_10_EXP -37
-#define CL_FLT_MIN_EXP -125
-#define CL_FLT_RADIX 2
-#define CL_FLT_MAX 340282346638528859811704183484516925440.0f
-#define CL_FLT_MIN 1.175494350822287507969e-38f
-#define CL_FLT_EPSILON 0x1.0p-23f
-
-#define CL_DBL_DIG 15
-#define CL_DBL_MANT_DIG 53
-#define CL_DBL_MAX_10_EXP +308
-#define CL_DBL_MAX_EXP +1024
-#define CL_DBL_MIN_10_EXP -307
-#define CL_DBL_MIN_EXP -1021
-#define CL_DBL_RADIX 2
-#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0
-#define CL_DBL_MIN 2.225073858507201383090e-308
-#define CL_DBL_EPSILON 2.220446049250313080847e-16
-
-#define CL_M_E 2.718281828459045090796
-#define CL_M_LOG2E 1.442695040888963387005
-#define CL_M_LOG10E 0.434294481903251816668
-#define CL_M_LN2 0.693147180559945286227
-#define CL_M_LN10 2.302585092994045901094
-#define CL_M_PI 3.141592653589793115998
-#define CL_M_PI_2 1.570796326794896557999
-#define CL_M_PI_4 0.785398163397448278999
-#define CL_M_1_PI 0.318309886183790691216
-#define CL_M_2_PI 0.636619772367581382433
-#define CL_M_2_SQRTPI 1.128379167095512558561
-#define CL_M_SQRT2 1.414213562373095145475
-#define CL_M_SQRT1_2 0.707106781186547572737
-
-#define CL_M_E_F 2.71828174591064f
-#define CL_M_LOG2E_F 1.44269502162933f
-#define CL_M_LOG10E_F 0.43429449200630f
-#define CL_M_LN2_F 0.69314718246460f
-#define CL_M_LN10_F 2.30258512496948f
-#define CL_M_PI_F 3.14159274101257f
-#define CL_M_PI_2_F 1.57079637050629f
-#define CL_M_PI_4_F 0.78539818525314f
-#define CL_M_1_PI_F 0.31830987334251f
-#define CL_M_2_PI_F 0.63661974668503f
-#define CL_M_2_SQRTPI_F 1.12837922573090f
-#define CL_M_SQRT2_F 1.41421353816986f
-#define CL_M_SQRT1_2_F 0.70710676908493f
-
-#define CL_NAN (CL_INFINITY - CL_INFINITY)
-#define CL_HUGE_VALF ((cl_float) 1e50)
-#define CL_HUGE_VAL ((cl_double) 1e500)
-#define CL_MAXFLOAT CL_FLT_MAX
-#define CL_INFINITY CL_HUGE_VALF
-
-#else
-
-#include <stdint.h>
-
-/* scalar types */
-typedef int8_t cl_char;
-typedef uint8_t cl_uchar;
-typedef int16_t cl_short __attribute__((aligned(2)));
-typedef uint16_t cl_ushort __attribute__((aligned(2)));
-typedef int32_t cl_int __attribute__((aligned(4)));
-typedef uint32_t cl_uint __attribute__((aligned(4)));
-typedef int64_t cl_long __attribute__((aligned(8)));
-typedef uint64_t cl_ulong __attribute__((aligned(8)));
-
-typedef uint16_t cl_half __attribute__((aligned(2)));
-typedef float cl_float __attribute__((aligned(4)));
-typedef double cl_double __attribute__((aligned(8)));
-
-/* Macro names and corresponding values defined by OpenCL */
-#define CL_CHAR_BIT 8
-#define CL_SCHAR_MAX 127
-#define CL_SCHAR_MIN (-127-1)
-#define CL_CHAR_MAX CL_SCHAR_MAX
-#define CL_CHAR_MIN CL_SCHAR_MIN
-#define CL_UCHAR_MAX 255
-#define CL_SHRT_MAX 32767
-#define CL_SHRT_MIN (-32767-1)
-#define CL_USHRT_MAX 65535
-#define CL_INT_MAX 2147483647
-#define CL_INT_MIN (-2147483647-1)
-#define CL_UINT_MAX 0xffffffffU
-#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL)
-#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
-#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)
-
-#define CL_FLT_DIG 6
-#define CL_FLT_MANT_DIG 24
-#define CL_FLT_MAX_10_EXP +38
-#define CL_FLT_MAX_EXP +128
-#define CL_FLT_MIN_10_EXP -37
-#define CL_FLT_MIN_EXP -125
-#define CL_FLT_RADIX 2
-#define CL_FLT_MAX 0x1.fffffep127f
-#define CL_FLT_MIN 0x1.0p-126f
-#define CL_FLT_EPSILON 0x1.0p-23f
-
-#define CL_DBL_DIG 15
-#define CL_DBL_MANT_DIG 53
-#define CL_DBL_MAX_10_EXP +308
-#define CL_DBL_MAX_EXP +1024
-#define CL_DBL_MIN_10_EXP -307
-#define CL_DBL_MIN_EXP -1021
-#define CL_DBL_RADIX 2
-#define CL_DBL_MAX 0x1.fffffffffffffp1023
-#define CL_DBL_MIN 0x1.0p-1022
-#define CL_DBL_EPSILON 0x1.0p-52
-
-#define CL_M_E 2.718281828459045090796
-#define CL_M_LOG2E 1.442695040888963387005
-#define CL_M_LOG10E 0.434294481903251816668
-#define CL_M_LN2 0.693147180559945286227
-#define CL_M_LN10 2.302585092994045901094
-#define CL_M_PI 3.141592653589793115998
-#define CL_M_PI_2 1.570796326794896557999
-#define CL_M_PI_4 0.785398163397448278999
-#define CL_M_1_PI 0.318309886183790691216
-#define CL_M_2_PI 0.636619772367581382433
-#define CL_M_2_SQRTPI 1.128379167095512558561
-#define CL_M_SQRT2 1.414213562373095145475
-#define CL_M_SQRT1_2 0.707106781186547572737
-
-#define CL_M_E_F 2.71828174591064f
-#define CL_M_LOG2E_F 1.44269502162933f
-#define CL_M_LOG10E_F 0.43429449200630f
-#define CL_M_LN2_F 0.69314718246460f
-#define CL_M_LN10_F 2.30258512496948f
-#define CL_M_PI_F 3.14159274101257f
-#define CL_M_PI_2_F 1.57079637050629f
-#define CL_M_PI_4_F 0.78539818525314f
-#define CL_M_1_PI_F 0.31830987334251f
-#define CL_M_2_PI_F 0.63661974668503f
-#define CL_M_2_SQRTPI_F 1.12837922573090f
-#define CL_M_SQRT2_F 1.41421353816986f
-#define CL_M_SQRT1_2_F 0.70710676908493f
-
-#if defined( __GNUC__ )
- #define CL_HUGE_VALF __builtin_huge_valf()
- #define CL_HUGE_VAL __builtin_huge_val()
- #define CL_NAN __builtin_nanf( "" )
-#else
- #define CL_HUGE_VALF ((cl_float) 1e50)
- #define CL_HUGE_VAL ((cl_double) 1e500)
- float nanf( const char * );
- #define CL_NAN nanf( "" )
-#endif
-#define CL_MAXFLOAT CL_FLT_MAX
-#define CL_INFINITY CL_HUGE_VALF
-
-#endif
-
-#include <stddef.h>
-
-/* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */
-typedef unsigned int cl_GLuint;
-typedef int cl_GLint;
-typedef unsigned int cl_GLenum;
-
-/*
- * Vector types
- *
- * Note: OpenCL requires that all types be naturally aligned.
- * This means that vector types must be naturally aligned.
- * For example, a vector of four floats must be aligned to
- * a 16 byte boundary (calculated as 4 * the natural 4-byte
- * alignment of the float). The alignment qualifiers here
- * will only function properly if your compiler supports them
- * and if you don't actively work to defeat them. For example,
- * in order for a cl_float4 to be 16 byte aligned in a struct,
- * the start of the struct must itself be 16-byte aligned.
- *
- * Maintaining proper alignment is the user's responsibility.
- */
-
-/* Define basic vector types */
-#if defined( __VEC__ )
- #include <altivec.h> /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */
- typedef vector unsigned char __cl_uchar16;
- typedef vector signed char __cl_char16;
- typedef vector unsigned short __cl_ushort8;
- typedef vector signed short __cl_short8;
- typedef vector unsigned int __cl_uint4;
- typedef vector signed int __cl_int4;
- typedef vector float __cl_float4;
- #define __CL_UCHAR16__ 1
- #define __CL_CHAR16__ 1
- #define __CL_USHORT8__ 1
- #define __CL_SHORT8__ 1
- #define __CL_UINT4__ 1
- #define __CL_INT4__ 1
- #define __CL_FLOAT4__ 1
-#endif
-
-#if defined( __SSE__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <xmmintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef float __cl_float4 __attribute__((vector_size(16)));
- #else
- typedef __m128 __cl_float4;
- #endif
- #define __CL_FLOAT4__ 1
-#endif
-
-#if defined( __SSE2__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <emmintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16)));
- typedef cl_char __cl_char16 __attribute__((vector_size(16)));
- typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16)));
- typedef cl_short __cl_short8 __attribute__((vector_size(16)));
- typedef cl_uint __cl_uint4 __attribute__((vector_size(16)));
- typedef cl_int __cl_int4 __attribute__((vector_size(16)));
- typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16)));
- typedef cl_long __cl_long2 __attribute__((vector_size(16)));
- typedef cl_double __cl_double2 __attribute__((vector_size(16)));
- #else
- typedef __m128i __cl_uchar16;
- typedef __m128i __cl_char16;
- typedef __m128i __cl_ushort8;
- typedef __m128i __cl_short8;
- typedef __m128i __cl_uint4;
- typedef __m128i __cl_int4;
- typedef __m128i __cl_ulong2;
- typedef __m128i __cl_long2;
- typedef __m128d __cl_double2;
- #endif
- #define __CL_UCHAR16__ 1
- #define __CL_CHAR16__ 1
- #define __CL_USHORT8__ 1
- #define __CL_SHORT8__ 1
- #define __CL_INT4__ 1
- #define __CL_UINT4__ 1
- #define __CL_ULONG2__ 1
- #define __CL_LONG2__ 1
- #define __CL_DOUBLE2__ 1
-#endif
-
-#if defined( __MMX__ )
- #include <mmintrin.h>
- #if defined( __GNUC__ )
- typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8)));
- typedef cl_char __cl_char8 __attribute__((vector_size(8)));
- typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8)));
- typedef cl_short __cl_short4 __attribute__((vector_size(8)));
- typedef cl_uint __cl_uint2 __attribute__((vector_size(8)));
- typedef cl_int __cl_int2 __attribute__((vector_size(8)));
- typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8)));
- typedef cl_long __cl_long1 __attribute__((vector_size(8)));
- typedef cl_float __cl_float2 __attribute__((vector_size(8)));
- #else
- typedef __m64 __cl_uchar8;
- typedef __m64 __cl_char8;
- typedef __m64 __cl_ushort4;
- typedef __m64 __cl_short4;
- typedef __m64 __cl_uint2;
- typedef __m64 __cl_int2;
- typedef __m64 __cl_ulong1;
- typedef __m64 __cl_long1;
- typedef __m64 __cl_float2;
- #endif
- #define __CL_UCHAR8__ 1
- #define __CL_CHAR8__ 1
- #define __CL_USHORT4__ 1
- #define __CL_SHORT4__ 1
- #define __CL_INT2__ 1
- #define __CL_UINT2__ 1
- #define __CL_ULONG1__ 1
- #define __CL_LONG1__ 1
- #define __CL_FLOAT2__ 1
-#endif
-
-#if defined( __AVX__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <immintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef cl_float __cl_float8 __attribute__((vector_size(32)));
- typedef cl_double __cl_double4 __attribute__((vector_size(32)));
- #else
- typedef __m256 __cl_float8;
- typedef __m256d __cl_double4;
- #endif
- #define __CL_FLOAT8__ 1
- #define __CL_DOUBLE4__ 1
-#endif
-
-/* Define alignment keys */
-#if defined( __GNUC__ )
- #define CL_ALIGNED(_x) __attribute__ ((aligned(_x)))
-#elif defined( _WIN32) && (_MSC_VER)
- /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */
- /* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */
- /* #include <crtdefs.h> */
- /* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */
- #define CL_ALIGNED(_x)
-#else
- #warning Need to implement some method to align data here
- #define CL_ALIGNED(_x)
-#endif
-
-/* Indicate whether .xyzw, .s0123 and .hi.lo are supported */
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- /* .xyzw and .s0123...{f|F} are supported */
- #define CL_HAS_NAMED_VECTOR_FIELDS 1
- /* .hi and .lo are supported */
- #define CL_HAS_HI_LO_VECTOR_FIELDS 1
-#endif
-
-/* Define cl_vector types */
-
-/* ---- cl_charn ---- */
-typedef union
-{
- cl_char CL_ALIGNED(2) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y; };
- __extension__ struct{ cl_char s0, s1; };
- __extension__ struct{ cl_char lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2;
-#endif
-}cl_char2;
-
-typedef union
-{
- cl_char CL_ALIGNED(4) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w; };
- __extension__ struct{ cl_char s0, s1, s2, s3; };
- __extension__ struct{ cl_char2 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[2];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4;
-#endif
-}cl_char4;
-
-/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */
-typedef cl_char4 cl_char3;
-
-typedef union
-{
- cl_char CL_ALIGNED(8) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w; };
- __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_char4 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[4];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4[2];
-#endif
-#if defined( __CL_CHAR8__ )
- __cl_char8 v8;
-#endif
-}cl_char8;
-
-typedef union
-{
- cl_char CL_ALIGNED(16) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_char8 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[8];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4[4];
-#endif
-#if defined( __CL_CHAR8__ )
- __cl_char8 v8[2];
-#endif
-#if defined( __CL_CHAR16__ )
- __cl_char16 v16;
-#endif
-}cl_char16;
-
-
-/* ---- cl_ucharn ---- */
-typedef union
-{
- cl_uchar CL_ALIGNED(2) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y; };
- __extension__ struct{ cl_uchar s0, s1; };
- __extension__ struct{ cl_uchar lo, hi; };
-#endif
-#if defined( __cl_uchar2__)
- __cl_uchar2 v2;
-#endif
-}cl_uchar2;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(4) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3; };
- __extension__ struct{ cl_uchar2 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[2];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4;
-#endif
-}cl_uchar4;
-
-/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */
-typedef cl_uchar4 cl_uchar3;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(8) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_uchar4 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[4];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4[2];
-#endif
-#if defined( __CL_UCHAR8__ )
- __cl_uchar8 v8;
-#endif
-}cl_uchar8;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(16) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_uchar8 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[8];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4[4];
-#endif
-#if defined( __CL_UCHAR8__ )
- __cl_uchar8 v8[2];
-#endif
-#if defined( __CL_UCHAR16__ )
- __cl_uchar16 v16;
-#endif
-}cl_uchar16;
-
-
-/* ---- cl_shortn ---- */
-typedef union
-{
- cl_short CL_ALIGNED(4) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y; };
- __extension__ struct{ cl_short s0, s1; };
- __extension__ struct{ cl_short lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2;
-#endif
-}cl_short2;
-
-typedef union
-{
- cl_short CL_ALIGNED(8) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w; };
- __extension__ struct{ cl_short s0, s1, s2, s3; };
- __extension__ struct{ cl_short2 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[2];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4;
-#endif
-}cl_short4;
-
-/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */
-typedef cl_short4 cl_short3;
-
-typedef union
-{
- cl_short CL_ALIGNED(16) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w; };
- __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_short4 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[4];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4[2];
-#endif
-#if defined( __CL_SHORT8__ )
- __cl_short8 v8;
-#endif
-}cl_short8;
-
-typedef union
-{
- cl_short CL_ALIGNED(32) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_short8 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[8];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4[4];
-#endif
-#if defined( __CL_SHORT8__ )
- __cl_short8 v8[2];
-#endif
-#if defined( __CL_SHORT16__ )
- __cl_short16 v16;
-#endif
-}cl_short16;
-
-
-/* ---- cl_ushortn ---- */
-typedef union
-{
- cl_ushort CL_ALIGNED(4) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y; };
- __extension__ struct{ cl_ushort s0, s1; };
- __extension__ struct{ cl_ushort lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2;
-#endif
-}cl_ushort2;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(8) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3; };
- __extension__ struct{ cl_ushort2 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[2];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4;
-#endif
-}cl_ushort4;
-
-/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */
-typedef cl_ushort4 cl_ushort3;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(16) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_ushort4 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[4];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4[2];
-#endif
-#if defined( __CL_USHORT8__ )
- __cl_ushort8 v8;
-#endif
-}cl_ushort8;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(32) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_ushort8 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[8];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4[4];
-#endif
-#if defined( __CL_USHORT8__ )
- __cl_ushort8 v8[2];
-#endif
-#if defined( __CL_USHORT16__ )
- __cl_ushort16 v16;
-#endif
-}cl_ushort16;
-
-/* ---- cl_intn ---- */
-typedef union
-{
- cl_int CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y; };
- __extension__ struct{ cl_int s0, s1; };
- __extension__ struct{ cl_int lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2;
-#endif
-}cl_int2;
-
-typedef union
-{
- cl_int CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w; };
- __extension__ struct{ cl_int s0, s1, s2, s3; };
- __extension__ struct{ cl_int2 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[2];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4;
-#endif
-}cl_int4;
-
-/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */
-typedef cl_int4 cl_int3;
-
-typedef union
-{
- cl_int CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w; };
- __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_int4 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[4];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4[2];
-#endif
-#if defined( __CL_INT8__ )
- __cl_int8 v8;
-#endif
-}cl_int8;
-
-typedef union
-{
- cl_int CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_int8 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[8];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4[4];
-#endif
-#if defined( __CL_INT8__ )
- __cl_int8 v8[2];
-#endif
-#if defined( __CL_INT16__ )
- __cl_int16 v16;
-#endif
-}cl_int16;
-
-
-/* ---- cl_uintn ---- */
-typedef union
-{
- cl_uint CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y; };
- __extension__ struct{ cl_uint s0, s1; };
- __extension__ struct{ cl_uint lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2;
-#endif
-}cl_uint2;
-
-typedef union
-{
- cl_uint CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w; };
- __extension__ struct{ cl_uint s0, s1, s2, s3; };
- __extension__ struct{ cl_uint2 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[2];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4;
-#endif
-}cl_uint4;
-
-/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */
-typedef cl_uint4 cl_uint3;
-
-typedef union
-{
- cl_uint CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w; };
- __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_uint4 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[4];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4[2];
-#endif
-#if defined( __CL_UINT8__ )
- __cl_uint8 v8;
-#endif
-}cl_uint8;
-
-typedef union
-{
- cl_uint CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_uint8 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[8];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4[4];
-#endif
-#if defined( __CL_UINT8__ )
- __cl_uint8 v8[2];
-#endif
-#if defined( __CL_UINT16__ )
- __cl_uint16 v16;
-#endif
-}cl_uint16;
-
-/* ---- cl_longn ---- */
-typedef union
-{
- cl_long CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y; };
- __extension__ struct{ cl_long s0, s1; };
- __extension__ struct{ cl_long lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2;
-#endif
-}cl_long2;
-
-typedef union
-{
- cl_long CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w; };
- __extension__ struct{ cl_long s0, s1, s2, s3; };
- __extension__ struct{ cl_long2 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[2];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4;
-#endif
-}cl_long4;
-
-/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */
-typedef cl_long4 cl_long3;
-
-typedef union
-{
- cl_long CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w; };
- __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_long4 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[4];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4[2];
-#endif
-#if defined( __CL_LONG8__ )
- __cl_long8 v8;
-#endif
-}cl_long8;
-
-typedef union
-{
- cl_long CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_long8 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[8];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4[4];
-#endif
-#if defined( __CL_LONG8__ )
- __cl_long8 v8[2];
-#endif
-#if defined( __CL_LONG16__ )
- __cl_long16 v16;
-#endif
-}cl_long16;
-
-
-/* ---- cl_ulongn ---- */
-typedef union
-{
- cl_ulong CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y; };
- __extension__ struct{ cl_ulong s0, s1; };
- __extension__ struct{ cl_ulong lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2;
-#endif
-}cl_ulong2;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3; };
- __extension__ struct{ cl_ulong2 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[2];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4;
-#endif
-}cl_ulong4;
-
-/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */
-typedef cl_ulong4 cl_ulong3;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_ulong4 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[4];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4[2];
-#endif
-#if defined( __CL_ULONG8__ )
- __cl_ulong8 v8;
-#endif
-}cl_ulong8;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_ulong8 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[8];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4[4];
-#endif
-#if defined( __CL_ULONG8__ )
- __cl_ulong8 v8[2];
-#endif
-#if defined( __CL_ULONG16__ )
- __cl_ulong16 v16;
-#endif
-}cl_ulong16;
-
-
-/* --- cl_floatn ---- */
-
-typedef union
-{
- cl_float CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y; };
- __extension__ struct{ cl_float s0, s1; };
- __extension__ struct{ cl_float lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2;
-#endif
-}cl_float2;
-
-typedef union
-{
- cl_float CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w; };
- __extension__ struct{ cl_float s0, s1, s2, s3; };
- __extension__ struct{ cl_float2 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[2];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4;
-#endif
-}cl_float4;
-
-/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */
-typedef cl_float4 cl_float3;
-
-typedef union
-{
- cl_float CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w; };
- __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_float4 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[4];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4[2];
-#endif
-#if defined( __CL_FLOAT8__ )
- __cl_float8 v8;
-#endif
-}cl_float8;
-
-typedef union
-{
- cl_float CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_float8 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[8];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4[4];
-#endif
-#if defined( __CL_FLOAT8__ )
- __cl_float8 v8[2];
-#endif
-#if defined( __CL_FLOAT16__ )
- __cl_float16 v16;
-#endif
-}cl_float16;
-
-/* --- cl_doublen ---- */
-
-typedef union
-{
- cl_double CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y; };
- __extension__ struct{ cl_double s0, s1; };
- __extension__ struct{ cl_double lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2;
-#endif
-}cl_double2;
-
-typedef union
-{
- cl_double CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w; };
- __extension__ struct{ cl_double s0, s1, s2, s3; };
- __extension__ struct{ cl_double2 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[2];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4;
-#endif
-}cl_double4;
-
-/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */
-typedef cl_double4 cl_double3;
-
-typedef union
-{
- cl_double CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w; };
- __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_double4 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[4];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4[2];
-#endif
-#if defined( __CL_DOUBLE8__ )
- __cl_double8 v8;
-#endif
-}cl_double8;
-
-typedef union
-{
- cl_double CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_double8 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[8];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4[4];
-#endif
-#if defined( __CL_DOUBLE8__ )
- __cl_double8 v8[2];
-#endif
-#if defined( __CL_DOUBLE16__ )
- __cl_double16 v16;
-#endif
-}cl_double16;
-
-/* Macro to facilitate debugging
- * Usage:
- * Place CL_PROGRAM_STRING_DEBUG_INFO on the line before the first line of your source.
- * The first line ends with: CL_PROGRAM_STRING_BEGIN \"
- * Each line thereafter of OpenCL C source must end with: \n\
- * The last line ends in ";
- *
- * Example:
- *
- * const char *my_program = CL_PROGRAM_STRING_BEGIN "\
- * kernel void foo( int a, float * b ) \n\
- * { \n\
- * // my comment \n\
- * *b[ get_global_id(0)] = a; \n\
- * } \n\
- * ";
- *
- * This should correctly set up the line, (column) and file information for your source
- * string so you can do source level debugging.
- */
-#define __CL_STRINGIFY( _x ) # _x
-#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x )
-#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CL_PLATFORM_H */
diff --git a/lib/gpu/geryon/opencl/CL/clext.h b/lib/gpu/geryon/opencl/CL/clext.h
deleted file mode 100644
index 868ccb727..000000000
--- a/lib/gpu/geryon/opencl/CL/clext.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-** Copyright 1998-2002, NVIDIA Corporation.
-** All Rights Reserved.
-**
-** THE INFORMATION CONTAINED HEREIN IS PROPRIETARY AND CONFIDENTIAL TO
-** NVIDIA, CORPORATION. USE, REPRODUCTION OR DISCLOSURE TO ANY THIRD PARTY
-** IS SUBJECT TO WRITTEN PRE-APPROVAL BY NVIDIA, CORPORATION.
-**
-**
-*/
-#ifndef __CLEXT_H
-#define __CLEXT_H
-
-#define CL_NV_DEVICE_COMPUTE_CAPABILITY_MAJOR 0x4000
-#define CL_NV_DEVICE_COMPUTE_CAPABILITY_MINOR 0x4001
-#define CL_NV_DEVICE_REGISTERS_PER_BLOCK 0x4002
-#define CL_NV_DEVICE_WARP_SIZE 0x4003
-#define CL_NV_DEVICE_GPU_OVERLAP 0x4004
-#define CL_NV_DEVICE_KERNEL_EXEC_TIMEOUT 0x4005
-#define CL_NV_DEVICE_INTEGRATED_MEMORY 0x4006
-
-#endif
diff --git a/lib/gpu/geryon/opencl/CL/opencl.h b/lib/gpu/geryon/opencl/CL/opencl.h
deleted file mode 100644
index 801729955..000000000
--- a/lib/gpu/geryon/opencl/CL/opencl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008-2010 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- ******************************************************************************/
-
-/* $Revision: 11708 $ on $Date: 2010-06-14 12:06:24 +0530 (Mon, 14 Jun 2010) $ */
-
-#ifndef __OPENCL_H
-#define __OPENCL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __APPLE__
-
-#include <OpenCL/cl.h>
-#include <OpenCL/cl_gl.h>
-#include <OpenCL/cl_gl_ext.h>
-#include <OpenCL/cl_ext.h>
-
-#else
-
-#include <CL/cl.h>
-#include <CL/cl_gl.h>
-#include <CL/cl_gl_ext.h>
-#include <CL/cl_ext.h>
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_H */
-
diff --git a/lib/gpu/geryon/opencl_1_0/CL/cl.h b/lib/gpu/geryon/opencl_1_0/CL/cl.h
deleted file mode 100644
index 3f3811645..000000000
--- a/lib/gpu/geryon/opencl_1_0/CL/cl.h
+++ /dev/null
@@ -1,876 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008-2009 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- ******************************************************************************/
-
-/* $Revision: 10424 $ on $Date: 2010-02-17 14:34:49 -0800 (Wed, 17 Feb 2010) $ */
-
-#ifndef __OPENCL_CL_H
-#define __OPENCL_CL_H
-
-#ifdef __APPLE__
-#include <OpenCL/cl_platform.h>
-#else
-#include <CL/cl_platform.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/******************************************************************************/
-
-typedef struct _cl_platform_id * cl_platform_id;
-typedef struct _cl_device_id * cl_device_id;
-typedef struct _cl_context * cl_context;
-typedef struct _cl_command_queue * cl_command_queue;
-typedef struct _cl_mem * cl_mem;
-typedef struct _cl_program * cl_program;
-typedef struct _cl_kernel * cl_kernel;
-typedef struct _cl_event * cl_event;
-typedef struct _cl_sampler * cl_sampler;
-
-typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */
-typedef cl_ulong cl_bitfield;
-typedef cl_bitfield cl_device_type;
-typedef cl_uint cl_platform_info;
-typedef cl_uint cl_device_info;
-typedef cl_bitfield cl_device_address_info;
-typedef cl_bitfield cl_device_fp_config;
-typedef cl_uint cl_device_mem_cache_type;
-typedef cl_uint cl_device_local_mem_type;
-typedef cl_bitfield cl_device_exec_capabilities;
-typedef cl_bitfield cl_command_queue_properties;
-
-typedef intptr_t cl_context_properties;
-typedef cl_uint cl_context_info;
-typedef cl_uint cl_command_queue_info;
-typedef cl_uint cl_channel_order;
-typedef cl_uint cl_channel_type;
-typedef cl_bitfield cl_mem_flags;
-typedef cl_uint cl_mem_object_type;
-typedef cl_uint cl_mem_info;
-typedef cl_uint cl_image_info;
-typedef cl_uint cl_addressing_mode;
-typedef cl_uint cl_filter_mode;
-typedef cl_uint cl_sampler_info;
-typedef cl_bitfield cl_map_flags;
-typedef cl_uint cl_program_info;
-typedef cl_uint cl_program_build_info;
-typedef cl_int cl_build_status;
-typedef cl_uint cl_kernel_info;
-typedef cl_uint cl_kernel_work_group_info;
-typedef cl_uint cl_event_info;
-typedef cl_uint cl_command_type;
-typedef cl_uint cl_profiling_info;
-
-typedef struct _cl_image_format {
- cl_channel_order image_channel_order;
- cl_channel_type image_channel_data_type;
-} cl_image_format;
-
-
-
-/******************************************************************************/
-
-/* Error Codes */
-#define CL_SUCCESS 0
-#define CL_DEVICE_NOT_FOUND -1
-#define CL_DEVICE_NOT_AVAILABLE -2
-#define CL_COMPILER_NOT_AVAILABLE -3
-#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4
-#define CL_OUT_OF_RESOURCES -5
-#define CL_OUT_OF_HOST_MEMORY -6
-#define CL_PROFILING_INFO_NOT_AVAILABLE -7
-#define CL_MEM_COPY_OVERLAP -8
-#define CL_IMAGE_FORMAT_MISMATCH -9
-#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10
-#define CL_BUILD_PROGRAM_FAILURE -11
-#define CL_MAP_FAILURE -12
-
-#define CL_INVALID_VALUE -30
-#define CL_INVALID_DEVICE_TYPE -31
-#define CL_INVALID_PLATFORM -32
-#define CL_INVALID_DEVICE -33
-#define CL_INVALID_CONTEXT -34
-#define CL_INVALID_QUEUE_PROPERTIES -35
-#define CL_INVALID_COMMAND_QUEUE -36
-#define CL_INVALID_HOST_PTR -37
-#define CL_INVALID_MEM_OBJECT -38
-#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39
-#define CL_INVALID_IMAGE_SIZE -40
-#define CL_INVALID_SAMPLER -41
-#define CL_INVALID_BINARY -42
-#define CL_INVALID_BUILD_OPTIONS -43
-#define CL_INVALID_PROGRAM -44
-#define CL_INVALID_PROGRAM_EXECUTABLE -45
-#define CL_INVALID_KERNEL_NAME -46
-#define CL_INVALID_KERNEL_DEFINITION -47
-#define CL_INVALID_KERNEL -48
-#define CL_INVALID_ARG_INDEX -49
-#define CL_INVALID_ARG_VALUE -50
-#define CL_INVALID_ARG_SIZE -51
-#define CL_INVALID_KERNEL_ARGS -52
-#define CL_INVALID_WORK_DIMENSION -53
-#define CL_INVALID_WORK_GROUP_SIZE -54
-#define CL_INVALID_WORK_ITEM_SIZE -55
-#define CL_INVALID_GLOBAL_OFFSET -56
-#define CL_INVALID_EVENT_WAIT_LIST -57
-#define CL_INVALID_EVENT -58
-#define CL_INVALID_OPERATION -59
-#define CL_INVALID_GL_OBJECT -60
-#define CL_INVALID_BUFFER_SIZE -61
-#define CL_INVALID_MIP_LEVEL -62
-#define CL_INVALID_GLOBAL_WORK_SIZE -63
-
-/* OpenCL Version */
-#define CL_VERSION_1_0 1
-
-/* cl_bool */
-#define CL_FALSE 0
-#define CL_TRUE 1
-
-/* cl_platform_info */
-#define CL_PLATFORM_PROFILE 0x0900
-#define CL_PLATFORM_VERSION 0x0901
-#define CL_PLATFORM_NAME 0x0902
-#define CL_PLATFORM_VENDOR 0x0903
-#define CL_PLATFORM_EXTENSIONS 0x0904
-
-/* cl_device_type - bitfield */
-#define CL_DEVICE_TYPE_DEFAULT (1 << 0)
-#define CL_DEVICE_TYPE_CPU (1 << 1)
-#define CL_DEVICE_TYPE_GPU (1 << 2)
-#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3)
-#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF
-
-/* cl_device_info */
-#define CL_DEVICE_TYPE 0x1000
-#define CL_DEVICE_VENDOR_ID 0x1001
-#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002
-#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003
-#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004
-#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A
-#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B
-#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C
-#define CL_DEVICE_ADDRESS_BITS 0x100D
-#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E
-#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F
-#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010
-#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011
-#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012
-#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013
-#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014
-#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015
-#define CL_DEVICE_IMAGE_SUPPORT 0x1016
-#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017
-#define CL_DEVICE_MAX_SAMPLERS 0x1018
-#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019
-#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A
-#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B
-#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C
-#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D
-#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E
-#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F
-#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020
-#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021
-#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022
-#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023
-#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024
-#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025
-#define CL_DEVICE_ENDIAN_LITTLE 0x1026
-#define CL_DEVICE_AVAILABLE 0x1027
-#define CL_DEVICE_COMPILER_AVAILABLE 0x1028
-#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029
-#define CL_DEVICE_QUEUE_PROPERTIES 0x102A
-#define CL_DEVICE_NAME 0x102B
-#define CL_DEVICE_VENDOR 0x102C
-#define CL_DRIVER_VERSION 0x102D
-#define CL_DEVICE_PROFILE 0x102E
-#define CL_DEVICE_VERSION 0x102F
-#define CL_DEVICE_EXTENSIONS 0x1030
-#define CL_DEVICE_PLATFORM 0x1031
-/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */
-/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */
-
-/* cl_device_fp_config - bitfield */
-#define CL_FP_DENORM (1 << 0)
-#define CL_FP_INF_NAN (1 << 1)
-#define CL_FP_ROUND_TO_NEAREST (1 << 2)
-#define CL_FP_ROUND_TO_ZERO (1 << 3)
-#define CL_FP_ROUND_TO_INF (1 << 4)
-#define CL_FP_FMA (1 << 5)
-
-/* cl_device_mem_cache_type */
-#define CL_NONE 0x0
-#define CL_READ_ONLY_CACHE 0x1
-#define CL_READ_WRITE_CACHE 0x2
-
-/* cl_device_local_mem_type */
-#define CL_LOCAL 0x1
-#define CL_GLOBAL 0x2
-
-/* cl_device_exec_capabilities - bitfield */
-#define CL_EXEC_KERNEL (1 << 0)
-#define CL_EXEC_NATIVE_KERNEL (1 << 1)
-
-/* cl_command_queue_properties - bitfield */
-#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0)
-#define CL_QUEUE_PROFILING_ENABLE (1 << 1)
-
-/* cl_context_info */
-#define CL_CONTEXT_REFERENCE_COUNT 0x1080
-#define CL_CONTEXT_DEVICES 0x1081
-#define CL_CONTEXT_PROPERTIES 0x1082
-
-/* cl_context_info + cl_context_properties */
-#define CL_CONTEXT_PLATFORM 0x1084
-
-/* cl_command_queue_info */
-#define CL_QUEUE_CONTEXT 0x1090
-#define CL_QUEUE_DEVICE 0x1091
-#define CL_QUEUE_REFERENCE_COUNT 0x1092
-#define CL_QUEUE_PROPERTIES 0x1093
-
-/* cl_mem_flags - bitfield */
-#define CL_MEM_READ_WRITE (1 << 0)
-#define CL_MEM_WRITE_ONLY (1 << 1)
-#define CL_MEM_READ_ONLY (1 << 2)
-#define CL_MEM_USE_HOST_PTR (1 << 3)
-#define CL_MEM_ALLOC_HOST_PTR (1 << 4)
-#define CL_MEM_COPY_HOST_PTR (1 << 5)
-
-/* cl_channel_order */
-#define CL_R 0x10B0
-#define CL_A 0x10B1
-#define CL_RG 0x10B2
-#define CL_RA 0x10B3
-#define CL_RGB 0x10B4
-#define CL_RGBA 0x10B5
-#define CL_BGRA 0x10B6
-#define CL_ARGB 0x10B7
-#define CL_INTENSITY 0x10B8
-#define CL_LUMINANCE 0x10B9
-
-/* cl_channel_type */
-#define CL_SNORM_INT8 0x10D0
-#define CL_SNORM_INT16 0x10D1
-#define CL_UNORM_INT8 0x10D2
-#define CL_UNORM_INT16 0x10D3
-#define CL_UNORM_SHORT_565 0x10D4
-#define CL_UNORM_SHORT_555 0x10D5
-#define CL_UNORM_INT_101010 0x10D6
-#define CL_SIGNED_INT8 0x10D7
-#define CL_SIGNED_INT16 0x10D8
-#define CL_SIGNED_INT32 0x10D9
-#define CL_UNSIGNED_INT8 0x10DA
-#define CL_UNSIGNED_INT16 0x10DB
-#define CL_UNSIGNED_INT32 0x10DC
-#define CL_HALF_FLOAT 0x10DD
-#define CL_FLOAT 0x10DE
-
-/* cl_mem_object_type */
-#define CL_MEM_OBJECT_BUFFER 0x10F0
-#define CL_MEM_OBJECT_IMAGE2D 0x10F1
-#define CL_MEM_OBJECT_IMAGE3D 0x10F2
-
-/* cl_mem_info */
-#define CL_MEM_TYPE 0x1100
-#define CL_MEM_FLAGS 0x1101
-#define CL_MEM_SIZE 0x1102
-#define CL_MEM_HOST_PTR 0x1103
-#define CL_MEM_MAP_COUNT 0x1104
-#define CL_MEM_REFERENCE_COUNT 0x1105
-#define CL_MEM_CONTEXT 0x1106
-
-/* cl_image_info */
-#define CL_IMAGE_FORMAT 0x1110
-#define CL_IMAGE_ELEMENT_SIZE 0x1111
-#define CL_IMAGE_ROW_PITCH 0x1112
-#define CL_IMAGE_SLICE_PITCH 0x1113
-#define CL_IMAGE_WIDTH 0x1114
-#define CL_IMAGE_HEIGHT 0x1115
-#define CL_IMAGE_DEPTH 0x1116
-
-/* cl_addressing_mode */
-#define CL_ADDRESS_NONE 0x1130
-#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131
-#define CL_ADDRESS_CLAMP 0x1132
-#define CL_ADDRESS_REPEAT 0x1133
-
-/* cl_filter_mode */
-#define CL_FILTER_NEAREST 0x1140
-#define CL_FILTER_LINEAR 0x1141
-
-/* cl_sampler_info */
-#define CL_SAMPLER_REFERENCE_COUNT 0x1150
-#define CL_SAMPLER_CONTEXT 0x1151
-#define CL_SAMPLER_NORMALIZED_COORDS 0x1152
-#define CL_SAMPLER_ADDRESSING_MODE 0x1153
-#define CL_SAMPLER_FILTER_MODE 0x1154
-
-/* cl_map_flags - bitfield */
-#define CL_MAP_READ (1 << 0)
-#define CL_MAP_WRITE (1 << 1)
-
-/* cl_program_info */
-#define CL_PROGRAM_REFERENCE_COUNT 0x1160
-#define CL_PROGRAM_CONTEXT 0x1161
-#define CL_PROGRAM_NUM_DEVICES 0x1162
-#define CL_PROGRAM_DEVICES 0x1163
-#define CL_PROGRAM_SOURCE 0x1164
-#define CL_PROGRAM_BINARY_SIZES 0x1165
-#define CL_PROGRAM_BINARIES 0x1166
-
-/* cl_program_build_info */
-#define CL_PROGRAM_BUILD_STATUS 0x1181
-#define CL_PROGRAM_BUILD_OPTIONS 0x1182
-#define CL_PROGRAM_BUILD_LOG 0x1183
-
-/* cl_build_status */
-#define CL_BUILD_SUCCESS 0
-#define CL_BUILD_NONE -1
-#define CL_BUILD_ERROR -2
-#define CL_BUILD_IN_PROGRESS -3
-
-/* cl_kernel_info */
-#define CL_KERNEL_FUNCTION_NAME 0x1190
-#define CL_KERNEL_NUM_ARGS 0x1191
-#define CL_KERNEL_REFERENCE_COUNT 0x1192
-#define CL_KERNEL_CONTEXT 0x1193
-#define CL_KERNEL_PROGRAM 0x1194
-
-/* cl_kernel_work_group_info */
-#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0
-#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1
-#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2
-
-/* cl_event_info */
-#define CL_EVENT_COMMAND_QUEUE 0x11D0
-#define CL_EVENT_COMMAND_TYPE 0x11D1
-#define CL_EVENT_REFERENCE_COUNT 0x11D2
-#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3
-
-/* cl_command_type */
-#define CL_COMMAND_NDRANGE_KERNEL 0x11F0
-#define CL_COMMAND_TASK 0x11F1
-#define CL_COMMAND_NATIVE_KERNEL 0x11F2
-#define CL_COMMAND_READ_BUFFER 0x11F3
-#define CL_COMMAND_WRITE_BUFFER 0x11F4
-#define CL_COMMAND_COPY_BUFFER 0x11F5
-#define CL_COMMAND_READ_IMAGE 0x11F6
-#define CL_COMMAND_WRITE_IMAGE 0x11F7
-#define CL_COMMAND_COPY_IMAGE 0x11F8
-#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9
-#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA
-#define CL_COMMAND_MAP_BUFFER 0x11FB
-#define CL_COMMAND_MAP_IMAGE 0x11FC
-#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD
-#define CL_COMMAND_MARKER 0x11FE
-#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF
-#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200
-
-/* command execution status */
-#define CL_COMPLETE 0x0
-#define CL_RUNNING 0x1
-#define CL_SUBMITTED 0x2
-#define CL_QUEUED 0x3
-
-/* cl_profiling_info */
-#define CL_PROFILING_COMMAND_QUEUED 0x1280
-#define CL_PROFILING_COMMAND_SUBMIT 0x1281
-#define CL_PROFILING_COMMAND_START 0x1282
-#define CL_PROFILING_COMMAND_END 0x1283
-
-/********************************************************************************************************/
-
-/* Platform API */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetPlatformIDs(cl_uint /* num_entries */,
- cl_platform_id * /* platforms */,
- cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetPlatformInfo(cl_platform_id /* platform */,
- cl_platform_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Device APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetDeviceIDs(cl_platform_id /* platform */,
- cl_device_type /* device_type */,
- cl_uint /* num_entries */,
- cl_device_id * /* devices */,
- cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetDeviceInfo(cl_device_id /* device */,
- cl_device_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Context APIs */
-extern CL_API_ENTRY cl_context CL_API_CALL
-clCreateContext(const cl_context_properties * /* properties */,
- cl_uint /* num_devices */,
- const cl_device_id * /* devices */,
- void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
- void * /* user_data */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_context CL_API_CALL
-clCreateContextFromType(const cl_context_properties * /* properties */,
- cl_device_type /* device_type */,
- void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
- void * /* user_data */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetContextInfo(cl_context /* context */,
- cl_context_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Command Queue APIs */
-extern CL_API_ENTRY cl_command_queue CL_API_CALL
-clCreateCommandQueue(cl_context /* context */,
- cl_device_id /* device */,
- cl_command_queue_properties /* properties */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetCommandQueueInfo(cl_command_queue /* command_queue */,
- cl_command_queue_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetCommandQueueProperty(cl_command_queue /* command_queue */,
- cl_command_queue_properties /* properties */,
- cl_bool /* enable */,
- cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Memory Object APIs */
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateBuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- size_t /* size */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateImage2D(cl_context /* context */,
- cl_mem_flags /* flags */,
- const cl_image_format * /* image_format */,
- size_t /* image_width */,
- size_t /* image_height */,
- size_t /* image_row_pitch */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateImage3D(cl_context /* context */,
- cl_mem_flags /* flags */,
- const cl_image_format * /* image_format */,
- size_t /* image_width */,
- size_t /* image_height */,
- size_t /* image_depth */,
- size_t /* image_row_pitch */,
- size_t /* image_slice_pitch */,
- void * /* host_ptr */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetSupportedImageFormats(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_mem_object_type /* image_type */,
- cl_uint /* num_entries */,
- cl_image_format * /* image_formats */,
- cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetMemObjectInfo(cl_mem /* memobj */,
- cl_mem_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetImageInfo(cl_mem /* image */,
- cl_image_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Sampler APIs */
-extern CL_API_ENTRY cl_sampler CL_API_CALL
-clCreateSampler(cl_context /* context */,
- cl_bool /* normalized_coords */,
- cl_addressing_mode /* addressing_mode */,
- cl_filter_mode /* filter_mode */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetSamplerInfo(cl_sampler /* sampler */,
- cl_sampler_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Program Object APIs */
-extern CL_API_ENTRY cl_program CL_API_CALL
-clCreateProgramWithSource(cl_context /* context */,
- cl_uint /* count */,
- const char ** /* strings */,
- const size_t * /* lengths */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_program CL_API_CALL
-clCreateProgramWithBinary(cl_context /* context */,
- cl_uint /* num_devices */,
- const cl_device_id * /* device_list */,
- const size_t * /* lengths */,
- const unsigned char ** /* binaries */,
- cl_int * /* binary_status */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clBuildProgram(cl_program /* program */,
- cl_uint /* num_devices */,
- const cl_device_id * /* device_list */,
- const char * /* options */,
- void (*pfn_notify)(cl_program /* program */, void * /* user_data */),
- void * /* user_data */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetProgramInfo(cl_program /* program */,
- cl_program_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetProgramBuildInfo(cl_program /* program */,
- cl_device_id /* device */,
- cl_program_build_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Kernel Object APIs */
-extern CL_API_ENTRY cl_kernel CL_API_CALL
-clCreateKernel(cl_program /* program */,
- const char * /* kernel_name */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clCreateKernelsInProgram(cl_program /* program */,
- cl_uint /* num_kernels */,
- cl_kernel * /* kernels */,
- cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clSetKernelArg(cl_kernel /* kernel */,
- cl_uint /* arg_index */,
- size_t /* arg_size */,
- const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetKernelInfo(cl_kernel /* kernel */,
- cl_kernel_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetKernelWorkGroupInfo(cl_kernel /* kernel */,
- cl_device_id /* device */,
- cl_kernel_work_group_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Event Object APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clWaitForEvents(cl_uint /* num_events */,
- const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetEventInfo(cl_event /* event */,
- cl_event_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Profiling APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetEventProfilingInfo(cl_event /* event */,
- cl_profiling_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Flush and Finish APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clFlush(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clFinish(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Enqueued Commands APIs */
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReadBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_read */,
- size_t /* offset */,
- size_t /* cb */,
- void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWriteBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_write */,
- size_t /* offset */,
- size_t /* cb */,
- const void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyBuffer(cl_command_queue /* command_queue */,
- cl_mem /* src_buffer */,
- cl_mem /* dst_buffer */,
- size_t /* src_offset */,
- size_t /* dst_offset */,
- size_t /* cb */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReadImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_read */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t /* row_pitch */,
- size_t /* slice_pitch */,
- void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWriteImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_write */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t /* input_row_pitch */,
- size_t /* input_slice_pitch */,
- const void * /* ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyImage(cl_command_queue /* command_queue */,
- cl_mem /* src_image */,
- cl_mem /* dst_image */,
- const size_t * /* src_origin[3] */,
- const size_t * /* dst_origin[3] */,
- const size_t * /* region[3] */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyImageToBuffer(cl_command_queue /* command_queue */,
- cl_mem /* src_image */,
- cl_mem /* dst_buffer */,
- const size_t * /* src_origin[3] */,
- const size_t * /* region[3] */,
- size_t /* dst_offset */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueCopyBufferToImage(cl_command_queue /* command_queue */,
- cl_mem /* src_buffer */,
- cl_mem /* dst_image */,
- size_t /* src_offset */,
- const size_t * /* dst_origin[3] */,
- const size_t * /* region[3] */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY void * CL_API_CALL
-clEnqueueMapBuffer(cl_command_queue /* command_queue */,
- cl_mem /* buffer */,
- cl_bool /* blocking_map */,
- cl_map_flags /* map_flags */,
- size_t /* offset */,
- size_t /* cb */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY void * CL_API_CALL
-clEnqueueMapImage(cl_command_queue /* command_queue */,
- cl_mem /* image */,
- cl_bool /* blocking_map */,
- cl_map_flags /* map_flags */,
- const size_t * /* origin[3] */,
- const size_t * /* region[3] */,
- size_t * /* image_row_pitch */,
- size_t * /* image_slice_pitch */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueUnmapMemObject(cl_command_queue /* command_queue */,
- cl_mem /* memobj */,
- void * /* mapped_ptr */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueNDRangeKernel(cl_command_queue /* command_queue */,
- cl_kernel /* kernel */,
- cl_uint /* work_dim */,
- const size_t * /* global_work_offset */,
- const size_t * /* global_work_size */,
- const size_t * /* local_work_size */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueTask(cl_command_queue /* command_queue */,
- cl_kernel /* kernel */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueNativeKernel(cl_command_queue /* command_queue */,
- void (*user_func)(void *),
- void * /* args */,
- size_t /* cb_args */,
- cl_uint /* num_mem_objects */,
- const cl_mem * /* mem_list */,
- const void ** /* args_mem_loc */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueMarker(cl_command_queue /* command_queue */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueWaitForEvents(cl_command_queue /* command_queue */,
- cl_uint /* num_events */,
- const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
-
-/* Extension function access
- *
- * Returns the extension function address for the given function name,
- * or NULL if a valid function can not be found. The client must
- * check to make sure the address is not NULL, before using or
- * calling the returned function address.
- */
-extern CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_CL_H */
-
diff --git a/lib/gpu/geryon/opencl_1_0/CL/cl_ext.h b/lib/gpu/geryon/opencl_1_0/CL/cl_ext.h
deleted file mode 100644
index dbe8424db..000000000
--- a/lib/gpu/geryon/opencl_1_0/CL/cl_ext.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008-2009 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- ******************************************************************************/
-
-/* $Revision: 10424 $ on $Date: 2010-02-17 14:34:49 -0800 (Wed, 17 Feb 2010) $ */
-
-#ifndef __CL_EXT_H
-#define __CL_EXT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* cl_khr_fp64 extension - no extension #define since it has no functions */
-#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032
-
-
-/* cl_khr_fp16 extension - no extension #define since it has no functions */
-#define CL_DEVICE_HALF_FP_CONFIG 0x1033
-
-
-/* cl_khr_icd extension */
-#define cl_khr_icd 1
-
-/* cl_platform_info */
-#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
-
-/* Additional Error Codes */
-#define CL_PLATFORM_NOT_FOUND_KHR -1001
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clIcdGetPlatformIDsKHR(cl_uint /* num_entries */,
- cl_platform_id * /* platforms */,
- cl_uint * /* num_platforms */);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __CL_EXT_H */
diff --git a/lib/gpu/geryon/opencl_1_0/CL/cl_gl.h b/lib/gpu/geryon/opencl_1_0/CL/cl_gl.h
deleted file mode 100644
index f3a5c2cfc..000000000
--- a/lib/gpu/geryon/opencl_1_0/CL/cl_gl.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/**********************************************************************************
- * Copyright (c) 2008-2009 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- **********************************************************************************/
-
-/* $Revision: 10424 $ on $Date: 2010-02-17 14:34:49 -0800 (Wed, 17 Feb 2010) $ */
-
-/*
- * cl_gl.h contains Khronos-approved (KHR) OpenCL extensions which have
- * OpenGL dependencies. The application is responsible for #including
- * OpenGL or OpenGL ES headers before #including cl_gl.h.
- */
-
-#ifndef __OPENCL_CL_GL_H
-#define __OPENCL_CL_GL_H
-
-#ifdef __APPLE__
-#include <OpenCL/cl.h>
-#else
-#include <CL/cl.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef cl_uint cl_gl_object_type;
-typedef cl_uint cl_gl_texture_info;
-typedef cl_uint cl_gl_platform_info;
-
-/* cl_gl_object_type */
-#define CL_GL_OBJECT_BUFFER 0x2000
-#define CL_GL_OBJECT_TEXTURE2D 0x2001
-#define CL_GL_OBJECT_TEXTURE3D 0x2002
-#define CL_GL_OBJECT_RENDERBUFFER 0x2003
-
-/* cl_gl_texture_info */
-#define CL_GL_TEXTURE_TARGET 0x2004
-#define CL_GL_MIPMAP_LEVEL 0x2005
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLBuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLuint /* bufobj */,
- int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLTexture2D(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLenum /* target */,
- cl_GLint /* miplevel */,
- cl_GLuint /* texture */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLTexture3D(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLenum /* target */,
- cl_GLint /* miplevel */,
- cl_GLuint /* texture */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_mem CL_API_CALL
-clCreateFromGLRenderbuffer(cl_context /* context */,
- cl_mem_flags /* flags */,
- cl_GLuint /* renderbuffer */,
- cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLObjectInfo(cl_mem /* memobj */,
- cl_gl_object_type * /* gl_object_type */,
- cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLTextureInfo(cl_mem /* memobj */,
- cl_gl_texture_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */,
- cl_uint /* num_objects */,
- const cl_mem * /* mem_objects */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */,
- cl_uint /* num_objects */,
- const cl_mem * /* mem_objects */,
- cl_uint /* num_events_in_wait_list */,
- const cl_event * /* event_wait_list */,
- cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
-
-/* cl_khr_gl_sharing extension */
-
-#define cl_khr_gl_sharing 1
-
-typedef cl_uint cl_gl_context_info;
-
-/* Additional Error Codes */
-#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000
-
-/* cl_gl_context_info */
-#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006
-#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007
-
-/* Additional cl_context_properties */
-#define CL_GL_CONTEXT_KHR 0x2008
-#define CL_EGL_DISPLAY_KHR 0x2009
-#define CL_GLX_DISPLAY_KHR 0x200A
-#define CL_WGL_HDC_KHR 0x200B
-#define CL_CGL_SHAREGROUP_KHR 0x200C
-
-extern CL_API_ENTRY cl_int CL_API_CALL
-clGetGLContextInfoKHR(const cl_context_properties * /* properties */,
- cl_gl_context_info /* param_name */,
- size_t /* param_value_size */,
- void * /* param_value */,
- size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __OPENCL_CL_GL_H */
diff --git a/lib/gpu/geryon/opencl_1_0/CL/cl_platform.h b/lib/gpu/geryon/opencl_1_0/CL/cl_platform.h
deleted file mode 100644
index 6d65738b2..000000000
--- a/lib/gpu/geryon/opencl_1_0/CL/cl_platform.h
+++ /dev/null
@@ -1,1081 +0,0 @@
-/**********************************************************************************
- * Copyright (c) 2008-2009 The Khronos Group Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and/or associated documentation files (the
- * "Materials"), to deal in the Materials without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Materials, and to
- * permit persons to whom the Materials are furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
- **********************************************************************************/
-
-/* $Revision: 10424 $ on $Date: 2010-02-17 14:34:49 -0800 (Wed, 17 Feb 2010) $ */
-
-#ifndef __CL_PLATFORM_H
-#define __CL_PLATFORM_H
-
-#ifdef __APPLE__
- /* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */
- #include <AvailabilityMacros.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_WIN32)
-#define CL_API_ENTRY
-#define CL_API_CALL __stdcall
-#else
-#define CL_API_ENTRY
-#define CL_API_CALL
-#endif
-
-#ifdef __APPLE__
-#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
-#define CL_API_SUFFIX__VERSION_1_1
-#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import))
-#else
-#define CL_API_SUFFIX__VERSION_1_0
-#define CL_API_SUFFIX__VERSION_1_1
-#define CL_EXTENSION_WEAK_LINK
-#endif
-
-#if (defined (_WIN32) && defined(_MSC_VER))
-
-/* scalar types */
-typedef signed __int8 cl_char;
-typedef unsigned __int8 cl_uchar;
-typedef signed __int16 cl_short;
-typedef unsigned __int16 cl_ushort;
-typedef signed __int32 cl_int;
-typedef unsigned __int32 cl_uint;
-typedef signed __int64 cl_long;
-typedef unsigned __int64 cl_ulong;
-
-typedef unsigned __int16 cl_half;
-typedef float cl_float;
-typedef double cl_double;
-
-/* Macro names and corresponding values defined by OpenCL */
-#define CL_CHAR_BIT 8
-#define CL_SCHAR_MAX 127
-#define CL_SCHAR_MIN (-127-1)
-#define CL_CHAR_MAX CL_SCHAR_MAX
-#define CL_CHAR_MIN CL_SCHAR_MIN
-#define CL_UCHAR_MAX 255
-#define CL_SHRT_MAX 32767
-#define CL_SHRT_MIN (-32767-1)
-#define CL_USHRT_MAX 65535
-#define CL_INT_MAX 2147483647
-#define CL_INT_MIN (-2147483647-1)
-#define CL_UINT_MAX 0xffffffffU
-#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL)
-#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
-#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)
-
-#define CL_FLT_DIG 6
-#define CL_FLT_MANT_DIG 24
-#define CL_FLT_MAX_10_EXP +38
-#define CL_FLT_MAX_EXP +128
-#define CL_FLT_MIN_10_EXP -37
-#define CL_FLT_MIN_EXP -125
-#define CL_FLT_RADIX 2
-#define CL_FLT_MAX 340282346638528859811704183484516925440.0f
-#define CL_FLT_MIN 1.175494350822287507969e-38f
-#define CL_FLT_EPSILON 0x1.0p-23f
-
-#define CL_DBL_DIG 15
-#define CL_DBL_MANT_DIG 53
-#define CL_DBL_MAX_10_EXP +308
-#define CL_DBL_MAX_EXP +1024
-#define CL_DBL_MIN_10_EXP -307
-#define CL_DBL_MIN_EXP -1021
-#define CL_DBL_RADIX 2
-#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0
-#define CL_DBL_MIN 2.225073858507201383090e-308
-#define CL_DBL_EPSILON 2.220446049250313080847e-16
-
-#define CL_NAN (CL_INFINITY - CL_INFINITY)
-#define CL_HUGE_VALF ((cl_float) 1e50)
-#define CL_HUGE_VAL ((cl_double) 1e500)
-#define CL_MAXFLOAT CL_FLT_MAX
-#define CL_INFINITY CL_HUGE_VALF
-
-#else
-
-#include <stdint.h>
-
-/* scalar types */
-typedef int8_t cl_char;
-typedef uint8_t cl_uchar;
-typedef int16_t cl_short __attribute__((aligned(2)));
-typedef uint16_t cl_ushort __attribute__((aligned(2)));
-typedef int32_t cl_int __attribute__((aligned(4)));
-typedef uint32_t cl_uint __attribute__((aligned(4)));
-typedef int64_t cl_long __attribute__((aligned(8)));
-typedef uint64_t cl_ulong __attribute__((aligned(8)));
-
-typedef uint16_t cl_half __attribute__((aligned(2)));
-typedef float cl_float __attribute__((aligned(4)));
-typedef double cl_double __attribute__((aligned(8)));
-
-/* Macro names and corresponding values defined by OpenCL */
-#define CL_CHAR_BIT 8
-#define CL_SCHAR_MAX 127
-#define CL_SCHAR_MIN (-127-1)
-#define CL_CHAR_MAX CL_SCHAR_MAX
-#define CL_CHAR_MIN CL_SCHAR_MIN
-#define CL_UCHAR_MAX 255
-#define CL_SHRT_MAX 32767
-#define CL_SHRT_MIN (-32767-1)
-#define CL_USHRT_MAX 65535
-#define CL_INT_MAX 2147483647
-#define CL_INT_MIN (-2147483647-1)
-#define CL_UINT_MAX 0xffffffffU
-#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL)
-#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
-#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)
-
-#define CL_FLT_DIG 6
-#define CL_FLT_MANT_DIG 24
-#define CL_FLT_MAX_10_EXP +38
-#define CL_FLT_MAX_EXP +128
-#define CL_FLT_MIN_10_EXP -37
-#define CL_FLT_MIN_EXP -125
-#define CL_FLT_RADIX 2
-#define CL_FLT_MAX 0x1.fffffep127f
-#define CL_FLT_MIN 0x1.0p-126f
-#define CL_FLT_EPSILON 0x1.0p-23f
-
-#define CL_DBL_DIG 15
-#define CL_DBL_MANT_DIG 53
-#define CL_DBL_MAX_10_EXP +308
-#define CL_DBL_MAX_EXP +1024
-#define CL_DBL_MIN_10_EXP -307
-#define CL_DBL_MIN_EXP -1021
-#define CL_DBL_RADIX 2
-#define CL_DBL_MAX 0x1.fffffffffffffp1023
-#define CL_DBL_MIN 0x1.0p-1022
-#define CL_DBL_EPSILON 0x1.0p-52
-
-#if defined( __GNUC__ )
- #define CL_HUGE_VALF __builtin_huge_valf()
- #define CL_HUGE_VAL __builtin_huge_val()
- #define CL_NAN __builtin_nanf( "" )
-#else
- #define CL_HUGE_VALF ((cl_float) 1e50)
- #define CL_HUGE_VAL ((cl_double) 1e500)
- float nanf( const char * );
- #define CL_NAN nanf( "" )
-#endif
-#define CL_MAXFLOAT CL_FLT_MAX
-#define CL_INFINITY CL_HUGE_VALF
-
-#endif
-
-#include <stddef.h>
-
-/* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */
-typedef unsigned int cl_GLuint;
-typedef int cl_GLint;
-typedef unsigned int cl_GLenum;
-
-/*
- * Vector types
- *
- * Note: OpenCL requires that all types be naturally aligned.
- * This means that vector types must be naturally aligned.
- * For example, a vector of four floats must be aligned to
- * a 16 byte boundary (calculated as 4 * the natural 4-byte
- * alignment of the float). The alignment qualifiers here
- * will only function properly if your compiler supports them
- * and if you don't actively work to defeat them. For example,
- * in order for a cl_float4 to be 16 byte aligned in a struct,
- * the start of the struct must itself be 16-byte aligned.
- *
- * Maintaining proper alignment is the user's responsibility.
- */
-
-/* Define basic vector types */
-#if defined( __VEC__ )
- #include <altivec.h> /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */
- typedef vector unsigned char __cl_uchar16;
- typedef vector signed char __cl_char16;
- typedef vector unsigned short __cl_ushort8;
- typedef vector signed short __cl_short8;
- typedef vector unsigned int __cl_uint4;
- typedef vector signed int __cl_int4;
- typedef vector float __cl_float4;
- #define __CL_UCHAR16__ 1
- #define __CL_CHAR16__ 1
- #define __CL_USHORT8__ 1
- #define __CL_SHORT8__ 1
- #define __CL_UINT4__ 1
- #define __CL_INT4__ 1
- #define __CL_FLOAT4__ 1
-#endif
-
-#if defined( __SSE__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <xmmintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef float __cl_float4 __attribute__((vector_size(16)));
- #else
- typedef __m128 __cl_float4;
- #endif
- #define __CL_FLOAT4__ 1
-#endif
-
-#if defined( __SSE2__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <emmintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16)));
- typedef cl_char __cl_char16 __attribute__((vector_size(16)));
- typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16)));
- typedef cl_short __cl_short8 __attribute__((vector_size(16)));
- typedef cl_uint __cl_uint4 __attribute__((vector_size(16)));
- typedef cl_int __cl_int4 __attribute__((vector_size(16)));
- typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16)));
- typedef cl_long __cl_long2 __attribute__((vector_size(16)));
- typedef cl_double __cl_double2 __attribute__((vector_size(16)));
- #else
- typedef __m128i __cl_uchar16;
- typedef __m128i __cl_char16;
- typedef __m128i __cl_ushort8;
- typedef __m128i __cl_short8;
- typedef __m128i __cl_uint4;
- typedef __m128i __cl_int4;
- typedef __m128i __cl_ulong2;
- typedef __m128i __cl_long2;
- typedef __m128d __cl_double2;
- #endif
- #define __CL_UCHAR16__ 1
- #define __CL_CHAR16__ 1
- #define __CL_USHORT8__ 1
- #define __CL_SHORT8__ 1
- #define __CL_INT4__ 1
- #define __CL_UINT4__ 1
- #define __CL_ULONG2__ 1
- #define __CL_LONG2__ 1
- #define __CL_DOUBLE2__ 1
-#endif
-
-#if defined( __MMX__ )
- #include <mmintrin.h>
- #if defined( __GNUC__ )
- typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8)));
- typedef cl_char __cl_char8 __attribute__((vector_size(8)));
- typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8)));
- typedef cl_short __cl_short4 __attribute__((vector_size(8)));
- typedef cl_uint __cl_uint2 __attribute__((vector_size(8)));
- typedef cl_int __cl_int2 __attribute__((vector_size(8)));
- typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8)));
- typedef cl_long __cl_long1 __attribute__((vector_size(8)));
- typedef cl_float __cl_float2 __attribute__((vector_size(8)));
- #else
- typedef __m64 __cl_uchar8;
- typedef __m64 __cl_char8;
- typedef __m64 __cl_ushort4;
- typedef __m64 __cl_short4;
- typedef __m64 __cl_uint2;
- typedef __m64 __cl_int2;
- typedef __m64 __cl_ulong1;
- typedef __m64 __cl_long1;
- typedef __m64 __cl_float2;
- #endif
- #define __CL_UCHAR8__ 1
- #define __CL_CHAR8__ 1
- #define __CL_USHORT4__ 1
- #define __CL_SHORT4__ 1
- #define __CL_INT2__ 1
- #define __CL_UINT2__ 1
- #define __CL_ULONG1__ 1
- #define __CL_LONG1__ 1
- #define __CL_FLOAT2__ 1
-#endif
-
-#if defined( __AVX__ )
- #if defined( __MINGW64__ )
- #include <intrin.h>
- #else
- #include <immintrin.h>
- #endif
- #if defined( __GNUC__ )
- typedef cl_float __cl_float8 __attribute__((vector_size(32)));
- typedef cl_double __cl_double4 __attribute__((vector_size(32)));
- #else
- typedef __m256 __cl_float8;
- typedef __m256d __cl_double4;
- #endif
- #define __CL_FLOAT8__ 1
- #define __CL_DOUBLE4__ 1
-#endif
-
-/* Define alignment keys */
-#if defined( __GNUC__ )
- #define CL_ALIGNED(_x) __attribute__ ((aligned(_x)))
-#elif defined( _WIN32) && (_MSC_VER)
- /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */
- /* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */
- /* #include <crtdefs.h> */
- /* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */
- #define CL_ALIGNED(_x)
-#else
- #warning Need to implement some method to align data here
- #define CL_ALIGNED(_x)
-#endif
-
-/* Indicate whether .xyzw, .s0123 and .hi.lo are supported */
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- /* .xyzw and .s0123...{f|F} are supported */
- #define CL_HAS_NAMED_VECTOR_FIELDS 1
- /* .hi and .lo are supported */
- #define CL_HAS_HI_LO_VECTOR_FIELDS 1
-#endif
-
-/* Define cl_vector types */
-
-/* ---- cl_charn ---- */
-typedef union
-{
- cl_char CL_ALIGNED(2) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y; };
- __extension__ struct{ cl_char s0, s1; };
- __extension__ struct{ cl_char lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2;
-#endif
-}cl_char2;
-
-typedef union
-{
- cl_char CL_ALIGNED(4) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w; };
- __extension__ struct{ cl_char s0, s1, s2, s3; };
- __extension__ struct{ cl_char2 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[2];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4;
-#endif
-}cl_char4;
-
-typedef union
-{
- cl_char CL_ALIGNED(8) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w; };
- __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_char4 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[4];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4[2];
-#endif
-#if defined( __CL_CHAR8__ )
- __cl_char8 v8;
-#endif
-}cl_char8;
-
-typedef union
-{
- cl_char CL_ALIGNED(16) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_char8 lo, hi; };
-#endif
-#if defined( __CL_CHAR2__)
- __cl_char2 v2[8];
-#endif
-#if defined( __CL_CHAR4__)
- __cl_char4 v4[4];
-#endif
-#if defined( __CL_CHAR8__ )
- __cl_char8 v8[2];
-#endif
-#if defined( __CL_CHAR16__ )
- __cl_char16 v16;
-#endif
-}cl_char16;
-
-
-/* ---- cl_ucharn ---- */
-typedef union
-{
- cl_uchar CL_ALIGNED(2) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y; };
- __extension__ struct{ cl_uchar s0, s1; };
- __extension__ struct{ cl_uchar lo, hi; };
-#endif
-#if defined( __cl_uchar2__)
- __cl_uchar2 v2;
-#endif
-}cl_uchar2;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(4) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3; };
- __extension__ struct{ cl_uchar2 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[2];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4;
-#endif
-}cl_uchar4;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(8) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_uchar4 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[4];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4[2];
-#endif
-#if defined( __CL_UCHAR8__ )
- __cl_uchar8 v8;
-#endif
-}cl_uchar8;
-
-typedef union
-{
- cl_uchar CL_ALIGNED(16) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_uchar8 lo, hi; };
-#endif
-#if defined( __CL_UCHAR2__)
- __cl_uchar2 v2[8];
-#endif
-#if defined( __CL_UCHAR4__)
- __cl_uchar4 v4[4];
-#endif
-#if defined( __CL_UCHAR8__ )
- __cl_uchar8 v8[2];
-#endif
-#if defined( __CL_UCHAR16__ )
- __cl_uchar16 v16;
-#endif
-}cl_uchar16;
-
-
-/* ---- cl_shortn ---- */
-typedef union
-{
- cl_short CL_ALIGNED(4) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y; };
- __extension__ struct{ cl_short s0, s1; };
- __extension__ struct{ cl_short lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2;
-#endif
-}cl_short2;
-
-typedef union
-{
- cl_short CL_ALIGNED(8) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w; };
- __extension__ struct{ cl_short s0, s1, s2, s3; };
- __extension__ struct{ cl_short2 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[2];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4;
-#endif
-}cl_short4;
-
-typedef union
-{
- cl_short CL_ALIGNED(16) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w; };
- __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_short4 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[4];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4[2];
-#endif
-#if defined( __CL_SHORT8__ )
- __cl_short8 v8;
-#endif
-}cl_short8;
-
-typedef union
-{
- cl_short CL_ALIGNED(32) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_short8 lo, hi; };
-#endif
-#if defined( __CL_SHORT2__)
- __cl_short2 v2[8];
-#endif
-#if defined( __CL_SHORT4__)
- __cl_short4 v4[4];
-#endif
-#if defined( __CL_SHORT8__ )
- __cl_short8 v8[2];
-#endif
-#if defined( __CL_SHORT16__ )
- __cl_short16 v16;
-#endif
-}cl_short16;
-
-
-/* ---- cl_ushortn ---- */
-typedef union
-{
- cl_ushort CL_ALIGNED(4) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y; };
- __extension__ struct{ cl_ushort s0, s1; };
- __extension__ struct{ cl_ushort lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2;
-#endif
-}cl_ushort2;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(8) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3; };
- __extension__ struct{ cl_ushort2 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[2];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4;
-#endif
-}cl_ushort4;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(16) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_ushort4 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[4];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4[2];
-#endif
-#if defined( __CL_USHORT8__ )
- __cl_ushort8 v8;
-#endif
-}cl_ushort8;
-
-typedef union
-{
- cl_ushort CL_ALIGNED(32) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_ushort8 lo, hi; };
-#endif
-#if defined( __CL_USHORT2__)
- __cl_ushort2 v2[8];
-#endif
-#if defined( __CL_USHORT4__)
- __cl_ushort4 v4[4];
-#endif
-#if defined( __CL_USHORT8__ )
- __cl_ushort8 v8[2];
-#endif
-#if defined( __CL_USHORT16__ )
- __cl_ushort16 v16;
-#endif
-}cl_ushort16;
-
-/* ---- cl_intn ---- */
-typedef union
-{
- cl_int CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y; };
- __extension__ struct{ cl_int s0, s1; };
- __extension__ struct{ cl_int lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2;
-#endif
-}cl_int2;
-
-typedef union
-{
- cl_int CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w; };
- __extension__ struct{ cl_int s0, s1, s2, s3; };
- __extension__ struct{ cl_int2 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[2];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4;
-#endif
-}cl_int4;
-
-typedef union
-{
- cl_int CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w; };
- __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_int4 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[4];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4[2];
-#endif
-#if defined( __CL_INT8__ )
- __cl_int8 v8;
-#endif
-}cl_int8;
-
-typedef union
-{
- cl_int CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_int8 lo, hi; };
-#endif
-#if defined( __CL_INT2__)
- __cl_int2 v2[8];
-#endif
-#if defined( __CL_INT4__)
- __cl_int4 v4[4];
-#endif
-#if defined( __CL_INT8__ )
- __cl_int8 v8[2];
-#endif
-#if defined( __CL_INT16__ )
- __cl_int16 v16;
-#endif
-}cl_int16;
-
-
-/* ---- cl_uintn ---- */
-typedef union
-{
- cl_uint CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y; };
- __extension__ struct{ cl_uint s0, s1; };
- __extension__ struct{ cl_uint lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2;
-#endif
-}cl_uint2;
-
-typedef union
-{
- cl_uint CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w; };
- __extension__ struct{ cl_uint s0, s1, s2, s3; };
- __extension__ struct{ cl_uint2 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[2];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4;
-#endif
-}cl_uint4;
-
-typedef union
-{
- cl_uint CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w; };
- __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_uint4 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[4];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4[2];
-#endif
-#if defined( __CL_UINT8__ )
- __cl_uint8 v8;
-#endif
-}cl_uint8;
-
-typedef union
-{
- cl_uint CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_uint8 lo, hi; };
-#endif
-#if defined( __CL_UINT2__)
- __cl_uint2 v2[8];
-#endif
-#if defined( __CL_UINT4__)
- __cl_uint4 v4[4];
-#endif
-#if defined( __CL_UINT8__ )
- __cl_uint8 v8[2];
-#endif
-#if defined( __CL_UINT16__ )
- __cl_uint16 v16;
-#endif
-}cl_uint16;
-
-/* ---- cl_longn ---- */
-typedef union
-{
- cl_long CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y; };
- __extension__ struct{ cl_long s0, s1; };
- __extension__ struct{ cl_long lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2;
-#endif
-}cl_long2;
-
-typedef union
-{
- cl_long CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w; };
- __extension__ struct{ cl_long s0, s1, s2, s3; };
- __extension__ struct{ cl_long2 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[2];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4;
-#endif
-}cl_long4;
-
-typedef union
-{
- cl_long CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w; };
- __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_long4 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[4];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4[2];
-#endif
-#if defined( __CL_LONG8__ )
- __cl_long8 v8;
-#endif
-}cl_long8;
-
-typedef union
-{
- cl_long CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_long8 lo, hi; };
-#endif
-#if defined( __CL_LONG2__)
- __cl_long2 v2[8];
-#endif
-#if defined( __CL_LONG4__)
- __cl_long4 v4[4];
-#endif
-#if defined( __CL_LONG8__ )
- __cl_long8 v8[2];
-#endif
-#if defined( __CL_LONG16__ )
- __cl_long16 v16;
-#endif
-}cl_long16;
-
-
-/* ---- cl_ulongn ---- */
-typedef union
-{
- cl_ulong CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y; };
- __extension__ struct{ cl_ulong s0, s1; };
- __extension__ struct{ cl_ulong lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2;
-#endif
-}cl_ulong2;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3; };
- __extension__ struct{ cl_ulong2 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[2];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4;
-#endif
-}cl_ulong4;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_ulong4 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[4];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4[2];
-#endif
-#if defined( __CL_ULONG8__ )
- __cl_ulong8 v8;
-#endif
-}cl_ulong8;
-
-typedef union
-{
- cl_ulong CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_ulong8 lo, hi; };
-#endif
-#if defined( __CL_ULONG2__)
- __cl_ulong2 v2[8];
-#endif
-#if defined( __CL_ULONG4__)
- __cl_ulong4 v4[4];
-#endif
-#if defined( __CL_ULONG8__ )
- __cl_ulong8 v8[2];
-#endif
-#if defined( __CL_ULONG16__ )
- __cl_ulong16 v16;
-#endif
-}cl_ulong16;
-
-
-/* --- cl_floatn ---- */
-
-typedef union
-{
- cl_float CL_ALIGNED(8) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y; };
- __extension__ struct{ cl_float s0, s1; };
- __extension__ struct{ cl_float lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2;
-#endif
-}cl_float2;
-
-typedef union
-{
- cl_float CL_ALIGNED(16) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w; };
- __extension__ struct{ cl_float s0, s1, s2, s3; };
- __extension__ struct{ cl_float2 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[2];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4;
-#endif
-}cl_float4;
-
-typedef union
-{
- cl_float CL_ALIGNED(32) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w; };
- __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_float4 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[4];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4[2];
-#endif
-#if defined( __CL_FLOAT8__ )
- __cl_float8 v8;
-#endif
-}cl_float8;
-
-typedef union
-{
- cl_float CL_ALIGNED(64) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_float8 lo, hi; };
-#endif
-#if defined( __CL_FLOAT2__)
- __cl_float2 v2[8];
-#endif
-#if defined( __CL_FLOAT4__)
- __cl_float4 v4[4];
-#endif
-#if defined( __CL_FLOAT8__ )
- __cl_float8 v8[2];
-#endif
-#if defined( __CL_FLOAT16__ )
- __cl_float16 v16;
-#endif
-}cl_float16;
-
-/* --- cl_doublen ---- */
-
-typedef union
-{
- cl_double CL_ALIGNED(16) s[2];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y; };
- __extension__ struct{ cl_double s0, s1; };
- __extension__ struct{ cl_double lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2;
-#endif
-}cl_double2;
-
-typedef union
-{
- cl_double CL_ALIGNED(32) s[4];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w; };
- __extension__ struct{ cl_double s0, s1, s2, s3; };
- __extension__ struct{ cl_double2 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[2];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4;
-#endif
-}cl_double4;
-
-typedef union
-{
- cl_double CL_ALIGNED(64) s[8];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w; };
- __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; };
- __extension__ struct{ cl_double4 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[4];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4[2];
-#endif
-#if defined( __CL_DOUBLE8__ )
- __cl_double8 v8;
-#endif
-}cl_double8;
-
-typedef union
-{
- cl_double CL_ALIGNED(128) s[16];
-#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ )
- __extension__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; };
- __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; };
- __extension__ struct{ cl_double8 lo, hi; };
-#endif
-#if defined( __CL_DOUBLE2__)
- __cl_double2 v2[8];
-#endif
-#if defined( __CL_DOUBLE4__)
- __cl_double4 v4[4];
-#endif
-#if defined( __CL_DOUBLE8__ )
- __cl_double8 v8[2];
-#endif
-#if defined( __CL_DOUBLE16__ )
- __cl_double16 v16;
-#endif
-}cl_double16;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CL_PLATFORM_H */
diff --git a/lib/gpu/geryon/opencl_1_0/CL/clext.h b/lib/gpu/geryon/opencl_1_0/CL/clext.h
deleted file mode 100644
index 868ccb727..000000000
--- a/lib/gpu/geryon/opencl_1_0/CL/clext.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-** Copyright 1998-2002, NVIDIA Corporation.
-** All Rights Reserved.
-**
-** THE INFORMATION CONTAINED HEREIN IS PROPRIETARY AND CONFIDENTIAL TO
-** NVIDIA, CORPORATION. USE, REPRODUCTION OR DISCLOSURE TO ANY THIRD PARTY
-** IS SUBJECT TO WRITTEN PRE-APPROVAL BY NVIDIA, CORPORATION.
-**
-**
-*/
-#ifndef __CLEXT_H
-#define __CLEXT_H
-
-#define CL_NV_DEVICE_COMPUTE_CAPABILITY_MAJOR 0x4000
-#define CL_NV_DEVICE_COMPUTE_CAPABILITY_MINOR 0x4001
-#define CL_NV_DEVICE_REGISTERS_PER_BLOCK 0x4002
-#define CL_NV_DEVICE_WARP_SIZE 0x4003
-#define CL_NV_DEVICE_GPU_OVERLAP 0x4004
-#define CL_NV_DEVICE_KERNEL_EXEC_TIMEOUT 0x4005
-#define CL_NV_DEVICE_INTEGRATED_MEMORY 0x4006
-
-#endif
diff --git a/lib/gpu/lal_cg_cmm.cpp b/lib/gpu/lal_cg_cmm.cpp
index 0742bc823..7b798cc44 100644
--- a/lib/gpu/lal_cg_cmm.cpp
+++ b/lib/gpu/lal_cg_cmm.cpp
@@ -1,154 +1,154 @@
/***************************************************************************
cg_cmm.cpp
-------------------
W. Michael Brown (ORNL)
- Class for acceleration of the cg/cmm/cut pair style
+ Class for acceleration of the lj/sdk/cut pair style
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#ifdef USE_OPENCL
#include "cg_cmm_cl.h"
#else
#include "cg_cmm_ptx.h"
#endif
#include "lal_cg_cmm.h"
#include <cassert>
using namespace LAMMPS_AL;
#define CGCMMT CGCMM<numtyp, acctyp>
extern Device<PRECISION,ACC_PRECISION> device;
template <class numtyp, class acctyp>
CGCMMT::CGCMM() : BaseAtomic<numtyp,acctyp>(), _allocated(false) {
}
template <class numtyp, class acctyp>
CGCMMT::~CGCMM() {
clear();
}
template <class numtyp, class acctyp>
int CGCMMT::bytes_per_atom(const int max_nbors) const {
return this->bytes_per_atom_atomic(max_nbors);
}
template <class numtyp, class acctyp>
int CGCMMT::init(const int ntypes, double **host_cutsq,
int **host_cg_type, double **host_lj1,
double **host_lj2, double **host_lj3,
double **host_lj4, double **host_offset,
double *host_special_lj, const int nlocal,
const int nall, const int max_nbors,
const int maxspecial, const double cell_size,
const double gpu_split, FILE *_screen) {
int success;
success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split,
_screen,cg_cmm);
if (success!=0)
return success;
// If atom type constants fit in shared memory use fast kernel
int cmm_types=ntypes;
shared_types=false;
int max_shared_types=this->device->max_shared_types();
if (cmm_types<=max_shared_types && this->_block_size>=max_shared_types) {
cmm_types=max_shared_types;
shared_types=true;
}
_cmm_types=cmm_types;
// Allocate a host write buffer for data initialization
UCL_H_Vec<numtyp> host_write(cmm_types*cmm_types*32,*(this->ucl_device),
UCL_WRITE_OPTIMIZED);
for (int i=0; i<cmm_types*cmm_types; i++)
host_write[i]=0.0;
lj1.alloc(cmm_types*cmm_types,*(this->ucl_device),UCL_READ_ONLY);
this->atom->type_pack4(ntypes,cmm_types,lj1,host_write,host_cutsq,
host_cg_type,host_lj1,host_lj2);
lj3.alloc(cmm_types*cmm_types,*(this->ucl_device),UCL_READ_ONLY);
this->atom->type_pack4(ntypes,cmm_types,lj3,host_write,host_lj3,host_lj4,
host_offset);
UCL_H_Vec<double> dview;
sp_lj.alloc(4,*(this->ucl_device),UCL_READ_ONLY);
dview.view(host_special_lj,4,*(this->ucl_device));
ucl_copy(sp_lj,dview,false);
_allocated=true;
this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+sp_lj.row_bytes();
return 0;
}
template <class numtyp, class acctyp>
void CGCMMT::clear() {
if (!_allocated)
return;
_allocated=false;
lj1.clear();
lj3.clear();
sp_lj.clear();
this->clear_atomic();
}
template <class numtyp, class acctyp>
double CGCMMT::host_memory_usage() const {
return this->host_memory_usage_atomic()+sizeof(CGCMM<numtyp,acctyp>);
}
// ---------------------------------------------------------------------------
// Calculate energies, forces, and torques
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void CGCMMT::loop(const bool _eflag, const bool _vflag) {
// Compute the block size and grid size to keep all cores busy
const int BX=this->block_size();
int eflag, vflag;
if (_eflag)
eflag=1;
else
eflag=0;
if (_vflag)
vflag=1;
else
vflag=0;
int GX=static_cast<int>(ceil(static_cast<double>(this->ans->inum())/
(BX/this->_threads_per_atom)));
int ainum=this->ans->inum();
int nbor_pitch=this->nbor->nbor_pitch();
this->time_pair.start();
if (shared_types) {
this->k_pair_fast.set_size(GX,BX);
this->k_pair_fast.run(&this->atom->dev_x.begin(), &lj1.begin(),
&lj3.begin(), &sp_lj.begin(),
&this->nbor->dev_nbor.begin(),
&this->_nbor_data->begin(),
&this->ans->dev_ans.begin(),
&this->ans->dev_engv.begin(), &eflag, &vflag,
&ainum, &nbor_pitch, &this->_threads_per_atom);
} else {
this->k_pair.set_size(GX,BX);
this->k_pair.run(&this->atom->dev_x.begin(), &lj1.begin(), &lj3.begin(),
&_cmm_types, &sp_lj.begin(), &this->nbor->dev_nbor.begin(),
&this->_nbor_data->begin(), &this->ans->dev_ans.begin(),
&this->ans->dev_engv.begin(), &eflag, &vflag, &ainum,
&nbor_pitch, &this->_threads_per_atom);
}
this->time_pair.stop();
}
template class CGCMM<PRECISION,ACC_PRECISION>;
diff --git a/lib/gpu/lal_cg_cmm.cu b/lib/gpu/lal_cg_cmm.cu
index 90c7376be..b3813b2f6 100644
--- a/lib/gpu/lal_cg_cmm.cu
+++ b/lib/gpu/lal_cg_cmm.cu
@@ -1,205 +1,209 @@
// **************************************************************************
// cg_cmm.cu
// -------------------
// W. Michael Brown (ORNL)
//
+<<<<<<< HEAD
// Device code for acceleration of the cg/cmm/cut pair style
+=======
+// Device code for acceleration of the lj/sdk pair style
+>>>>>>> ad9fa0e18743a47e42452e38329083e37cb90055
//
// __________________________________________________________________________
// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
// __________________________________________________________________________
//
// begin :
// email : brownw@ornl.gov
// ***************************************************************************/
#ifdef NV_KERNEL
#include "lal_aux_fun1.h"
texture<float4> pos_tex;
#ifndef _DOUBLE_DOUBLE
ucl_inline float4 fetch_pos(const int& i, const float4 *pos)
{ return tex1Dfetch(pos_tex, i); }
#endif
#endif
__kernel void kernel_pair(__global numtyp4 *x_, __global numtyp4 *lj1,
__global numtyp4* lj3, const int lj_types,
__global numtyp *sp_lj_in, __global int *dev_nbor,
__global int *dev_packed, __global acctyp4 *ans,
__global acctyp *engv, const int eflag,
const int vflag, const int inum,
const int nbor_pitch, const int t_per_atom) {
int tid, ii, offset;
atom_info(t_per_atom,ii,tid,offset);
__local numtyp sp_lj[4];
sp_lj[0]=sp_lj_in[0];
sp_lj[1]=sp_lj_in[1];
sp_lj[2]=sp_lj_in[2];
sp_lj[3]=sp_lj_in[3];
acctyp energy=(acctyp)0;
acctyp4 f;
f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
acctyp virial[6];
for (int i=0; i<6; i++)
virial[i]=(acctyp)0;
if (ii<inum) {
__global int *nbor, *list_end;
int i, numj, n_stride;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,list_end,nbor);
numtyp4 ix=fetch_pos(i,x_); //x_[i];
int itype=ix.w;
numtyp factor_lj;
for ( ; nbor<list_end; nbor+=n_stride) {
int j=*nbor;
factor_lj = sp_lj[sbmask(j)];
j &= NEIGHMASK;
numtyp4 jx=fetch_pos(j,x_); //x_[j];
int jtype=jx.w;
// Compute r12
numtyp delx = ix.x-jx.x;
numtyp dely = ix.y-jx.y;
numtyp delz = ix.z-jx.z;
numtyp r2inv = delx*delx+dely*dely+delz*delz;
int mtype=itype*lj_types+jtype;
if (r2inv<lj1[mtype].x) {
r2inv=ucl_recip(r2inv);
numtyp inv1,inv2;
if (lj1[mtype].y == 2) {
inv1=r2inv*r2inv;
inv2=inv1*inv1;
} else if (lj1[mtype].y == 1) {
inv2=r2inv*ucl_sqrt(r2inv);
inv1=inv2*inv2;
} else {
inv1=r2inv*r2inv*r2inv;
inv2=inv1;
}
numtyp force = factor_lj*r2inv*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
f.x+=delx*force;
f.y+=dely*force;
f.z+=delz*force;
if (eflag>0)
energy += factor_lj*inv1*(lj3[mtype].x*inv2-lj3[mtype].y)-
lj3[mtype].z;
if (vflag>0) {
virial[0] += delx*delx*force;
virial[1] += dely*dely*force;
virial[2] += delz*delz*force;
virial[3] += delx*dely*force;
virial[4] += delx*delz*force;
virial[5] += dely*delz*force;
}
}
} // for nbor
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag,
ans,engv);
} // if ii
}
__kernel void kernel_pair_fast(__global numtyp4 *x_, __global numtyp4 *lj1_in,
__global numtyp4* lj3_in,
__global numtyp* sp_lj_in,__global int *dev_nbor,
__global int *dev_packed, __global acctyp4 *ans,
__global acctyp *engv, const int eflag,
const int vflag, const int inum,
const int nbor_pitch, const int t_per_atom) {
int tid, ii, offset;
atom_info(t_per_atom,ii,tid,offset);
__local numtyp4 lj1[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
__local numtyp4 lj3[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
__local numtyp sp_lj[4];
if (tid<4)
sp_lj[tid]=sp_lj_in[tid];
if (tid<MAX_SHARED_TYPES*MAX_SHARED_TYPES) {
lj1[tid]=lj1_in[tid];
if (eflag>0)
lj3[tid]=lj3_in[tid];
}
acctyp energy=(acctyp)0;
acctyp4 f;
f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
acctyp virial[6];
for (int i=0; i<6; i++)
virial[i]=(acctyp)0;
__syncthreads();
if (ii<inum) {
__global int *nbor, *list_end;
int i, numj, n_stride;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,list_end,nbor);
numtyp4 ix=fetch_pos(i,x_); //x_[i];
int iw=ix.w;
int itype=fast_mul((int)MAX_SHARED_TYPES,iw);
numtyp factor_lj;
for ( ; nbor<list_end; nbor+=n_stride) {
int j=*nbor;
factor_lj = sp_lj[sbmask(j)];
j &= NEIGHMASK;
numtyp4 jx=fetch_pos(j,x_); //x_[j];
int mtype=itype+jx.w;
// Compute r12
numtyp delx = ix.x-jx.x;
numtyp dely = ix.y-jx.y;
numtyp delz = ix.z-jx.z;
numtyp r2inv = delx*delx+dely*dely+delz*delz;
if (r2inv<lj1[mtype].x) {
r2inv=ucl_recip(r2inv);
numtyp inv1,inv2;
if (lj1[mtype].y == (numtyp)2) {
inv1=r2inv*r2inv;
inv2=inv1*inv1;
} else if (lj1[mtype].y == (numtyp)1) {
inv2=r2inv*ucl_sqrt(r2inv);
inv1=inv2*inv2;
} else {
inv1=r2inv*r2inv*r2inv;
inv2=inv1;
}
numtyp force = factor_lj*r2inv*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
f.x+=delx*force;
f.y+=dely*force;
f.z+=delz*force;
if (eflag>0)
energy += factor_lj*inv1*(lj3[mtype].x*inv2-lj3[mtype].y)-
lj3[mtype].z;
if (vflag>0) {
virial[0] += delx*delx*force;
virial[1] += dely*dely*force;
virial[2] += delz*delz*force;
virial[3] += delx*dely*force;
virial[4] += delx*delz*force;
virial[5] += dely*delz*force;
}
}
} // for nbor
store_answers(f,energy,virial,ii,inum,tid,t_per_atom,offset,eflag,vflag,
ans,engv);
} // if ii
}
diff --git a/lib/gpu/lal_cg_cmm.h b/lib/gpu/lal_cg_cmm.h
index c7d50b0b0..394cd8125 100644
--- a/lib/gpu/lal_cg_cmm.h
+++ b/lib/gpu/lal_cg_cmm.h
@@ -1,79 +1,79 @@
/***************************************************************************
cg_cmm.h
-------------------
W. Michael Brown (ORNL)
- Class for acceleration of the cg/cmm/cut pair style
+ Class for acceleration of the lj/sdk pair style
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#ifndef LAL_CG_CMM_H
#define LAL_CG_CMM_H
#include "lal_base_atomic.h"
namespace LAMMPS_AL {
template <class numtyp, class acctyp>
class CGCMM : public BaseAtomic<numtyp, acctyp> {
public:
CGCMM();
~CGCMM();
/// Clear any previous data and set up for a new LAMMPS run
/** \param max_nbors initial number of rows in the neighbor matrix
* \param cell_size cutoff + skin
* \param gpu_split fraction of particles handled by device
*
* Returns:
* - 0 if successfull
* - -1 if fix gpu not found
* - -3 if there is an out of memory error
* - -4 if the GPU library was not compiled for GPU
* - -5 Double precision is not supported on card **/
int init(const int ntypes, double **host_cutsq, int **host_cg_type,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **host_offset, double *host_special_lj,
const int nlocal, const int nall, const int max_nbors,
const int maxspecial, const double cell_size,
const double gpu_split, FILE *screen);
/// Clear all host and device data
/** \note This is called at the beginning of the init() routine **/
void clear();
/// Returns memory usage on device per atom
int bytes_per_atom(const int max_nbors) const;
/// Total host memory used by library for pair style
double host_memory_usage() const;
// --------------------------- TYPE DATA --------------------------
/// lj1.x = cutsq, lj1.y=cg_type, lj1.z = lj1, lj1.w = lj2
UCL_D_Vec<numtyp4> lj1;
/// lj3.x = lj3, lj3.y = lj4, lj3.z = offset
UCL_D_Vec<numtyp4> lj3;
/// Special LJ values
UCL_D_Vec<numtyp> sp_lj;
/// If atom type constants fit in shared memory, use fast kernels
bool shared_types;
/// Number of atom types
int _cmm_types;
private:
bool _allocated;
void loop(const bool _eflag, const bool _vflag);
};
}
#endif
diff --git a/lib/gpu/lal_cg_cmm_ext.cpp b/lib/gpu/lal_cg_cmm_ext.cpp
index c9fafb789..6d64c3043 100644
--- a/lib/gpu/lal_cg_cmm_ext.cpp
+++ b/lib/gpu/lal_cg_cmm_ext.cpp
@@ -1,121 +1,121 @@
/***************************************************************************
cg_cmm.h
-------------------
W. Michael Brown (ORNL)
- Functions for LAMMPS access to cg/cmm/cut pair acceleration routines
+ Functions for LAMMPS access to lj/sdk pair acceleration routines
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#include <iostream>
#include <cassert>
#include <math.h>
#include "lal_cg_cmm.h"
using namespace std;
using namespace LAMMPS_AL;
static CGCMM<PRECISION,ACC_PRECISION> CMMMF;
// ---------------------------------------------------------------------------
// Allocate memory on host and device and copy constants to device
// ---------------------------------------------------------------------------
int cmm_gpu_init(const int ntypes, double **cutsq, int **cg_types,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **offset, double *special_lj,
const int inum, const int nall, const int max_nbors,
const int maxspecial, const double cell_size, int &gpu_mode,
FILE *screen) {
CMMMF.clear();
gpu_mode=CMMMF.device->gpu_mode();
double gpu_split=CMMMF.device->particle_split();
int first_gpu=CMMMF.device->first_device();
int last_gpu=CMMMF.device->last_device();
int world_me=CMMMF.device->world_me();
int gpu_rank=CMMMF.device->gpu_rank();
int procs_per_gpu=CMMMF.device->procs_per_gpu();
- CMMMF.device->init_message(screen,"cg/cmm",first_gpu,last_gpu);
+ CMMMF.device->init_message(screen,"lj/sdk",first_gpu,last_gpu);
bool message=false;
if (CMMMF.device->replica_me()==0 && screen)
message=true;
if (message) {
fprintf(screen,"Initializing GPU and compiling on process 0...");
fflush(screen);
}
int init_ok=0;
if (world_me==0)
init_ok=CMMMF.init(ntypes,cutsq,cg_types,host_lj1,host_lj2,host_lj3,
host_lj4, offset, special_lj, inum, nall, 300,
maxspecial, cell_size, gpu_split, screen);
CMMMF.device->world_barrier();
if (message)
fprintf(screen,"Done.\n");
for (int i=0; i<procs_per_gpu; i++) {
if (message) {
if (last_gpu-first_gpu==0)
fprintf(screen,"Initializing GPU %d on core %d...",first_gpu,i);
else
fprintf(screen,"Initializing GPUs %d-%d on core %d...",first_gpu,
last_gpu,i);
fflush(screen);
}
if (gpu_rank==i && world_me!=0)
init_ok=CMMMF.init(ntypes,cutsq,cg_types,host_lj1,host_lj2,host_lj3,
host_lj4, offset, special_lj, inum, nall, 300,
maxspecial, cell_size, gpu_split, screen);
CMMMF.device->gpu_barrier();
if (message)
fprintf(screen,"Done.\n");
}
if (message)
fprintf(screen,"\n");
if (init_ok==0)
CMMMF.estimate_gpu_overhead();
return init_ok;
}
void cmm_gpu_clear() {
CMMMF.clear();
}
int** cmm_gpu_compute_n(const int ago, const int inum_full,
const int nall, double **host_x, int *host_type,
double *sublo, double *subhi, int *tag, int **nspecial,
int **special, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
int **ilist, int **jnum, const double cpu_time,
bool &success) {
return CMMMF.compute(ago, inum_full, nall, host_x, host_type, sublo,
subhi, tag, nspecial, special, eflag, vflag, eatom,
vatom, host_start, ilist, jnum, cpu_time, success);
}
void cmm_gpu_compute(const int ago, const int inum_full, const int nall,
double **host_x, int *host_type, int *ilist, int *numj,
int **firstneigh, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
const double cpu_time, bool &success) {
CMMMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj,
firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success);
}
double cmm_gpu_bytes() {
return CMMMF.host_memory_usage();
}
diff --git a/lib/gpu/lal_cg_cmm_long.cpp b/lib/gpu/lal_cg_cmm_long.cpp
index ffda7343c..2c12125b5 100644
--- a/lib/gpu/lal_cg_cmm_long.cpp
+++ b/lib/gpu/lal_cg_cmm_long.cpp
@@ -1,169 +1,169 @@
/***************************************************************************
cg_cmm_long.cpp
-------------------
W. Michael Brown (ORNL)
- Class for acceleration of the cg/cmm/coul/long pair style
+ Class for acceleration of the lj/sdk/coul/long pair style
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#ifdef USE_OPENCL
#include "cg_cmm_long_cl.h"
#else
#include "cg_cmm_long_ptx.h"
#endif
#include "lal_cg_cmm_long.h"
#include <cassert>
using namespace LAMMPS_AL;
#define CGCMMLongT CGCMMLong<numtyp, acctyp>
extern Device<PRECISION,ACC_PRECISION> device;
template <class numtyp, class acctyp>
CGCMMLongT::CGCMMLong() : BaseCharge<numtyp,acctyp>(),
_allocated(false) {
}
template <class numtyp, class acctyp>
CGCMMLongT::~CGCMMLong() {
clear();
}
template <class numtyp, class acctyp>
int CGCMMLongT::bytes_per_atom(const int max_nbors) const {
return this->bytes_per_atom_atomic(max_nbors);
}
template <class numtyp, class acctyp>
int CGCMMLongT::init(const int ntypes, double **host_cutsq,
int **host_cg_type, double **host_lj1,
double **host_lj2, double **host_lj3,
double **host_lj4, double **host_offset,
double *host_special_lj, const int nlocal,
const int nall, const int max_nbors,
const int maxspecial, const double cell_size,
const double gpu_split, FILE *_screen,
double **host_cut_ljsq,
const double host_cut_coulsq,
double *host_special_coul, const double qqrd2e,
const double g_ewald) {
int success;
success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split,
_screen,cg_cmm_long);
if (success!=0)
return success;
// If atom type constants fit in shared memory use fast kernel
int lj_types=ntypes;
shared_types=false;
int max_shared_types=this->device->max_shared_types();
if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) {
lj_types=max_shared_types;
shared_types=true;
}
_lj_types=lj_types;
// Allocate a host write buffer for data initialization
UCL_H_Vec<numtyp> host_write(lj_types*lj_types*32,*(this->ucl_device),
UCL_WRITE_OPTIMIZED);
for (int i=0; i<lj_types*lj_types; i++)
host_write[i]=0.0;
lj1.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY);
this->atom->type_pack4(ntypes,lj_types,lj1,host_write,host_cutsq,
host_cut_ljsq,host_lj1,host_lj2);
lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY);
this->atom->type_pack4(ntypes,lj_types,lj3,host_write,host_cg_type,host_lj3,
host_lj4,host_offset);
sp_lj.alloc(8,*(this->ucl_device),UCL_READ_ONLY);
for (int i=0; i<4; i++) {
host_write[i]=host_special_lj[i];
host_write[i+4]=host_special_coul[i];
}
ucl_copy(sp_lj,host_write,8,false);
_cut_coulsq=host_cut_coulsq;
_qqrd2e=qqrd2e;
_g_ewald=g_ewald;
_allocated=true;
this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+sp_lj.row_bytes();
return 0;
}
template <class numtyp, class acctyp>
void CGCMMLongT::clear() {
if (!_allocated)
return;
_allocated=false;
lj1.clear();
lj3.clear();
sp_lj.clear();
this->clear_atomic();
}
template <class numtyp, class acctyp>
double CGCMMLongT::host_memory_usage() const {
return this->host_memory_usage_atomic()+sizeof(CGCMMLong<numtyp,acctyp>);
}
// ---------------------------------------------------------------------------
// Calculate energies, forces, and torques
// ---------------------------------------------------------------------------
template <class numtyp, class acctyp>
void CGCMMLongT::loop(const bool _eflag, const bool _vflag) {
// Compute the block size and grid size to keep all cores busy
const int BX=this->block_size();
int eflag, vflag;
if (_eflag)
eflag=1;
else
eflag=0;
if (_vflag)
vflag=1;
else
vflag=0;
int GX=static_cast<int>(ceil(static_cast<double>(this->ans->inum())/
(BX/this->_threads_per_atom)));
int ainum=this->ans->inum();
int nbor_pitch=this->nbor->nbor_pitch();
this->time_pair.start();
if (shared_types) {
this->k_pair_fast.set_size(GX,BX);
this->k_pair_fast.run(&this->atom->dev_x.begin(), &lj1.begin(),
&lj3.begin(), &sp_lj.begin(),
&this->nbor->dev_nbor.begin(),
&this->_nbor_data->begin(),
&this->ans->dev_ans.begin(),
&this->ans->dev_engv.begin(), &eflag, &vflag,
&ainum, &nbor_pitch,
&this->atom->dev_q.begin(), &_cut_coulsq,
&_qqrd2e, &_g_ewald, &this->_threads_per_atom);
} else {
this->k_pair.set_size(GX,BX);
this->k_pair.run(&this->atom->dev_x.begin(), &lj1.begin(), &lj3.begin(),
&_lj_types, &sp_lj.begin(), &this->nbor->dev_nbor.begin(),
&this->_nbor_data->begin(), &this->ans->dev_ans.begin(),
&this->ans->dev_engv.begin(), &eflag, &vflag, &ainum,
&nbor_pitch, &this->atom->dev_q.begin(),
&_cut_coulsq, &_qqrd2e, &_g_ewald,
&this->_threads_per_atom);
}
this->time_pair.stop();
}
template class CGCMMLong<PRECISION,ACC_PRECISION>;
diff --git a/lib/gpu/lal_cg_cmm_long.cu b/lib/gpu/lal_cg_cmm_long.cu
index 45dbf2a86..8051dd5ab 100644
--- a/lib/gpu/lal_cg_cmm_long.cu
+++ b/lib/gpu/lal_cg_cmm_long.cu
@@ -1,265 +1,269 @@
// **************************************************************************
// cg_cmm_long.cu
// -------------------
// W. Michael Brown (ORNL)
//
+<<<<<<< HEAD
// Device code for acceleration of the cg/cmm/coul/long pair style
+=======
+// Device code for acceleration of the lj/sdk/coul/long pair style
+>>>>>>> ad9fa0e18743a47e42452e38329083e37cb90055
//
// __________________________________________________________________________
// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
// __________________________________________________________________________
//
// begin :
// email : brownw@ornl.gov
// ***************************************************************************/
#ifdef NV_KERNEL
#include "lal_aux_fun1.h"
texture<float4> pos_tex;
texture<float> q_tex;
#ifndef _DOUBLE_DOUBLE
ucl_inline float4 fetch_pos(const int& i, const float4 *pos)
{ return tex1Dfetch(pos_tex, i); }
ucl_inline float fetch_q(const int& i, const float *q)
{ return tex1Dfetch(q_tex, i); }
#endif
#endif
__kernel void kernel_pair(__global numtyp4 *x_, __global numtyp4 *lj1,
__global numtyp4* lj3, const int lj_types,
__global numtyp *sp_lj_in, __global int *dev_nbor,
__global int *dev_packed, __global acctyp4 *ans,
__global acctyp *engv, const int eflag,
const int vflag, const int inum,
const int nbor_pitch, __global numtyp *q_ ,
const numtyp cut_coulsq, const numtyp qqrd2e,
const numtyp g_ewald, const int t_per_atom) {
int tid, ii, offset;
atom_info(t_per_atom,ii,tid,offset);
__local numtyp sp_lj[8];
sp_lj[0]=sp_lj_in[0];
sp_lj[1]=sp_lj_in[1];
sp_lj[2]=sp_lj_in[2];
sp_lj[3]=sp_lj_in[3];
sp_lj[4]=sp_lj_in[4];
sp_lj[5]=sp_lj_in[5];
sp_lj[6]=sp_lj_in[6];
sp_lj[7]=sp_lj_in[7];
acctyp energy=(acctyp)0;
acctyp e_coul=(acctyp)0;
acctyp4 f;
f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
acctyp virial[6];
for (int i=0; i<6; i++)
virial[i]=(acctyp)0;
if (ii<inum) {
__global int *nbor, *list_end;
int i, numj, n_stride;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,list_end,nbor);
numtyp4 ix=fetch_pos(i,x_); //x_[i];
numtyp qtmp=fetch_q(i,q_);
int itype=ix.w;
for ( ; nbor<list_end; nbor+=n_stride) {
int j=*nbor;
numtyp factor_lj, factor_coul;
factor_lj = sp_lj[sbmask(j)];
factor_coul = (numtyp)1.0-sp_lj[sbmask(j)+4];
j &= NEIGHMASK;
numtyp4 jx=fetch_pos(j,x_); //x_[j];
int jtype=jx.w;
// Compute r12
numtyp delx = ix.x-jx.x;
numtyp dely = ix.y-jx.y;
numtyp delz = ix.z-jx.z;
numtyp rsq = delx*delx+dely*dely+delz*delz;
int mtype=itype*lj_types+jtype;
if (rsq<lj1[mtype].x) {
numtyp forcecoul, force_lj, force, inv1, inv2, prefactor, _erfc;
numtyp r2inv=ucl_recip(rsq);
if (rsq < lj1[mtype].y) {
if (lj3[mtype].x == (numtyp)2) {
inv1=r2inv*r2inv;
inv2=inv1*inv1;
} else if (lj3[mtype].x == (numtyp)1) {
inv2=r2inv*ucl_rsqrt(rsq);
inv1=inv2*inv2;
} else {
inv1=r2inv*r2inv*r2inv;
inv2=inv1;
}
force_lj = factor_lj*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
} else
force_lj = (numtyp)0.0;
if (rsq < cut_coulsq) {
numtyp r = ucl_rsqrt(r2inv);
numtyp grij = g_ewald * r;
numtyp expm2 = ucl_exp(-grij*grij);
numtyp t = ucl_recip((numtyp)1.0 + EWALD_P*grij);
_erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*fetch_q(j,q_)/r;
forcecoul = prefactor * (_erfc + EWALD_F*grij*expm2-factor_coul);
} else
forcecoul = (numtyp)0.0;
force = (force_lj + forcecoul) * r2inv;
f.x+=delx*force;
f.y+=dely*force;
f.z+=delz*force;
if (eflag>0) {
if (rsq < cut_coulsq)
e_coul += prefactor*(_erfc-factor_coul);
if (rsq < lj1[mtype].y) {
energy += factor_lj*inv1*(lj3[mtype].y*inv2-lj3[mtype].z)-
lj3[mtype].w;
}
}
if (vflag>0) {
virial[0] += delx*delx*force;
virial[1] += dely*dely*force;
virial[2] += delz*delz*force;
virial[3] += delx*dely*force;
virial[4] += delx*delz*force;
virial[5] += dely*delz*force;
}
}
} // for nbor
store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,
vflag,ans,engv);
} // if ii
}
__kernel void kernel_pair_fast(__global numtyp4 *x_, __global numtyp4 *lj1_in,
__global numtyp4* lj3_in,
__global numtyp* sp_lj_in,
__global int *dev_nbor, __global int *dev_packed,
__global acctyp4 *ans, __global acctyp *engv,
const int eflag, const int vflag, const int inum,
const int nbor_pitch, __global numtyp *q_,
const numtyp cut_coulsq, const numtyp qqrd2e,
const numtyp g_ewald, const int t_per_atom) {
int tid, ii, offset;
atom_info(t_per_atom,ii,tid,offset);
__local numtyp4 lj1[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
__local numtyp4 lj3[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
__local numtyp sp_lj[8];
if (tid<8)
sp_lj[tid]=sp_lj_in[tid];
if (tid<MAX_SHARED_TYPES*MAX_SHARED_TYPES) {
lj1[tid]=lj1_in[tid];
lj3[tid]=lj3_in[tid];
}
acctyp energy=(acctyp)0;
acctyp e_coul=(acctyp)0;
acctyp4 f;
f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
acctyp virial[6];
for (int i=0; i<6; i++)
virial[i]=(acctyp)0;
__syncthreads();
if (ii<inum) {
__global int *nbor, *list_end;
int i, numj, n_stride;
nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
n_stride,list_end,nbor);
numtyp4 ix=fetch_pos(i,x_); //x_[i];
numtyp qtmp=fetch_q(i,q_);
int iw=ix.w;
int itype=fast_mul((int)MAX_SHARED_TYPES,iw);
for ( ; nbor<list_end; nbor+=n_stride) {
int j=*nbor;
numtyp factor_lj, factor_coul;
factor_lj = sp_lj[sbmask(j)];
factor_coul = (numtyp)1.0-sp_lj[sbmask(j)+4];
j &= NEIGHMASK;
numtyp4 jx=fetch_pos(j,x_); //x_[j];
int mtype=itype+jx.w;
// Compute r12
numtyp delx = ix.x-jx.x;
numtyp dely = ix.y-jx.y;
numtyp delz = ix.z-jx.z;
numtyp rsq = delx*delx+dely*dely+delz*delz;
if (rsq<lj1[mtype].x) {
numtyp forcecoul, force_lj, force, inv1, inv2, prefactor, _erfc;
numtyp r2inv=ucl_recip(rsq);
if (rsq < lj1[mtype].y) {
if (lj3[mtype].x == (numtyp)2) {
inv1=r2inv*r2inv;
inv2=inv1*inv1;
} else if (lj3[mtype].x == (numtyp)1) {
inv2=r2inv*ucl_rsqrt(rsq);
inv1=inv2*inv2;
} else {
inv1=r2inv*r2inv*r2inv;
inv2=inv1;
}
force_lj = factor_lj*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
} else
force_lj = (numtyp)0.0;
if (rsq < cut_coulsq) {
numtyp r = ucl_rsqrt(r2inv);
numtyp grij = g_ewald * r;
numtyp expm2 = ucl_exp(-grij*grij);
numtyp t = ucl_recip((numtyp)1.0 + EWALD_P*grij);
_erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*fetch_q(j,q_)/r;
forcecoul = prefactor * (_erfc + EWALD_F*grij*expm2-factor_coul);
} else
forcecoul = (numtyp)0.0;
force = (force_lj + forcecoul) * r2inv;
f.x+=delx*force;
f.y+=dely*force;
f.z+=delz*force;
if (eflag>0) {
if (rsq < cut_coulsq)
e_coul += prefactor*(_erfc-factor_coul);
if (rsq < lj1[mtype].y) {
energy += factor_lj*inv1*(lj3[mtype].y*inv2-lj3[mtype].z)-
lj3[mtype].w;
}
}
if (vflag>0) {
virial[0] += delx*delx*force;
virial[1] += dely*dely*force;
virial[2] += delz*delz*force;
virial[3] += delx*dely*force;
virial[4] += delx*delz*force;
virial[5] += dely*delz*force;
}
}
} // for nbor
store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,
vflag,ans,engv);
} // if ii
}
diff --git a/lib/gpu/lal_cg_cmm_long.h b/lib/gpu/lal_cg_cmm_long.h
index 1ffbc7c5b..bde5c79c7 100644
--- a/lib/gpu/lal_cg_cmm_long.h
+++ b/lib/gpu/lal_cg_cmm_long.h
@@ -1,83 +1,83 @@
/***************************************************************************
cg_cmm_long.h
-------------------
W. Michael Brown (ORNL)
- Class for acceleration of the cg/cmm/coul/long pair style
+ Class for acceleration of the lj/sdk/coul/long pair style
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#ifndef LAL_CG_CMM_LONG_H
#define LAL_CG_CMM_LONG_H
#include "lal_base_charge.h"
namespace LAMMPS_AL {
template <class numtyp, class acctyp>
class CGCMMLong : public BaseCharge<numtyp, acctyp> {
public:
CGCMMLong();
~CGCMMLong();
/// Clear any previous data and set up for a new LAMMPS run
/** \param max_nbors initial number of rows in the neighbor matrix
* \param cell_size cutoff + skin
* \param gpu_split fraction of particles handled by device
*
* Returns:
* - 0 if successfull
* - -1 if fix gpu not found
* - -3 if there is an out of memory error
* - -4 if the GPU library was not compiled for GPU
* - -5 Double precision is not supported on card **/
int init(const int ntypes, double **host_cutsq, int ** cg_type,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **host_offset, double *host_special_lj,
const int nlocal, const int nall, const int max_nbors,
const int maxspecial, const double cell_size,
const double gpu_split, FILE *screen, double **host_cut_ljsq,
const double host_cut_coulsq, double *host_special_coul,
const double qqrd2e, const double g_ewald);
/// Clear all host and device data
/** \note This is called at the beginning of the init() routine **/
void clear();
/// Returns memory usage on device per atom
int bytes_per_atom(const int max_nbors) const;
/// Total host memory used by library for pair style
double host_memory_usage() const;
// --------------------------- TYPE DATA --------------------------
/// lj1.x = cutsq, lj1.y = cutsq_vdw, lj1.z = lj1, lj1.w = lj2,
UCL_D_Vec<numtyp4> lj1;
/// lj3.x = cg_type, lj3.y = lj3, lj3.z = lj4, lj3.w = offset
UCL_D_Vec<numtyp4> lj3;
/// Special LJ values [0-3] and Special Coul values [4-7]
UCL_D_Vec<numtyp> sp_lj;
/// If atom type constants fit in shared memory, use fast kernels
bool shared_types;
/// Number of atom types
int _lj_types;
numtyp _cut_coulsq, _qqrd2e, _g_ewald;
private:
bool _allocated;
void loop(const bool _eflag, const bool _vflag);
};
}
#endif
diff --git a/lib/gpu/lal_cg_cmm_long_ext.cpp b/lib/gpu/lal_cg_cmm_long_ext.cpp
index 8da2d65af..ca7aab70c 100644
--- a/lib/gpu/lal_cg_cmm_long_ext.cpp
+++ b/lib/gpu/lal_cg_cmm_long_ext.cpp
@@ -1,129 +1,129 @@
/***************************************************************************
cg_cmm_long.h
-------------------
W. Michael Brown (ORNL)
- Functions for LAMMPS access to cg/cmm/coul/long acceleration functions
+ Functions for LAMMPS access to lj/sdk/coul/long acceleration functions
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#include <iostream>
#include <cassert>
#include <math.h>
#include "lal_cg_cmm_long.h"
using namespace std;
using namespace LAMMPS_AL;
static CGCMMLong<PRECISION,ACC_PRECISION> CMMLMF;
// ---------------------------------------------------------------------------
// Allocate memory on host and device and copy constants to device
// ---------------------------------------------------------------------------
int cmml_gpu_init(const int ntypes, double **cutsq, int **cg_type,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **offset, double *special_lj,
const int inum, const int nall, const int max_nbors,
const int maxspecial, const double cell_size, int &gpu_mode,
FILE *screen, double **host_cut_ljsq, double host_cut_coulsq,
double *host_special_coul, const double qqrd2e,
const double g_ewald) {
CMMLMF.clear();
gpu_mode=CMMLMF.device->gpu_mode();
double gpu_split=CMMLMF.device->particle_split();
int first_gpu=CMMLMF.device->first_device();
int last_gpu=CMMLMF.device->last_device();
int world_me=CMMLMF.device->world_me();
int gpu_rank=CMMLMF.device->gpu_rank();
int procs_per_gpu=CMMLMF.device->procs_per_gpu();
- CMMLMF.device->init_message(screen,"cg/cmm/coul/long",first_gpu,last_gpu);
+ CMMLMF.device->init_message(screen,"lj/sdk/coul/long",first_gpu,last_gpu);
bool message=false;
if (CMMLMF.device->replica_me()==0 && screen)
message=true;
if (message) {
fprintf(screen,"Initializing GPU and compiling on process 0...");
fflush(screen);
}
int init_ok=0;
if (world_me==0)
init_ok=CMMLMF.init(ntypes, cutsq, cg_type, host_lj1, host_lj2, host_lj3,
host_lj4, offset, special_lj, inum, nall, 300,
maxspecial, cell_size, gpu_split, screen, host_cut_ljsq,
host_cut_coulsq, host_special_coul, qqrd2e,g_ewald);
CMMLMF.device->world_barrier();
if (message)
fprintf(screen,"Done.\n");
for (int i=0; i<procs_per_gpu; i++) {
if (message) {
if (last_gpu-first_gpu==0)
fprintf(screen,"Initializing GPU %d on core %d...",first_gpu,i);
else
fprintf(screen,"Initializing GPUs %d-%d on core %d...",first_gpu,
last_gpu,i);
fflush(screen);
}
if (gpu_rank==i && world_me!=0)
init_ok=CMMLMF.init(ntypes, cutsq, cg_type, host_lj1, host_lj2, host_lj3,
host_lj4, offset, special_lj, inum, nall, 300,
maxspecial, cell_size, gpu_split, screen,
host_cut_ljsq, host_cut_coulsq, host_special_coul,
qqrd2e, g_ewald);
CMMLMF.device->gpu_barrier();
if (message)
fprintf(screen,"Done.\n");
}
if (message)
fprintf(screen,"\n");
if (init_ok==0)
CMMLMF.estimate_gpu_overhead();
return init_ok;
}
void cmml_gpu_clear() {
CMMLMF.clear();
}
int** cmml_gpu_compute_n(const int ago, const int inum_full,
const int nall, double **host_x, int *host_type,
double *sublo, double *subhi, int *tag, int **nspecial,
int **special, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
int **ilist, int **jnum, const double cpu_time,
bool &success, double *host_q, double *boxlo,
double *prd) {
return CMMLMF.compute(ago, inum_full, nall, host_x, host_type, sublo,
subhi, tag, nspecial, special, eflag, vflag, eatom,
vatom, host_start, ilist, jnum, cpu_time, success,
host_q,boxlo,prd);
}
void cmml_gpu_compute(const int ago, const int inum_full, const int nall,
double **host_x, int *host_type, int *ilist, int *numj,
int **firstneigh, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
const double cpu_time, bool &success, double *host_q,
const int nlocal, double *boxlo, double *prd) {
CMMLMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj,
firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success,
host_q,nlocal,boxlo,prd);
}
double cmml_gpu_bytes() {
return CMMLMF.host_memory_usage();
}
diff --git a/lib/gpu/lal_cg_cmm_msm.cpp b/lib/gpu/lal_cg_cmm_msm.cpp
deleted file mode 100644
index 6376c9d99..000000000
--- a/lib/gpu/lal_cg_cmm_msm.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/***************************************************************************
- cg_cmm_msm.cpp
- -------------------
- W. Michael Brown (ORNL)
-
- Class for acceleration of the cg/cmm/coul/msm pair style.
-
- __________________________________________________________________________
- This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
- __________________________________________________________________________
-
- begin :
- email : brownw@ornl.gov
- ***************************************************************************/
-
-#ifdef USE_OPENCL
-#include "cg_cmm_msm_cl.h"
-#else
-#include "cg_cmm_msm_ptx.h"
-#endif
-
-#include "lal_cg_cmm_msm.h"
-#include <cassert>
-using namespace LAMMPS_AL;
-#define CGCMMMSMT CGCMMMSM<numtyp, acctyp>
-
-extern Device<PRECISION,ACC_PRECISION> device;
-
-template <class numtyp, class acctyp>
-CGCMMMSMT::CGCMMMSM() : BaseCharge<numtyp,acctyp>(),
- _allocated(false) {
-}
-
-template <class numtyp, class acctyp>
-CGCMMMSMT::~CGCMMMSM() {
- clear();
-}
-
-template <class numtyp, class acctyp>
-int CGCMMMSMT::bytes_per_atom(const int max_nbors) const {
- return this->bytes_per_atom_atomic(max_nbors);
-}
-
-template <class numtyp, class acctyp>
-int CGCMMMSMT::init(const int ntypes, double **host_cutsq,
- int **host_cg_type, double **host_lj1,
- double **host_lj2, double **host_lj3,
- double **host_lj4, double **host_offset,
- double *host_special_lj, const int nlocal,
- const int nall, const int max_nbors,
- const int maxspecial, const double cell_size,
- const double gpu_split, FILE *_screen,
- double **host_cut_ljsq,
- const double host_cut_coulsq,
- double *host_special_coul, const double qqrd2e,
- const int smooth) {
- int success;
- success=this->init_atomic(nlocal,nall,max_nbors,maxspecial,cell_size,gpu_split,
- _screen,cg_cmm_msm);
- if (success!=0)
- return success;
-
- // If atom type constants fit in shared memory use fast kernel
- int lj_types=ntypes;
- shared_types=false;
- int max_shared_types=this->device->max_shared_types();
- if (lj_types<=max_shared_types && this->_block_size>=max_shared_types) {
- lj_types=max_shared_types;
- shared_types=true;
- }
- _lj_types=lj_types;
-
- // Allocate a host write buffer for data initialization
- UCL_H_Vec<numtyp> host_write(lj_types*lj_types*32,*(this->ucl_device),
- UCL_WRITE_OPTIMIZED);
-
- for (int i=0; i<lj_types*lj_types; i++)
- host_write[i]=0.0;
-
- lj1.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY);
- this->atom->type_pack4(ntypes,lj_types,lj1,host_write,host_cutsq,
- host_cut_ljsq,host_lj1,host_lj2);
-
- lj3.alloc(lj_types*lj_types,*(this->ucl_device),UCL_READ_ONLY);
- this->atom->type_pack4(ntypes,lj_types,lj3,host_write,host_cg_type,host_lj3,
- host_lj4,host_offset);
-
- sp_lj.alloc(8,*(this->ucl_device),UCL_READ_ONLY);
- for (int i=0; i<4; i++) {
- host_write[i]=host_special_lj[i];
- host_write[i+4]=host_special_coul[i];
- }
- ucl_copy(sp_lj,host_write,8,false);
-
- _cut_coulsq=host_cut_coulsq;
- _qqrd2e=qqrd2e;
- _smooth=smooth;
-
- _allocated=true;
- this->_max_bytes=lj1.row_bytes()+lj3.row_bytes()+sp_lj.row_bytes();
- return 0;
-}
-
-template <class numtyp, class acctyp>
-void CGCMMMSMT::clear() {
- if (!_allocated)
- return;
- _allocated=false;
-
- lj1.clear();
- lj3.clear();
- sp_lj.clear();
- this->clear_atomic();
-}
-
-template <class numtyp, class acctyp>
-double CGCMMMSMT::host_memory_usage() const {
- return this->host_memory_usage_atomic()+sizeof(CGCMMMSM<numtyp,acctyp>);
-}
-
-// ---------------------------------------------------------------------------
-// Calculate energies, forces, and torques
-// ---------------------------------------------------------------------------
-template <class numtyp, class acctyp>
-void CGCMMMSMT::loop(const bool _eflag, const bool _vflag) {
- // Compute the block size and grid size to keep all cores busy
- const int BX=this->block_size();
- int eflag, vflag;
- if (_eflag)
- eflag=1;
- else
- eflag=0;
-
- if (_vflag)
- vflag=1;
- else
- vflag=0;
-
- int GX=static_cast<int>(ceil(static_cast<double>(this->ans->inum())/
- (BX/this->_threads_per_atom)));
-
- int ainum=this->ans->inum();
- int nbor_pitch=this->nbor->nbor_pitch();
- this->time_pair.start();
- if (shared_types) {
- this->k_pair_fast.set_size(GX,BX);
- this->k_pair_fast.run(&this->atom->dev_x.begin(), &lj1.begin(),
- &lj3.begin(), &sp_lj.begin(),
- &this->nbor->dev_nbor.begin(),
- &this->_nbor_data->begin(),
- &this->ans->dev_ans.begin(),
- &this->ans->dev_engv.begin(), &eflag, &vflag,
- &ainum, &nbor_pitch,
- &this->atom->dev_q.begin(), &_cut_coulsq,
- &_qqrd2e, &_smooth, &this->_threads_per_atom);
- } else {
- this->k_pair.set_size(GX,BX);
- this->k_pair.run(&this->atom->dev_x.begin(), &lj1.begin(), &lj3.begin(),
- &_lj_types, &sp_lj.begin(), &this->nbor->dev_nbor.begin(),
- &this->_nbor_data->begin(), &this->ans->dev_ans.begin(),
- &this->ans->dev_engv.begin(), &eflag, &vflag, &ainum,
- &nbor_pitch, &this->atom->dev_q.begin(), &_cut_coulsq,
- &_qqrd2e, &_smooth, &this->_threads_per_atom);
- }
- this->time_pair.stop();
-}
-
-template class CGCMMMSM<PRECISION,ACC_PRECISION>;
diff --git a/lib/gpu/lal_cg_cmm_msm.cu b/lib/gpu/lal_cg_cmm_msm.cu
deleted file mode 100644
index 2f0bd1c3a..000000000
--- a/lib/gpu/lal_cg_cmm_msm.cu
+++ /dev/null
@@ -1,315 +0,0 @@
-// **************************************************************************
-// cg_cmm_msm.cu
-// -------------------
-// W. Michael Brown (ORNL)
-//
-// Device code for acceleration of the cg/cmm/msm pair style
-//
-// __________________________________________________________________________
-// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
-// __________________________________________________________________________
-//
-// begin :
-// email : brownw@ornl.gov
-// ***************************************************************************/
-
-#ifdef NV_KERNEL
-#include "lal_aux_fun1.h"
-texture<float4> pos_tex;
-texture<float> q_tex;
-#ifndef _DOUBLE_DOUBLE
-ucl_inline float4 fetch_pos(const int& i, const float4 *pos)
- { return tex1Dfetch(pos_tex, i); }
-ucl_inline float fetch_q(const int& i, const float *q)
- { return tex1Dfetch(q_tex, i); }
-#endif
-#endif
-
-__kernel void kernel_pair(__global numtyp4 *x_, __global numtyp4 *lj1,
- __global numtyp4* lj3, const int lj_types,
- __global numtyp *sp_lj_in, __global int *dev_nbor,
- __global int *dev_packed, __global acctyp4 *ans,
- __global acctyp *engv, const int eflag,
- const int vflag, const int inum,
- const int nbor_pitch, __global numtyp *q_,
- const numtyp cut_coulsq, const numtyp qqrd2e,
- const int smooth, const int t_per_atom) {
- int tid, ii, offset;
- atom_info(t_per_atom,ii,tid,offset);
-
- __local numtyp sp_lj[8];
- sp_lj[0]=sp_lj_in[0];
- sp_lj[1]=sp_lj_in[1];
- sp_lj[2]=sp_lj_in[2];
- sp_lj[3]=sp_lj_in[3];
- sp_lj[4]=sp_lj_in[4];
- sp_lj[5]=sp_lj_in[5];
- sp_lj[6]=sp_lj_in[6];
- sp_lj[7]=sp_lj_in[7];
- __local numtyp _ia;
- __local numtyp _ia2;
- __local numtyp _ia3;
-
- acctyp energy=(acctyp)0;
- acctyp e_coul=(acctyp)0;
- acctyp4 f;
- f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
- acctyp virial[6];
- for (int i=0; i<6; i++)
- virial[i]=(acctyp)0;
-
- if (ii<inum) {
- _ia=-ucl_rsqrt(cut_coulsq);
- _ia2=ucl_recip(cut_coulsq);
- _ia3=_ia2*_ia;
-
- __global int *nbor, *list_end;
- int i, numj, n_stride;
- nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
- n_stride,list_end,nbor);
-
- numtyp4 ix=fetch_pos(i,x_); //x_[i];
- numtyp qtmp=fetch_q(i,q_);
- int itype=ix.w;
-
- for ( ; nbor<list_end; nbor+=n_stride) {
- int j=*nbor;
-
- numtyp factor_lj, factor_coul;
- factor_lj = sp_lj[sbmask(j)];
- factor_coul = (numtyp)1.0-sp_lj[sbmask(j)+4];
- j &= NEIGHMASK;
-
- numtyp4 jx=fetch_pos(j,x_); //x_[j];
- int jtype=jx.w;
-
- // Compute r12
- numtyp delx = ix.x-jx.x;
- numtyp dely = ix.y-jx.y;
- numtyp delz = ix.z-jx.z;
- numtyp rsq = delx*delx+dely*dely+delz*delz;
-
- int mtype=itype*lj_types+jtype;
- if (rsq<lj1[mtype].x) {
- numtyp forcecoul, force_lj, force, inv1, inv2, prefactor;
- numtyp r2inv=ucl_recip(rsq);
-
- if (rsq < lj1[mtype].y) {
- if (lj3[mtype].x == (numtyp)2) {
- inv1=r2inv*r2inv;
- inv2=inv1*inv1;
- } else if (lj3[mtype].x == (numtyp)1) {
- inv2=r2inv*ucl_rsqrt(rsq);
- inv1=inv2*inv2;
- } else {
- inv1=r2inv*r2inv*r2inv;
- inv2=inv1;
- }
- force_lj = factor_lj*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
- } else
- force_lj = (numtyp)0.0;
-
- numtyp ir, r2_ia2, r4_ia4, r6_ia6;
- if (rsq < cut_coulsq) {
- ir = ucl_rsqrt(rsq);
- prefactor = qqrd2e*qtmp*fetch_q(j,q_);
- r2_ia2 = rsq*_ia2;
- r4_ia4 = r2_ia2*r2_ia2;
- if (smooth==0)
- forcecoul = prefactor*(_ia3*((numtyp)-4.375+(numtyp)5.25*r2_ia2-
- (numtyp)1.875*r4_ia4)-ir/rsq-
- factor_coul*ir);
- else {
- r6_ia6 = r2_ia2*r4_ia4;
- forcecoul = prefactor*(_ia3*((numtyp)-6.5625+(numtyp)11.8125*
- r2_ia2-(numtyp)8.4375*r4_ia4+
- (numtyp)2.1875*r6_ia6)-ir/rsq-
- factor_coul*ir);
- }
- } else
- forcecoul = (numtyp)0.0;
-
- force = forcecoul + force_lj * r2inv;
-
- f.x+=delx*force;
- f.y+=dely*force;
- f.z+=delz*force;
-
- if (eflag>0) {
- if (rsq < cut_coulsq)
- if (smooth==0)
- e_coul += prefactor*(ir+_ia*((numtyp)2.1875-(numtyp)2.1875*r2_ia2+
- (numtyp)1.3125*r4_ia4-
- (numtyp)0.3125*r4_ia4*r2_ia2)-
- factor_coul*ir);
- else
- e_coul += prefactor*(ir+_ia*((numtyp)2.4609375-(numtyp)3.28125*
- r2_ia2+(numtyp)2.953125*r4_ia4-
- (numtyp)1.40625*r6_ia6+
- (numtyp)0.2734375*r4_ia4*r4_ia4));
-
- if (rsq < lj1[mtype].y) {
- energy += factor_lj*inv1*(lj3[mtype].y*inv2-lj3[mtype].z)-
- lj3[mtype].w;
- }
- }
- if (vflag>0) {
- virial[0] += delx*delx*force;
- virial[1] += dely*dely*force;
- virial[2] += delz*delz*force;
- virial[3] += delx*dely*force;
- virial[4] += delx*delz*force;
- virial[5] += dely*delz*force;
- }
- }
-
- } // for nbor
- store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,
- vflag,ans,engv);
- } // if ii
-}
-
-__kernel void kernel_pair_fast(__global numtyp4 *x_, __global numtyp4 *lj1_in,
- __global numtyp4* lj3_in,
- __global numtyp* sp_lj_in,
- __global int *dev_nbor, __global int *dev_packed,
- __global acctyp4 *ans, __global acctyp *engv,
- const int eflag, const int vflag, const int inum,
- const int nbor_pitch, __global numtyp *q_,
- const numtyp cut_coulsq, const numtyp qqrd2e,
- const int smooth, const int t_per_atom) {
- int tid, ii, offset;
- atom_info(t_per_atom,ii,tid,offset);
-
- __local numtyp4 lj1[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
- __local numtyp4 lj3[MAX_SHARED_TYPES*MAX_SHARED_TYPES];
- __local numtyp sp_lj[8];
- if (tid<8)
- sp_lj[tid]=sp_lj_in[tid];
- if (tid<MAX_SHARED_TYPES*MAX_SHARED_TYPES) {
- lj1[tid]=lj1_in[tid];
- lj3[tid]=lj3_in[tid];
- }
-
- acctyp energy=(acctyp)0;
- acctyp e_coul=(acctyp)0;
- acctyp4 f;
- f.x=(acctyp)0; f.y=(acctyp)0; f.z=(acctyp)0;
- acctyp virial[6];
- for (int i=0; i<6; i++)
- virial[i]=(acctyp)0;
-
- __local numtyp _ia;
- __local numtyp _ia2;
- __local numtyp _ia3;
- _ia=-ucl_rsqrt(cut_coulsq);
- _ia2=ucl_recip(cut_coulsq);
- _ia3=_ia2*_ia;
- __syncthreads();
-
- if (ii<inum) {
- __global int *nbor, *list_end;
- int i, numj, n_stride;
- nbor_info(dev_nbor,dev_packed,nbor_pitch,t_per_atom,ii,offset,i,numj,
- n_stride,list_end,nbor);
-
- numtyp4 ix=fetch_pos(i,x_); //x_[i];
- numtyp qtmp=fetch_q(i,q_);
- int iw=ix.w;
- int itype=fast_mul((int)MAX_SHARED_TYPES,iw);
-
- for ( ; nbor<list_end; nbor+=n_stride) {
- int j=*nbor;
-
- numtyp factor_lj, factor_coul;
- factor_lj = sp_lj[sbmask(j)];
- factor_coul = (numtyp)1.0-sp_lj[sbmask(j)+4];
- j &= NEIGHMASK;
-
- numtyp4 jx=fetch_pos(j,x_); //x_[j];
- int mtype=itype+jx.w;
-
- // Compute r12
- numtyp delx = ix.x-jx.x;
- numtyp dely = ix.y-jx.y;
- numtyp delz = ix.z-jx.z;
- numtyp rsq = delx*delx+dely*dely+delz*delz;
-
- if (rsq<lj1[mtype].x) {
- numtyp forcecoul, force_lj, force, inv1, inv2, prefactor;
- numtyp r2inv=ucl_recip(rsq);
-
- if (rsq < lj1[mtype].y) {
- if (lj3[mtype].x == (numtyp)2) {
- inv1=r2inv*r2inv;
- inv2=inv1*inv1;
- } else if (lj3[mtype].x == (numtyp)1) {
- inv2=r2inv*ucl_rsqrt(rsq);
- inv1=inv2*inv2;
- } else {
- inv1=r2inv*r2inv*r2inv;
- inv2=inv1;
- }
- force_lj = factor_lj*inv1*(lj1[mtype].z*inv2-lj1[mtype].w);
- } else
- force_lj = (numtyp)0.0;
-
- numtyp ir, r2_ia2, r4_ia4, r6_ia6;
- if (rsq < cut_coulsq) {
- ir = ucl_rsqrt(rsq);
- prefactor = qqrd2e*qtmp*fetch_q(j,q_);
- r2_ia2 = rsq*_ia2;
- r4_ia4 = r2_ia2*r2_ia2;
- if (smooth==0)
- forcecoul = prefactor*(_ia3*((numtyp)-4.375+(numtyp)5.25*r2_ia2-
- (numtyp)1.875*r4_ia4)-ir/rsq-
- factor_coul*ir);
- else {
- r6_ia6 = r2_ia2*r4_ia4;
- forcecoul = prefactor*(_ia3*((numtyp)-6.5625+(numtyp)11.8125*
- r2_ia2-(numtyp)8.4375*r4_ia4+
- (numtyp)2.1875*r6_ia6)-ir/rsq-
- factor_coul*ir);
- }
- } else
- forcecoul = (numtyp)0.0;
-
- force = forcecoul + force_lj * r2inv;
-
- f.x+=delx*force;
- f.y+=dely*force;
- f.z+=delz*force;
-
- if (eflag>0) {
- if (rsq < cut_coulsq)
- if (smooth==0)
- e_coul += prefactor*(ir+_ia*((numtyp)2.1875-(numtyp)2.1875*r2_ia2+
- (numtyp)1.3125*r4_ia4-
- (numtyp)0.3125*r4_ia4*r2_ia2)-
- factor_coul*ir);
- else
- e_coul += prefactor*(ir+_ia*((numtyp)2.4609375-(numtyp)3.28125*
- r2_ia2+(numtyp)2.953125*r4_ia4-
- (numtyp)1.40625*r6_ia6+
- (numtyp)0.2734375*r4_ia4*r4_ia4));
- if (rsq < lj1[mtype].y) {
- energy += factor_lj*inv1*(lj3[mtype].y*inv2-lj3[mtype].z)-
- lj3[mtype].w;
- }
- }
- if (vflag>0) {
- virial[0] += delx*delx*force;
- virial[1] += dely*dely*force;
- virial[2] += delz*delz*force;
- virial[3] += delx*dely*force;
- virial[4] += delx*delz*force;
- virial[5] += dely*delz*force;
- }
- }
-
- } // for nbor
- store_answers_q(f,energy,e_coul,virial,ii,inum,tid,t_per_atom,offset,eflag,
- vflag,ans,engv);
- } // if ii
-}
-
diff --git a/lib/gpu/lal_cg_cmm_msm.h b/lib/gpu/lal_cg_cmm_msm.h
deleted file mode 100644
index 694714f12..000000000
--- a/lib/gpu/lal_cg_cmm_msm.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- cg_cmm_msm.h
- -------------------
- W. Michael Brown (ORNL)
-
- Class for acceleration of the cg/cmm/coul/msm pair style.
-
- __________________________________________________________________________
- This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
- __________________________________________________________________________
-
- begin :
- email : brownw@ornl.gov
- ***************************************************************************/
-
-#ifndef LAL_CG_CMM_MSM_H
-#define LAL_CG_CMM_MSM_H
-
-#include "lal_base_charge.h"
-
-namespace LAMMPS_AL {
-
-template <class numtyp, class acctyp>
-class CGCMMMSM : public BaseCharge<numtyp, acctyp> {
- public:
- CGCMMMSM();
- ~CGCMMMSM();
-
- /// Clear any previous data and set up for a new LAMMPS run
- /** \param max_nbors initial number of rows in the neighbor matrix
- * \param cell_size cutoff + skin
- * \param gpu_split fraction of particles handled by device
- *
- * Returns:
- * - 0 if successfull
- * - -1 if fix gpu not found
- * - -3 if there is an out of memory error
- * - -4 if the GPU library was not compiled for GPU
- * - -5 Double precision is not supported on card **/
- int init(const int ntypes, double **host_cutsq, int ** cg_type,
- double **host_lj1, double **host_lj2, double **host_lj3,
- double **host_lj4, double **host_offset, double *host_special_lj,
- const int nlocal, const int nall, const int max_nbors,
- const int maxspecial, const double cell_size,
- const double gpu_split, FILE *screen, double **host_cut_ljsq,
- const double host_cut_coulsq, double *host_special_coul,
- const double qqrd2e, const int smooth);
-
- /// Clear all host and device data
- /** \note This is called at the beginning of the init() routine **/
- void clear();
-
- /// Returns memory usage on device per atom
- int bytes_per_atom(const int max_nbors) const;
-
- /// Total host memory used by library for pair style
- double host_memory_usage() const;
-
- // --------------------------- TYPE DATA --------------------------
-
- /// lj1.x = cutsq, lj1.y = cutsq_vdw, lj1.z = lj1, lj1.w = lj2,
- UCL_D_Vec<numtyp4> lj1;
- /// lj3.x = cg_type, lj3.y = lj3, lj3.z = lj4, lj3.w = offset
- UCL_D_Vec<numtyp4> lj3;
- /// Special LJ values [0-3] and Special Coul values [4-7]
- UCL_D_Vec<numtyp> sp_lj;
-
- /// If atom type constants fit in shared memory, use fast kernels
- bool shared_types;
-
- /// Number of atom types
- int _lj_types;
-
- numtyp _cut_coulsq, _qqrd2e;
-
- private:
- bool _allocated;
- int _smooth;
- void loop(const bool _eflag, const bool _vflag);
-};
-
-}
-
-#endif
diff --git a/lib/gpu/lal_cg_cmm_msm_ext.cpp b/lib/gpu/lal_cg_cmm_msm_ext.cpp
deleted file mode 100644
index 7b26a2403..000000000
--- a/lib/gpu/lal_cg_cmm_msm_ext.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/***************************************************************************
- cg_cmm_msm_ext.cpp
- -------------------
- W. Michael Brown (ORNL)
-
- Function for LAMMPS access to cg/cmm/coul/msm pair acceleration routines.
-
- __________________________________________________________________________
- This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
- __________________________________________________________________________
-
- begin :
- email : brownw@ornl.gov
- ***************************************************************************/
-
-#include <iostream>
-#include <cassert>
-#include <math.h>
-
-#include "lal_cg_cmm_msm.h"
-
-using namespace std;
-using namespace LAMMPS_AL;
-
-static CGCMMMSM<PRECISION,ACC_PRECISION> CMMMMF;
-
-// ---------------------------------------------------------------------------
-// Allocate memory on host and device and copy constants to device
-// ---------------------------------------------------------------------------
-int cmmm_gpu_init(const int ntypes, double **cutsq, int **cg_type,
- double **host_lj1, double **host_lj2, double **host_lj3,
- double **host_lj4, double **offset, double *special_lj,
- const int inum, const int nall, const int max_nbors,
- const int maxspecial, const double cell_size, int &gpu_mode,
- FILE *screen, double **host_cut_ljsq, double host_cut_coulsq,
- double *host_special_coul, const double qqrd2e,
- const int smooth) {
- CMMMMF.clear();
- gpu_mode=CMMMMF.device->gpu_mode();
- double gpu_split=CMMMMF.device->particle_split();
- int first_gpu=CMMMMF.device->first_device();
- int last_gpu=CMMMMF.device->last_device();
- int world_me=CMMMMF.device->world_me();
- int gpu_rank=CMMMMF.device->gpu_rank();
- int procs_per_gpu=CMMMMF.device->procs_per_gpu();
-
- CMMMMF.device->init_message(screen,"cg/cmm/coul/msm",first_gpu,last_gpu);
-
- bool message=false;
- if (CMMMMF.device->replica_me()==0 && screen)
- message=true;
-
- if (message) {
- fprintf(screen,"Initializing GPU and compiling on process 0...");
- fflush(screen);
- }
-
- int init_ok=0;
- if (world_me==0)
- init_ok=CMMMMF.init(ntypes, cutsq, cg_type, host_lj1, host_lj2, host_lj3,
- host_lj4, offset, special_lj, inum, nall, 300,
- maxspecial, cell_size, gpu_split, screen, host_cut_ljsq,
- host_cut_coulsq, host_special_coul, qqrd2e,smooth);
-
- CMMMMF.device->world_barrier();
- if (message)
- fprintf(screen,"Done.\n");
-
- for (int i=0; i<procs_per_gpu; i++) {
- if (message) {
- if (last_gpu-first_gpu==0)
- fprintf(screen,"Initializing GPU %d on core %d...",first_gpu,i);
- else
- fprintf(screen,"Initializing GPUs %d-%d on core %d...",first_gpu,
- last_gpu,i);
- fflush(screen);
- }
- if (gpu_rank==i && world_me!=0)
- init_ok=CMMMMF.init(ntypes, cutsq, cg_type, host_lj1, host_lj2, host_lj3,
- host_lj4, offset, special_lj, inum, nall, 300,
- maxspecial, cell_size, gpu_split, screen,
- host_cut_ljsq, host_cut_coulsq, host_special_coul,
- qqrd2e,smooth);
-
- CMMMMF.device->gpu_barrier();
- if (message)
- fprintf(screen,"Done.\n");
- }
- if (message)
- fprintf(screen,"\n");
-
- if (init_ok==0)
- CMMMMF.estimate_gpu_overhead();
- return init_ok;
-}
-
-void cmmm_gpu_clear() {
- CMMMMF.clear();
-}
-
-int** cmmm_gpu_compute_n(const int ago, const int inum_full,
- const int nall, double **host_x, int *host_type,
- double *sublo, double *subhi, int *tag, int **nspecial,
- int **special, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- int **ilist, int **jnum, const double cpu_time,
- bool &success, double *host_q, double *boxlo,
- double *prd) {
- return CMMMMF.compute(ago, inum_full, nall, host_x, host_type, sublo,
- subhi, tag, nspecial, special, eflag, vflag, eatom,
- vatom, host_start, ilist, jnum, cpu_time, success,
- host_q, boxlo, prd);
-}
-
-void cmmm_gpu_compute(const int ago, const int inum_full, const int nall,
- double **host_x, int *host_type, int *ilist, int *numj,
- int **firstneigh, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- const double cpu_time, bool &success, double *host_q,
- const int nlocal, double *boxlo, double *prd) {
- CMMMMF.compute(ago,inum_full,nall,host_x,host_type,ilist,numj,
- firstneigh,eflag,vflag,eatom,vatom,host_start,cpu_time,success,
- host_q,nlocal,boxlo,prd);
-}
-
-double cmmm_gpu_bytes() {
- return CMMMMF.host_memory_usage();
-}
-
-
diff --git a/lib/gpu/lal_device.cpp b/lib/gpu/lal_device.cpp
index 143b0d0c2..675412845 100644
--- a/lib/gpu/lal_device.cpp
+++ b/lib/gpu/lal_device.cpp
@@ -1,640 +1,640 @@
/***************************************************************************
device.cpp
-------------------
W. Michael Brown (ORNL)
Class for management of the device where the computations are performed
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#include "lal_device.h"
#include "lal_precision.h"
#include <map>
#include <math.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#ifdef USE_OPENCL
#include "device_cl.h"
#else
#include "device_ptx.h"
#endif
using namespace LAMMPS_AL;
#define DeviceT Device<numtyp, acctyp>
template <class numtyp, class acctyp>
DeviceT::Device() : _init_count(0), _device_init(false),
_gpu_mode(GPU_FORCE), _first_device(0),
_last_device(0), _compiled(false) {
}
template <class numtyp, class acctyp>
DeviceT::~Device() {
clear_device();
}
template <class numtyp, class acctyp>
int DeviceT::init_device(MPI_Comm world, MPI_Comm replica,
const int first_gpu, const int last_gpu,
const int gpu_mode, const double p_split,
const int nthreads, const int t_per_atom) {
_nthreads=nthreads;
#ifdef _OPENMP
omp_set_num_threads(nthreads);
#endif
_threads_per_atom=t_per_atom;
_threads_per_charge=t_per_atom;
if (_device_init)
return 0;
_device_init=true;
_comm_world=world;
_comm_replica=replica;
_first_device=first_gpu;
_last_device=last_gpu;
_gpu_mode=gpu_mode;
_particle_split=p_split;
// Get the rank/size within the world
MPI_Comm_rank(_comm_world,&_world_me);
MPI_Comm_size(_comm_world,&_world_size);
// Get the rank/size within the replica
MPI_Comm_rank(_comm_replica,&_replica_me);
MPI_Comm_size(_comm_replica,&_replica_size);
// Get the names of all nodes
int name_length;
char node_name[MPI_MAX_PROCESSOR_NAME];
char node_names[MPI_MAX_PROCESSOR_NAME*_world_size];
MPI_Get_processor_name(node_name,&name_length);
MPI_Allgather(&node_name,MPI_MAX_PROCESSOR_NAME,MPI_CHAR,&node_names,
MPI_MAX_PROCESSOR_NAME,MPI_CHAR,_comm_world);
std::string node_string=std::string(node_name);
// Get the number of procs per node
std::map<std::string,int> name_map;
std::map<std::string,int>::iterator np;
for (int i=0; i<_world_size; i++) {
std::string i_string=std::string(&node_names[i*MPI_MAX_PROCESSOR_NAME]);
np=name_map.find(i_string);
if (np==name_map.end())
name_map[i_string]=1;
else
np->second++;
}
int procs_per_node=name_map.begin()->second;
// Assign a unique id to each node
int split_num=0, split_id=0;
for (np=name_map.begin(); np!=name_map.end(); ++np) {
if (np->first==node_string)
split_id=split_num;
split_num++;
}
// Set up a per node communicator and find rank within
MPI_Comm node_comm;
MPI_Comm_split(_comm_world, split_id, 0, &node_comm);
int node_rank;
MPI_Comm_rank(node_comm,&node_rank);
// set the device ID
_procs_per_gpu=static_cast<int>(ceil(static_cast<double>(procs_per_node)/
(last_gpu-first_gpu+1)));
int my_gpu=node_rank/_procs_per_gpu+first_gpu;
// Time on the device only if 1 proc per gpu
_time_device=true;
if (_procs_per_gpu>1)
_time_device=false;
// Set up a per device communicator
MPI_Comm_split(node_comm,my_gpu,0,&_comm_gpu);
MPI_Comm_rank(_comm_gpu,&_gpu_rank);
gpu=new UCL_Device();
if (my_gpu>=gpu->num_devices())
return -2;
if (_procs_per_gpu>1 && gpu->sharing_supported(my_gpu)==false)
return -7;
if (gpu->set(my_gpu)!=UCL_SUCCESS)
return -6;
_long_range_precompute=0;
int flag=compile_kernels();
return flag;
}
template <class numtyp, class acctyp>
int DeviceT::init(Answer<numtyp,acctyp> &ans, const bool charge,
const bool rot, const int nlocal,
const int host_nlocal, const int nall,
Neighbor *nbor, const int maxspecial,
const int gpu_host, const int max_nbors,
const double cell_size, const bool pre_cut,
const int threads_per_atom) {
if (!_device_init)
return -1;
if (sizeof(acctyp)==sizeof(double) && gpu->double_precision()==false)
return -5;
// Counts of data transfers for timing overhead estimates
_data_in_estimate=0;
_data_out_estimate=1;
// Initial number of local particles
int ef_nlocal=nlocal;
if (_particle_split<1.0 && _particle_split>0.0)
ef_nlocal=static_cast<int>(_particle_split*nlocal);
int gpu_nbor=0;
if (_gpu_mode==Device<numtyp,acctyp>::GPU_NEIGH)
gpu_nbor=1;
else if (_gpu_mode==Device<numtyp,acctyp>::GPU_HYB_NEIGH)
gpu_nbor=2;
#ifndef USE_CUDPP
if (gpu_nbor==1)
gpu_nbor=2;
#endif
if (_init_count==0) {
// Initialize atom and nbor data
if (!atom.init(nall,charge,rot,*gpu,gpu_nbor,gpu_nbor>0 && maxspecial>0))
return -3;
_data_in_estimate++;
if (charge)
_data_in_estimate++;
if (rot)
_data_in_estimate++;
} else {
if (atom.charge()==false && charge)
_data_in_estimate++;
if (atom.quat()==false && rot)
_data_in_estimate++;
if (!atom.add_fields(charge,rot,gpu_nbor,gpu_nbor>0 && maxspecial))
return -3;
}
if (!ans.init(ef_nlocal,charge,rot,*gpu))
return -3;
if (!nbor->init(&_neighbor_shared,ef_nlocal,host_nlocal,max_nbors,maxspecial,
*gpu,gpu_nbor,gpu_host,pre_cut, _block_cell_2d,
_block_cell_id, _block_nbor_build, threads_per_atom,
_time_device))
return -3;
nbor->cell_size(cell_size);
_init_count++;
return 0;
}
template <class numtyp, class acctyp>
int DeviceT::init(Answer<numtyp,acctyp> &ans, const int nlocal,
const int nall) {
if (!_device_init)
return -1;
if (sizeof(acctyp)==sizeof(double) && gpu->double_precision()==false)
return -5;
if (_init_count==0) {
// Initialize atom and nbor data
if (!atom.init(nall,true,false,*gpu,false,false))
return -3;
} else
if (!atom.add_fields(true,false,false,false))
return -3;
if (!ans.init(nlocal,true,false,*gpu))
return -3;
_init_count++;
return 0;
}
template <class numtyp, class acctyp>
void DeviceT::set_single_precompute
(PPPM<numtyp,acctyp,float,_lgpu_float4> *pppm) {
_long_range_precompute=1;
pppm_single=pppm;
}
template <class numtyp, class acctyp>
void DeviceT::set_double_precompute
(PPPM<numtyp,acctyp,double,_lgpu_double4> *pppm) {
_long_range_precompute=2;
pppm_double=pppm;
}
template <class numtyp, class acctyp>
void DeviceT::init_message(FILE *screen, const char *name,
const int first_gpu, const int last_gpu) {
#ifdef USE_OPENCL
std::string fs="";
#else
std::string fs=toa(gpu->free_gigabytes())+"/";
#endif
if (_replica_me == 0 && screen) {
fprintf(screen,"\n-------------------------------------");
fprintf(screen,"-------------------------------------\n");
fprintf(screen,"- Using GPGPU acceleration for %s:\n",name);
fprintf(screen,"- with %d proc(s) per device.\n",_procs_per_gpu);
#ifdef _OPENMP
fprintf(screen,"- with %d thread(s) per proc.\n",_nthreads);
#endif
#ifdef USE_OPENCL
fprintf(screen,"- with OpenCL Parameters for: %s\n",OCL_VENDOR);
#endif
fprintf(screen,"-------------------------------------");
fprintf(screen,"-------------------------------------\n");
int last=last_gpu+1;
if (last>gpu->num_devices())
last=gpu->num_devices();
for (int i=first_gpu; i<last; i++) {
std::string sname;
if (i==first_gpu)
sname=gpu->name(i)+", "+toa(gpu->cores(i))+" cores, "+fs+
toa(gpu->gigabytes(i))+" GB, "+toa(gpu->clock_rate(i))+" GHZ (";
else
sname=gpu->name(i)+", "+toa(gpu->cores(i))+" cores, "+fs+
toa(gpu->clock_rate(i))+" GHZ (";
if (sizeof(PRECISION)==4) {
if (sizeof(ACC_PRECISION)==4)
sname+="Single Precision)";
else
sname+="Mixed Precision)";
} else
sname+="Double Precision)";
fprintf(screen,"GPU %d: %s\n",i,sname.c_str());
}
fprintf(screen,"-------------------------------------");
fprintf(screen,"-------------------------------------\n\n");
}
}
template <class numtyp, class acctyp>
void DeviceT::estimate_gpu_overhead(const int kernel_calls,
double &gpu_overhead,
double &gpu_driver_overhead) {
UCL_H_Vec<int> *host_data_in=NULL, *host_data_out=NULL;
UCL_D_Vec<int> *dev_data_in=NULL, *dev_data_out=NULL, *kernel_data=NULL;
UCL_Timer *timers_in=NULL, *timers_out=NULL, *timers_kernel=NULL;
UCL_Timer over_timer(*gpu);
if (_data_in_estimate>0) {
host_data_in=new UCL_H_Vec<int>[_data_in_estimate];
dev_data_in=new UCL_D_Vec<int>[_data_in_estimate];
timers_in=new UCL_Timer[_data_in_estimate];
}
if (_data_out_estimate>0) {
host_data_out=new UCL_H_Vec<int>[_data_out_estimate];
dev_data_out=new UCL_D_Vec<int>[_data_out_estimate];
timers_out=new UCL_Timer[_data_out_estimate];
}
if (kernel_calls>0) {
kernel_data=new UCL_D_Vec<int>[kernel_calls];
timers_kernel=new UCL_Timer[kernel_calls];
}
for (int i=0; i<_data_in_estimate; i++) {
host_data_in[i].alloc(1,*gpu);
dev_data_in[i].alloc(1,*gpu);
timers_in[i].init(*gpu);
}
for (int i=0; i<_data_out_estimate; i++) {
host_data_out[i].alloc(1,*gpu);
dev_data_out[i].alloc(1,*gpu);
timers_out[i].init(*gpu);
}
for (int i=0; i<kernel_calls; i++) {
kernel_data[i].alloc(1,*gpu);
timers_kernel[i].init(*gpu);
}
gpu_overhead=0.0;
gpu_driver_overhead=0.0;
for (int i=0; i<10; i++) {
gpu->sync();
gpu_barrier();
over_timer.start();
gpu->sync();
gpu_barrier();
double driver_time=MPI_Wtime();
for (int i=0; i<_data_in_estimate; i++) {
timers_in[i].start();
ucl_copy(dev_data_in[i],host_data_in[i],true);
timers_in[i].stop();
}
for (int i=0; i<kernel_calls; i++) {
timers_kernel[i].start();
zero(kernel_data[i],1);
timers_kernel[i].stop();
}
for (int i=0; i<_data_out_estimate; i++) {
timers_out[i].start();
ucl_copy(host_data_out[i],dev_data_out[i],true);
timers_out[i].stop();
}
over_timer.stop();
double time=over_timer.seconds();
driver_time=MPI_Wtime()-driver_time;
if (time_device()) {
for (int i=0; i<_data_in_estimate; i++)
timers_in[i].add_to_total();
for (int i=0; i<kernel_calls; i++)
timers_kernel[i].add_to_total();
for (int i=0; i<_data_out_estimate; i++)
timers_out[i].add_to_total();
}
double mpi_time, mpi_driver_time;
MPI_Allreduce(&time,&mpi_time,1,MPI_DOUBLE,MPI_MAX,gpu_comm());
MPI_Allreduce(&driver_time,&mpi_driver_time,1,MPI_DOUBLE,MPI_MAX,gpu_comm());
gpu_overhead+=mpi_time;
gpu_driver_overhead+=mpi_driver_time;
}
gpu_overhead/=10.0;
gpu_driver_overhead/=10.0;
if (_data_in_estimate>0) {
delete [] host_data_in;
delete [] dev_data_in;
delete [] timers_in;
}
if (_data_out_estimate>0) {
delete [] host_data_out;
delete [] dev_data_out;
delete [] timers_out;
}
if (kernel_calls>0) {
delete [] kernel_data;
delete [] timers_kernel;
}
}
template <class numtyp, class acctyp>
void DeviceT::output_times(UCL_Timer &time_pair,
Answer<numtyp,acctyp> &ans,
Neighbor &nbor, const double avg_split,
const double max_bytes,
const double gpu_overhead,
const double driver_overhead,
const int threads_per_atom, FILE *screen) {
double single[9], times[9];
single[0]=atom.transfer_time()+ans.transfer_time();
single[1]=nbor.time_nbor.total_seconds()+nbor.time_hybrid1.total_seconds()+
nbor.time_hybrid2.total_seconds();
single[2]=nbor.time_kernel.total_seconds();
single[3]=time_pair.total_seconds();
single[4]=atom.cast_time()+ans.cast_time();
single[5]=gpu_overhead;
single[6]=driver_overhead;
single[7]=ans.cpu_idle_time();
single[8]=nbor.bin_time();
MPI_Reduce(single,times,9,MPI_DOUBLE,MPI_SUM,0,_comm_replica);
double my_max_bytes=max_bytes+atom.max_gpu_bytes();
double mpi_max_bytes;
MPI_Reduce(&my_max_bytes,&mpi_max_bytes,1,MPI_DOUBLE,MPI_MAX,0,_comm_replica);
double max_mb=mpi_max_bytes/(1024.0*1024.0);
if (replica_me()==0)
if (screen && times[5]>0.0) {
fprintf(screen,"\n\n-------------------------------------");
fprintf(screen,"--------------------------------\n");
fprintf(screen," GPU Time Info (average): ");
fprintf(screen,"\n-------------------------------------");
fprintf(screen,"--------------------------------\n");
if (time_device()) {
fprintf(screen,"Data Transfer: %.4f s.\n",times[0]/_replica_size);
fprintf(screen,"Data Cast/Pack: %.4f s.\n",times[4]/_replica_size);
fprintf(screen,"Neighbor copy: %.4f s.\n",times[1]/_replica_size);
if (nbor.gpu_nbor()>0)
fprintf(screen,"Neighbor build: %.4f s.\n",times[2]/_replica_size);
else
fprintf(screen,"Neighbor unpack: %.4f s.\n",times[2]/_replica_size);
fprintf(screen,"Force calc: %.4f s.\n",times[3]/_replica_size);
}
if (nbor.gpu_nbor()==2)
fprintf(screen,"Neighbor (CPU): %.4f s.\n",times[8]/_replica_size);
fprintf(screen,"GPU Overhead: %.4f s.\n",times[5]/_replica_size);
fprintf(screen,"Average split: %.4f.\n",avg_split);
fprintf(screen,"Threads / atom: %d.\n",threads_per_atom);
fprintf(screen,"Max Mem / Proc: %.2f MB.\n",max_mb);
fprintf(screen,"CPU Driver_Time: %.4f s.\n",times[6]/_replica_size);
fprintf(screen,"CPU Idle_Time: %.4f s.\n",times[7]/_replica_size);
fprintf(screen,"-------------------------------------");
fprintf(screen,"--------------------------------\n\n");
}
}
template <class numtyp, class acctyp>
void DeviceT::output_kspace_times(UCL_Timer &time_in,
UCL_Timer &time_out,
UCL_Timer &time_map,
UCL_Timer &time_rho,
UCL_Timer &time_interp,
Answer<numtyp,acctyp> &ans,
const double max_bytes,
const double cpu_time,
const double idle_time, FILE *screen) {
double single[8], times[8];
single[0]=time_out.total_seconds();
single[1]=time_in.total_seconds()+atom.transfer_time()+atom.cast_time();
single[2]=time_map.total_seconds();
single[3]=time_rho.total_seconds();
single[4]=time_interp.total_seconds();
single[5]=ans.transfer_time()+ans.cast_time();
single[6]=cpu_time;
single[7]=idle_time;
MPI_Reduce(single,times,8,MPI_DOUBLE,MPI_SUM,0,_comm_replica);
double my_max_bytes=max_bytes+atom.max_gpu_bytes();
double mpi_max_bytes;
MPI_Reduce(&my_max_bytes,&mpi_max_bytes,1,MPI_DOUBLE,MPI_MAX,0,_comm_replica);
double max_mb=mpi_max_bytes/(1024.0*1024.0);
if (replica_me()==0)
if (screen && times[6]>0.0) {
fprintf(screen,"\n\n-------------------------------------");
fprintf(screen,"--------------------------------\n");
fprintf(screen," GPU Time Info (average): ");
fprintf(screen,"\n-------------------------------------");
fprintf(screen,"--------------------------------\n");
if (time_device()) {
fprintf(screen,"Data Out: %.4f s.\n",times[0]/_replica_size);
fprintf(screen,"Data In: %.4f s.\n",times[1]/_replica_size);
fprintf(screen,"Kernel (map): %.4f s.\n",times[2]/_replica_size);
fprintf(screen,"Kernel (rho): %.4f s.\n",times[3]/_replica_size);
fprintf(screen,"Force interp: %.4f s.\n",times[4]/_replica_size);
fprintf(screen,"Total rho: %.4f s.\n",
(times[0]+times[2]+times[3])/_replica_size);
fprintf(screen,"Total interp: %.4f s.\n",
(times[1]+times[4])/_replica_size);
fprintf(screen,"Force copy/cast: %.4f s.\n",times[5]/_replica_size);
fprintf(screen,"Total: %.4f s.\n",
(times[0]+times[1]+times[2]+times[3]+times[4]+times[5])/
_replica_size);
}
fprintf(screen,"CPU Poisson: %.4f s.\n",times[6]/_replica_size);
fprintf(screen,"CPU Idle Time: %.4f s.\n",times[7]/_replica_size);
fprintf(screen,"Max Mem / Proc: %.2f MB.\n",max_mb);
fprintf(screen,"-------------------------------------");
fprintf(screen,"--------------------------------\n\n");
}
}
template <class numtyp, class acctyp>
void DeviceT::clear() {
if (_init_count>0) {
_long_range_precompute=0;
_init_count--;
if (_init_count==0) {
atom.clear();
_neighbor_shared.clear();
- if (_compiled) {
- k_zero.clear();
- k_info.clear();
- delete dev_program;
- _compiled=false;
- }
}
}
}
template <class numtyp, class acctyp>
void DeviceT::clear_device() {
while (_init_count>0)
clear();
+ if (_compiled) {
+ k_zero.clear();
+ k_info.clear();
+ delete dev_program;
+ _compiled=false;
+ }
if (_device_init) {
delete gpu;
_device_init=false;
}
}
template <class numtyp, class acctyp>
int DeviceT::compile_kernels() {
int flag=0;
if (_compiled)
return flag;
std::string flags="-cl-mad-enable -D"+std::string(OCL_VENDOR);
dev_program=new UCL_Program(*gpu);
int success=dev_program->load_string(device,flags.c_str());
if (success!=UCL_SUCCESS)
return -4;
k_zero.set_function(*dev_program,"kernel_zero");
k_info.set_function(*dev_program,"kernel_info");
_compiled=true;
UCL_H_Vec<int> h_gpu_lib_data(14,*gpu,UCL_NOT_PINNED);
UCL_D_Vec<int> d_gpu_lib_data(14,*gpu);
k_info.set_size(1,1);
k_info.run(&d_gpu_lib_data.begin());
ucl_copy(h_gpu_lib_data,d_gpu_lib_data,false);
_ptx_arch=static_cast<double>(h_gpu_lib_data[0])/100.0;
#ifndef USE_OPENCL
if (_ptx_arch>gpu->arch())
return -4;
#endif
_num_mem_threads=h_gpu_lib_data[1];
_warp_size=h_gpu_lib_data[2];
if (_threads_per_atom<1)
_threads_per_atom=h_gpu_lib_data[3];
if (_threads_per_charge<1)
_threads_per_charge=h_gpu_lib_data[13];
_pppm_max_spline=h_gpu_lib_data[4];
_pppm_block=h_gpu_lib_data[5];
_block_pair=h_gpu_lib_data[6];
_max_shared_types=h_gpu_lib_data[7];
_block_cell_2d=h_gpu_lib_data[8];
_block_cell_id=h_gpu_lib_data[9];
_block_nbor_build=h_gpu_lib_data[10];
_block_bio_pair=h_gpu_lib_data[11];
_max_bio_shared_types=h_gpu_lib_data[12];
if (static_cast<size_t>(_block_pair)>gpu->group_size())
_block_pair=gpu->group_size();
if (static_cast<size_t>(_block_bio_pair)>gpu->group_size())
_block_bio_pair=gpu->group_size();
if (_threads_per_atom>_warp_size)
_threads_per_atom=_warp_size;
if (_warp_size%_threads_per_atom!=0)
_threads_per_atom=1;
if (_threads_per_atom & (_threads_per_atom - 1))
_threads_per_atom=1;
if (_threads_per_charge>_warp_size)
_threads_per_charge=_warp_size;
if (_warp_size%_threads_per_charge!=0)
_threads_per_charge=1;
if (_threads_per_charge & (_threads_per_charge - 1))
_threads_per_charge=1;
return flag;
}
template <class numtyp, class acctyp>
double DeviceT::host_memory_usage() const {
return atom.host_memory_usage()+4*sizeof(numtyp)+
sizeof(Device<numtyp,acctyp>);
}
template class Device<PRECISION,ACC_PRECISION>;
Device<PRECISION,ACC_PRECISION> global_device;
int lmp_init_device(MPI_Comm world, MPI_Comm replica, const int first_gpu,
const int last_gpu, const int gpu_mode,
const double particle_split, const int nthreads,
const int t_per_atom) {
return global_device.init_device(world,replica,first_gpu,last_gpu,gpu_mode,
particle_split,nthreads,t_per_atom);
}
void lmp_clear_device() {
global_device.clear_device();
}
double lmp_gpu_forces(double **f, double **tor, double *eatom,
double **vatom, double *virial, double &ecoul) {
return global_device.fix_gpu(f,tor,eatom,vatom,virial,ecoul);
}
diff --git a/lib/gpu/lal_neighbor_gpu.cu b/lib/gpu/lal_neighbor_gpu.cu
index 29007abe8..36cd8c42f 100644
--- a/lib/gpu/lal_neighbor_gpu.cu
+++ b/lib/gpu/lal_neighbor_gpu.cu
@@ -1,277 +1,277 @@
// **************************************************************************
// neighbor_gpu.cu
// -------------------
// Peng Wang (Nvidia)
// W. Michael Brown (ORNL)
//
// Device code for handling GPU generated neighbor lists
//
// __________________________________________________________________________
// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
// __________________________________________________________________________
//
// begin :
// email : penwang@nvidia.com, brownw@ornl.gov
// ***************************************************************************/
#ifdef NV_KERNEL
#include "lal_preprocessor.h"
texture<float4> neigh_tex;
#ifndef _DOUBLE_DOUBLE
ucl_inline float4 fetch_pos(const int& i, const float4 *pos)
{ return tex1Dfetch(neigh_tex, i); }
#endif
__kernel void calc_cell_id(numtyp4 *pos, unsigned *cell_id, int *particle_id,
numtyp boxlo0,
numtyp boxlo1, numtyp boxlo2, numtyp boxhi0,
numtyp boxhi1, numtyp boxhi2, numtyp cell_size,
int ncellx, int ncelly, int nall) {
int i = threadIdx.x + blockIdx.x*blockDim.x;
if (i < nall) {
numtyp4 p = fetch_pos(i,pos); //pos[i];
p.x -= boxlo0;
p.y -= boxlo1;
p.z -= boxlo2;
p.x = fmaxf(p.x, -cell_size);
p.x = fminf(p.x, boxhi0-boxlo0+cell_size);
p.y = fmaxf(p.y, -cell_size);
p.y = fminf(p.y, boxhi1-boxlo1+cell_size);
p.z = fmaxf(p.z, -cell_size);
p.z = fminf(p.z, boxhi2-boxlo2+cell_size);
unsigned int id = (unsigned int)(p.x/cell_size + 1.0)
+ (unsigned int)(p.y/cell_size + 1.0) * ncellx
+ (unsigned int)(p.z/cell_size + 1.0) * ncellx * ncelly;
cell_id[i] = id;
particle_id[i] = i;
}
}
__kernel void kernel_calc_cell_counts(unsigned *cell_id,
int *cell_counts, int nall, int ncell) {
int idx = threadIdx.x + blockIdx.x * blockDim.x;
if (idx < nall) {
int id = cell_id[idx];
// handle boundary cases
if (idx == 0) {
for (int i = 0; i < id + 1; i++)
cell_counts[i] = 0;
}
if (idx == nall - 1) {
for (int i = id+1; i <= ncell; i++)
cell_counts[i] = nall;
}
if (idx > 0 && idx < nall) {
int id_l = cell_id[idx-1];
if (id != id_l) {
for (int i = id_l+1; i <= id; i++)
cell_counts[i] = idx;
}
}
}
}
#endif
__kernel void transpose(__global int *out, __global int *in, int columns_in,
int rows_in)
{
__local float block[BLOCK_CELL_2D][BLOCK_CELL_2D+1];
unsigned ti=THREAD_ID_X;
unsigned tj=THREAD_ID_Y;
unsigned bi=BLOCK_ID_X;
unsigned bj=BLOCK_ID_Y;
unsigned i=bi*BLOCK_CELL_2D+ti;
unsigned j=bj*BLOCK_CELL_2D+tj;
if ((i<columns_in) && (j<rows_in))
block[tj][ti]=in[j*columns_in+i];
__syncthreads();
i=bj*BLOCK_CELL_2D+ti;
j=bi*BLOCK_CELL_2D+tj;
if ((i<rows_in) && (j<columns_in))
out[j*rows_in+i] = block[ti][tj];
}
__kernel void calc_neigh_list_cell(__global numtyp4 *x_,
__global int *cell_particle_id,
__global int *cell_counts,
__global int *nbor_list,
__global int *host_nbor_list,
__global int *host_numj,
int neigh_bin_size, numtyp cell_size,
int ncellx, int ncelly, int ncellz,
int inum, int nt, int nall, int t_per_atom)
{
int tid = THREAD_ID_X;
int ix = BLOCK_ID_X;
int iy = BLOCK_ID_Y % ncelly;
int iz = BLOCK_ID_Y / ncelly;
int icell = ix + iy*ncellx + iz*ncellx*ncelly;
__local int cell_list_sh[BLOCK_NBOR_BUILD];
__local numtyp4 pos_sh[BLOCK_NBOR_BUILD];
int icell_begin = cell_counts[icell];
int icell_end = cell_counts[icell+1];
int nborz0 = max(iz-1,0), nborz1 = min(iz+1, ncellz-1),
nbory0 = max(iy-1,0), nbory1 = min(iy+1, ncelly-1),
nborx0 = max(ix-1,0), nborx1 = min(ix+1, ncellx-1);
numtyp4 diff;
numtyp r2;
int cap=ucl_ceil((numtyp)(icell_end - icell_begin)/BLOCK_SIZE_X);
for (int ii = 0; ii < cap; ii++) {
int i = icell_begin + tid + ii*BLOCK_SIZE_X;
int pid_i = nall, pid_j, stride;
numtyp4 atom_i, atom_j;
int cnt = 0;
__global int *neigh_counts, *neigh_list;
if (i < icell_end)
pid_i = cell_particle_id[i];
if (pid_i < nt) {
atom_i = fetch_pos(pid_i,x_); //pos[pid_i];
}
if (pid_i < inum) {
stride=inum;
neigh_counts=nbor_list+stride+pid_i;
neigh_list=neigh_counts+stride+pid_i*(t_per_atom-1);
stride=stride*t_per_atom-t_per_atom;
nbor_list[pid_i]=pid_i;
} else {
stride=0;
neigh_counts=host_numj+pid_i-inum;
neigh_list=host_nbor_list+(pid_i-inum)*neigh_bin_size;
}
// loop through neighbors
for (int nborz = nborz0; nborz <= nborz1; nborz++) {
for (int nbory = nbory0; nbory <= nbory1; nbory++) {
for (int nborx = nborx0; nborx <= nborx1; nborx++) {
int jcell = nborx + nbory*ncellx + nborz*ncellx*ncelly;
int jcell_begin = cell_counts[jcell];
int jcell_end = cell_counts[jcell+1];
int num_atom_cell = jcell_end - jcell_begin;
// load jcell to shared memory
int num_iter = ucl_ceil((numtyp)num_atom_cell/BLOCK_NBOR_BUILD);
for (int k = 0; k < num_iter; k++) {
int end_idx = min(BLOCK_NBOR_BUILD,
num_atom_cell-k*BLOCK_NBOR_BUILD);
if (tid < end_idx) {
pid_j = cell_particle_id[tid+k*BLOCK_NBOR_BUILD+jcell_begin];
cell_list_sh[tid] = pid_j;
atom_j = fetch_pos(pid_j,x_); //[pid_j];
pos_sh[tid].x = atom_j.x;
pos_sh[tid].y = atom_j.y;
pos_sh[tid].z = atom_j.z;
}
__syncthreads();
if (pid_i < nt) {
for (int j = 0; j < end_idx; j++) {
int pid_j = cell_list_sh[j]; // gather from shared memory
diff.x = atom_i.x - pos_sh[j].x;
diff.y = atom_i.y - pos_sh[j].y;
diff.z = atom_i.z - pos_sh[j].z;
r2 = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z;
if (r2 < cell_size*cell_size && r2 > 1e-5) {
cnt++;
- if (cnt < neigh_bin_size) {
+ if (cnt <= neigh_bin_size) {
*neigh_list = pid_j;
neigh_list++;
if ((cnt & (t_per_atom-1))==0)
neigh_list=neigh_list+stride;
}
}
}
}
__syncthreads();
} // for (k)
}
}
}
if (pid_i < nt)
*neigh_counts = cnt;
} // for (i)
}
__kernel void kernel_special(__global int *dev_nbor,
__global int *host_nbor_list,
__global int *host_numj, __global int *tag,
__global int *nspecial, __global int *special,
int inum, int nt, int max_nbors, int t_per_atom) {
int tid=THREAD_ID_X;
int ii=fast_mul((int)BLOCK_ID_X,(int)(BLOCK_SIZE_X)/t_per_atom);
ii+=tid/t_per_atom;
int offset=tid & (t_per_atom-1);
if (ii<nt) {
int stride;
__global int *list, *list_end;
int n1=nspecial[ii*3];
int n2=nspecial[ii*3+1];
int n3=nspecial[ii*3+2];
int numj;
if (ii < inum) {
stride=inum;
list=dev_nbor+stride+ii;
numj=*list;
list+=stride+fast_mul(ii,t_per_atom-1);
stride=fast_mul(inum,t_per_atom);
int njt=numj/t_per_atom;
list_end=list+fast_mul(njt,stride)+(numj & (t_per_atom-1));
list+=offset;
} else {
stride=1;
list=host_nbor_list+(ii-inum)*max_nbors;
numj=host_numj[ii-inum];
list_end=list+fast_mul(numj,stride);
}
for ( ; list<list_end; list+=stride) {
int nbor=*list;
int jtag=tag[nbor];
int offset=ii;
for (int i=0; i<n3; i++) {
if (special[offset]==jtag) {
int which = 1;
if (i>=n1)
which++;
if (i>=n2)
which++;
nbor=nbor ^ (which << SBBITS);
*list=nbor;
}
offset+=nt;
}
}
} // if ii
}
diff --git a/lib/gpu/lal_precision.h b/lib/gpu/lal_precision.h
index 2ba544542..c9ef2b41f 100644
--- a/lib/gpu/lal_precision.h
+++ b/lib/gpu/lal_precision.h
@@ -1,95 +1,102 @@
/***************************************************************************
precision.h
-------------------
W. Michael Brown (ORNL)
Data and preprocessor definitions for different precision modes
__________________________________________________________________________
This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
__________________________________________________________________________
begin :
email : brownw@ornl.gov
***************************************************************************/
#ifndef LAL_PRECISION_H
#define LAL_PRECISION_H
struct _lgpu_float2 {
float x; float y;
};
struct _lgpu_float4 {
float x; float y; float z; float w;
};
struct _lgpu_double2 {
double x; double y;
};
struct _lgpu_double4 {
double x; double y; double z; double w;
};
#include <iostream>
inline std::ostream & operator<<(std::ostream &out, const _lgpu_float2 &v) {
out << v.x << " " << v.y;
return out;
}
inline std::ostream & operator<<(std::ostream &out, const _lgpu_float4 &v) {
out << v.x << " " << v.y << " " << v.z;
return out;
}
inline std::ostream & operator<<(std::ostream &out, const _lgpu_double2 &v) {
out << v.x << " " << v.y;
return out;
}
inline std::ostream & operator<<(std::ostream &out, const _lgpu_double4 &v) {
out << v.x << " " << v.y << " " << v.z;
return out;
}
// PRECISION - Precision for rsq, energy, force, and torque calculation
// ACC_PRECISION - Precision for accumulation of energies, forces, and torques
#ifdef _SINGLE_DOUBLE
#define OCL_PRECISION_COMPILE "-D_SINGLE_DOUBLE"
#define PRECISION float
#define ACC_PRECISION double
#define numtyp2 _lgpu_float2
#define numtyp4 _lgpu_float4
#define acctyp4 _lgpu_double4
#endif
#ifdef _DOUBLE_DOUBLE
#define OCL_PRECISION_COMPILE "-D_DOUBLE_DOUBLE"
#define PRECISION double
#define ACC_PRECISION double
#define numtyp2 _lgpu_double2
#define numtyp4 _lgpu_double4
#define acctyp4 _lgpu_double4
#endif
#ifndef PRECISION
#define OCL_PRECISION_COMPILE "-D_SINGLE_SINGLE"
#define PRECISION float
#define ACC_PRECISION float
#define numtyp2 _lgpu_float2
#define numtyp4 _lgpu_float4
#define acctyp4 _lgpu_float4
#endif
enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE};
+// OCL_VENDOR: preprocessor define for hardware
+// specific sizes of OpenCL kernel related constants
+
#ifdef FERMI_OCL
#define OCL_VENDOR "FERMI_OCL"
#endif
+#ifdef CYPRESS_OCL
+#define OCL_VENDOR "CYPRESS_OCL"
+#endif
+
#ifndef OCL_VENDOR
#define OCL_VENDOR "GENERIC_OCL"
#endif
#endif
diff --git a/lib/gpu/lal_preprocessor.h b/lib/gpu/lal_preprocessor.h
index 28734b343..ea4e2c655 100644
--- a/lib/gpu/lal_preprocessor.h
+++ b/lib/gpu/lal_preprocessor.h
@@ -1,320 +1,355 @@
// **************************************************************************
// preprocessor.cu
// -------------------
// W. Michael Brown (ORNL)
//
// Device code for CUDA-specific preprocessor definitions
//
// __________________________________________________________________________
// This file is part of the LAMMPS Accelerator Library (LAMMPS_AL)
// __________________________________________________________________________
//
// begin :
// email : brownw@ornl.gov
// ***************************************************************************/
//*************************************************************************
// Preprocessor Definitions
//
// Note: It is assumed that constants with the same names are defined with
// the same values in all files.
//
// ARCH
// Definition: Architecture number for accelerator
// MEM_THREADS
// Definition: Number of threads with sequential ids accessing memory
// simultaneously on multiprocessor
// WARP_SIZE:
// Definition: Number of threads guaranteed to be on the same instruction
// THREADS_PER_ATOM
// Definition: Default number of threads assigned per atom for pair styles
// Restructions: Must be power of 2; THREADS_PER_ATOM<=WARP_SIZE
// THREADS_PER_CHARGE
// Definition: Default number of threads assigned per atom for pair styles
// with charge
// Restructions: Must be power of 2; THREADS_PER_ATOM<=WARP_SIZE
// PPPM_MAX_SPLINE
// Definition: Maximum order for splines in PPPM
// PPPM_BLOCK_1D
// Definition: Thread block size for PPPM kernels
// Restrictions: PPPM_BLOCK_1D>=PPPM_MAX_SPLINE*PPPM_MAX_SPLINE
// PPPM_BLOCK_1D%32==0
// BLOCK_PAIR
// Definition: Default thread block size for pair styles
// Restrictions:
// MAX_SHARED_TYPES 8
// Definition: Max # of atom type params can be stored in shared memory
// Restrictions: MAX_SHARED_TYPES*MAX_SHARED_TYPES<=BLOCK_PAIR
// BLOCK_CELL_2D
// Definition: Default block size in each dimension for cell list builds
// and matrix transpose
// BLOCK_CELL_ID
// Definition: Default block size for binning atoms in cell list builds
// BLOCK_NBOR_BUILD
// Definition: Default block size for neighbor list builds
// BLOCK_BIO_PAIR
// Definition: Default thread block size for "bio" pair styles
// MAX_BIO_SHARED_TYPES
// Definition: Max # of atom type params can be stored in shared memory
// Restrictions: MAX_BIO_SHARED_TYPES<=BLOCK_BIO_PAIR*2 &&
// MAX_BIO_SHARED_TYPES>=BLOCK_BIO_PAIR
//
//*************************************************************************/
// -------------------------------------------------------------------------
// CUDA DEFINITIONS
// -------------------------------------------------------------------------
#ifdef NV_KERNEL
#define GLOBAL_ID_X threadIdx.x+mul24(blockIdx.x,blockDim.x)
#define GLOBAL_ID_Y threadIdx.y+mul24(blockIdx.y,blockDim.y)
#define GLOBAL_SIZE_X mul24(gridDim.x,blockDim.x);
#define GLOBAL_SIZE_Y mul24(gridDim.y,blockDim.y);
#define THREAD_ID_X threadIdx.x
#define THREAD_ID_Y threadIdx.y
#define BLOCK_ID_X blockIdx.x
#define BLOCK_ID_Y blockIdx.y
#define BLOCK_SIZE_X blockDim.x
#define BLOCK_SIZE_Y blockDim.y
#define __kernel extern "C" __global__
#define __local __shared__
#define __global
#define atom_add atomicAdd
#define ucl_inline static __inline__ __device__
#ifdef __CUDA_ARCH__
#define ARCH __CUDA_ARCH__
#else
#define ARCH 100
#endif
#if (ARCH < 200)
#define THREADS_PER_ATOM 1
#define THREADS_PER_CHARGE 16
#define BLOCK_NBOR_BUILD 64
#define BLOCK_PAIR 64
#define BLOCK_BIO_PAIR 64
#define MAX_SHARED_TYPES 8
#else
#define THREADS_PER_ATOM 4
#define THREADS_PER_CHARGE 8
#define BLOCK_NBOR_BUILD 128
#define BLOCK_PAIR 128
#define BLOCK_BIO_PAIR 128
#define MAX_SHARED_TYPES 11
#endif
#define WARP_SIZE 32
#define PPPM_BLOCK_1D 64
#define BLOCK_CELL_2D 8
#define BLOCK_CELL_ID 128
#define MAX_BIO_SHARED_TYPES 128
#ifdef _DOUBLE_DOUBLE
ucl_inline double4 fetch_pos(const int& i, const double4 *pos) { return pos[i]; }
ucl_inline double fetch_q(const int& i, const double *q) { return q[i]; }
#endif
#if (__CUDA_ARCH__ < 200)
#define fast_mul __mul24
#define MEM_THREADS 16
#else
#define fast_mul(X,Y) (X)*(Y)
#define MEM_THREADS 32
#endif
#ifdef CUDA_PRE_THREE
struct __builtin_align__(16) _double4
{
double x, y, z, w;
};
typedef struct _double4 double4;
#endif
#ifdef _DOUBLE_DOUBLE
#define ucl_exp exp
#define ucl_powr pow
#define ucl_atan atan
#define ucl_cbrt cbrt
#define ucl_ceil ceil
#define ucl_abs fabs
#define ucl_rsqrt rsqrt
#define ucl_sqrt sqrt
#define ucl_recip(x) ((numtyp)1.0/(x))
#else
#define ucl_atan atanf
#define ucl_cbrt cbrtf
#define ucl_ceil ceilf
#define ucl_abs fabsf
#define ucl_recip(x) ((numtyp)1.0/(x))
#define ucl_rsqrt rsqrtf
#define ucl_sqrt sqrtf
#ifdef NO_HARDWARE_TRANSCENDENTALS
#define ucl_exp expf
#define ucl_powr powf
#else
#define ucl_exp __expf
#define ucl_powr __powf
#endif
#endif
#endif
// -------------------------------------------------------------------------
+<<<<<<< HEAD
// FERMI OPENCL DEFINITIONS
+=======
+// NVIDIA FERMI OPENCL DEFINITIONS
+>>>>>>> ad9fa0e18743a47e42452e38329083e37cb90055
// -------------------------------------------------------------------------
#ifdef FERMI_OCL
#define USE_OPENCL
#define fast_mul(X,Y) (X)*(Y)
#define ARCH 0
#define DRIVER 0
#define MEM_THREADS 32
#define THREADS_PER_ATOM 4
#define THREADS_PER_CHARGE 8
#define BLOCK_PAIR 128
#define MAX_SHARED_TYPES 11
#define BLOCK_NBOR_BUILD 128
#define BLOCK_BIO_PAIR 128
#define WARP_SIZE 32
#define PPPM_BLOCK_1D 64
#define BLOCK_CELL_2D 8
#define BLOCK_CELL_ID 128
#define MAX_BIO_SHARED_TYPES 128
#pragma OPENCL EXTENSION cl_khr_fp64: enable
#endif
// -------------------------------------------------------------------------
+<<<<<<< HEAD
+=======
+// AMD CYPRESS OPENCL DEFINITIONS
+// -------------------------------------------------------------------------
+
+#ifdef CYPRESS_OCL
+
+#define USE_OPENCL
+#define fast_mul(X,Y) (X)*(Y)
+#define ARCH 0
+#define DRIVER 0
+#define MEM_THREADS 32
+#define THREADS_PER_ATOM 4
+#define THREADS_PER_CHARGE 8
+#define BLOCK_PAIR 128
+#define MAX_SHARED_TYPES 8
+#define BLOCK_NBOR_BUILD 64
+#define BLOCK_BIO_PAIR 64
+
+#define WARP_SIZE 64
+#define PPPM_BLOCK_1D 64
+#define BLOCK_CELL_2D 8
+#define BLOCK_CELL_ID 128
+#define MAX_BIO_SHARED_TYPES 128
+
+#pragma OPENCL EXTENSION cl_khr_fp64: enable
+
+#endif
+
+// -------------------------------------------------------------------------
+>>>>>>> ad9fa0e18743a47e42452e38329083e37cb90055
// GENERIC OPENCL DEFINITIONS
// -------------------------------------------------------------------------
#ifdef GENERIC_OCL
#define USE_OPENCL
#define fast_mul mul24
#define ARCH 0
#define DRIVER 0
#define MEM_THREADS 16
#define THREADS_PER_ATOM 1
#define THREADS_PER_CHARGE 1
#define BLOCK_PAIR 64
#define MAX_SHARED_TYPES 8
#define BLOCK_NBOR_BUILD 64
#define BLOCK_BIO_PAIR 64
#define WARP_SIZE 1
#define PPPM_BLOCK_1D 64
#define BLOCK_CELL_2D 8
#define BLOCK_CELL_ID 128
#define MAX_BIO_SHARED_TYPES 128
#pragma OPENCL EXTENSION cl_khr_fp64: enable
#endif
// -------------------------------------------------------------------------
// OPENCL Stuff for All Hardware
// -------------------------------------------------------------------------
#ifdef USE_OPENCL
#define GLOBAL_ID_X get_global_id(0)
#define THREAD_ID_X get_local_id(0)
#define BLOCK_ID_X get_group_id(0)
#define BLOCK_SIZE_X get_local_size(0)
#define GLOBAL_SIZE_X get_global_size(0)
#define THREAD_ID_Y get_local_id(1)
#define BLOCK_ID_Y get_group_id(1)
#define __syncthreads() barrier(CLK_LOCAL_MEM_FENCE)
#define ucl_inline inline
#define fetch_pos(i,y) x_[i]
#define fetch_q(i,y) q_[i]
#define ucl_atan atan
#define ucl_cbrt cbrt
#define ucl_ceil ceil
#define ucl_abs fabs
#ifdef _DOUBLE_DOUBLE
#define NO_HARDWARE_TRANSCENDENTALS
#endif
#ifdef NO_HARDWARE_TRANSCENDENTALS
#define ucl_exp exp
#define ucl_powr powr
#define ucl_rsqrt rsqrt
#define ucl_sqrt sqrt
#define ucl_recip(x) ((numtyp)1.0/(x))
#else
#define ucl_exp native_exp
#define ucl_powr native_powr
#define ucl_rsqrt native_rsqrt
#define ucl_sqrt native_sqrt
#define ucl_recip native_recip
#endif
#endif
// -------------------------------------------------------------------------
// ARCHITECTURE INDEPENDENT DEFINITIONS
// -------------------------------------------------------------------------
#define PPPM_MAX_SPLINE 8
#ifdef _DOUBLE_DOUBLE
#define numtyp double
#define numtyp2 double2
#define numtyp4 double4
#define acctyp double
#define acctyp4 double4
#endif
#ifdef _SINGLE_DOUBLE
#define numtyp float
#define numtyp2 float2
#define numtyp4 float4
#define acctyp double
#define acctyp4 double4
#endif
#ifndef numtyp
#define numtyp float
#define numtyp2 float2
#define numtyp4 float4
#define acctyp float
#define acctyp4 float4
#endif
#define EWALD_F (numtyp)1.12837917
#define EWALD_P (numtyp)0.3275911
#define A1 (numtyp)0.254829592
#define A2 (numtyp)-0.284496736
#define A3 (numtyp)1.421413741
#define A4 (numtyp)-1.453152027
#define A5 (numtyp)1.061405429
#define SBBITS 30
#define NEIGHMASK 0x3FFFFFFF
ucl_inline int sbmask(int j) { return j >> SBBITS & 3; }
diff --git a/lib/gpu/replace_code.sh b/lib/gpu/replace_code.sh
deleted file mode 100755
index a066938ec..000000000
--- a/lib/gpu/replace_code.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/tcsh
-
-set files = `echo *.h *.cu`
-rm -rf /tmp/cpp5678
-mkdir /tmp/cpp5678
-mkdir /tmp/cpp5678/lgpu
-
-foreach file ( $files )
-# /bin/cp $file /tmp/cpp5678/$file:t:t
- # ------ Sed Replace
- sed -i.bak 's/(numtyp)1\.0\/rsq/ucl_recip(rsq)/g' $file
-end
-
diff --git a/lib/meam/Makefile.lammps.glory b/lib/meam/Makefile.lammps.glory
new file mode 100644
index 000000000..153e699b7
--- /dev/null
+++ b/lib/meam/Makefile.lammps.glory
@@ -0,0 +1,5 @@
+# Settings that the LAMMPS build will import when this package library is used
+
+meam_SYSINC =
+meam_SYSLIB = -lifcore -lsvml -lompstub -limf
+meam_SYSPATH = -L/opt/intel-11.1.046/lib/intel64
diff --git a/python/lammps.py b/python/lammps.py
index 5f5ee5263..23abd7f77 100644
--- a/python/lammps.py
+++ b/python/lammps.py
@@ -1,169 +1,169 @@
# ----------------------------------------------------------------------
# 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.
# -------------------------------------------------------------------------
# Python wrapper on LAMMPS library via ctypes
import types
from ctypes import *
LMPINT = 0
LMPDOUBLE = 1
LMPIPTR = 2
LMPDPTR = 3
LMPDPTRPTR = 4
class lammps:
def __init__(self,args=None):
# attempt to load parallel library first, serial library next
# could provide caller a flag to choose which library to load
try:
self.lib = CDLL("_lammps.so")
except:
try:
self.lib = CDLL("_lammps_serial.so")
- except:
- raise StandardError,"Could not load LAMMPS dynamic library"
+ #except:
+ # raise OSError,"Could not load LAMMPS dynamic library"
# create an instance of LAMMPS
# don't know how to pass an MPI communicator from PyPar
# no_mpi call lets LAMMPS use MPI_COMM_WORLD
# cargs = array of C strings from args
if args:
args.insert(0,"lammps.py")
narg = len(args)
cargs = (c_char_p*narg)(*args)
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(narg,cargs,byref(self.lmp))
else:
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(0,None,byref(self.lmp))
# could use just this if LAMMPS lib interface supported it
# self.lmp = self.lib.lammps_open_no_mpi(0,None)
def __del__(self):
if self.lmp: self.lib.lammps_close(self.lmp)
def close(self):
self.lib.lammps_close(self.lmp)
self.lmp = None
def file(self,file):
self.lib.lammps_file(self.lmp,file)
def command(self,cmd):
self.lib.lammps_command(self.lmp,cmd)
def extract_global(self,name,type):
if type == LMPDOUBLE:
self.lib.lammps_extract_global.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_global(self.lmp,name)
return ptr[0]
if type == LMPINT:
self.lib.lammps_extract_global.restype = POINTER(c_int)
ptr = self.lib.lammps_extract_global(self.lmp,name)
return ptr[0]
return None
def extract_atom(self,name,type):
if type == LMPDPTRPTR:
self.lib.lammps_extract_atom.restype = POINTER(POINTER(c_double))
ptr = self.lib.lammps_extract_atom(self.lmp,name)
return ptr
if type == LMPDPTR:
self.lib.lammps_extract_atom.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_atom(self.lmp,name)
return ptr
if type == LMPIPTR:
self.lib.lammps_extract_atom.restype = POINTER(c_int)
ptr = self.lib.lammps_extract_atom(self.lmp,name)
return ptr
return None
def extract_compute(self,id,style,type):
if type == 0:
if style > 0: return None
self.lib.lammps_extract_compute.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
return ptr[0]
elif type == 1:
self.lib.lammps_extract_compute.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
return ptr
elif type == 2:
self.lib.lammps_extract_compute.restype = POINTER(POINTER(c_double))
ptr = self.lib.lammps_extract_compute(self.lmp,id,style,type)
return ptr
return None
# in case of global datum, free memory for 1 double via lammps_free()
# double was allocated by library interface function
def extract_fix(self,id,style,type,i=0,j=0):
if type == 0:
if style > 0: return None
self.lib.lammps_extract_fix.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_bix(self.lmp,id,style,type,i,j)
result = ptr[0]
self.lib.lammps_free(ptr)
return result
elif type == 1:
self.lib.lammps_extract_fix.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,i,j)
return ptr
elif type == 2:
self.lib.lammps_extract_fix.restype = POINTER(POINTER(c_double))
ptr = self.lib.lammps_extract_fix(self.lmp,id,style,type,i,j)
return ptr
return None
# free memory for 1 double or 1 vector of doubles via lammps_free()
# for vector, must copy nlocal returned values to local c_double vector
# memory was allocated by library interface function
def extract_variable(self,name,group,type):
if type == 0:
self.lib.lammps_extract_variable.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_variable(self.lmp,name,group)
result = ptr[0]
self.lib.lammps_free(ptr)
return result
if type == 1:
self.lib.lammps_extract_global.restype = POINTER(c_int)
nlocalptr = self.lib.lammps_extract_global(self.lmp,"nlocal")
nlocal = nlocalptr[0]
result = (c_double*nlocal)()
self.lib.lammps_extract_variable.restype = POINTER(c_double)
ptr = self.lib.lammps_extract_variable(self.lmp,name,group)
for i in xrange(nlocal): result[i] = ptr[i]
self.lib.lammps_free(ptr)
return result
return None
def get_natoms(self):
return self.lib.lammps_get_natoms(self.lmp)
def get_coords(self):
nlen = 3 * self.lib.lammps_get_natoms(self.lmp)
coords = (c_double*nlen)()
self.lib.lammps_get_coords(self.lmp,coords)
return coords
# assume coords is an array of c_double, as created by get_coords()
# could check if it is some other Python object and create c_double array?
# constructor for c_double array can take an arg to use to fill it?
def put_coords(self,coords):
self.lib.lammps_put_coords(self.lmp,coords)
diff --git a/python/setup.py b/python/setup.py
index 80fcfcdb2..072673c02 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -1,39 +1,39 @@
#!/usr/local/bin/python
"""
-setup.py file for LAMMPS with system MPI library
+setup.py file for LAMMPS with system MPICH library
"""
from distutils.core import setup, Extension
import os, glob
path = os.path.dirname(os.getcwd())
# list of src files for LAMMPS
libfiles = glob.glob("%s/src/*.cpp" % path)
lammps_library = Extension("_lammps",
sources = libfiles,
define_macros = [("MPICH_IGNORE_CXX_SEEK",1),
("LAMMPS_GZIP",1),
("FFT_NONE",1),],
# src files for LAMMPS
include_dirs = ["../src"],
# additional libs for MPICH on Linux
- libraries = ["mpich","rt"],
+ libraries = ["mpich","mpl","pthread"],
# where to find the MPICH lib on Linux
library_dirs = ["/usr/local/lib"],
# additional libs for MPI on Mac
# libraries = ["mpi"],
)
setup(name = "lammps",
- version = "26Oct10",
+ version = "28Nov11",
author = "Steve Plimpton",
author_email = "sjplimp@sandia.gov",
url = "http://lammps.sandia.gov",
description = """LAMMPS molecular dynamics library - parallel""",
py_modules = ["lammps"],
ext_modules = [lammps_library]
)
diff --git a/python/setup_serial.py b/python/setup_serial.py
index 425f47062..f06937613 100755
--- a/python/setup_serial.py
+++ b/python/setup_serial.py
@@ -1,34 +1,34 @@
#!/usr/local/bin/python
"""
setup_serial.py file for LAMMPS with dummy serial MPI library
"""
from distutils.core import setup, Extension
import os, glob
path = os.path.dirname(os.getcwd())
# list of src files for LAMMPS and MPI STUBS
libfiles = glob.glob("%s/src/*.cpp" % path) + \
glob.glob("%s/src/STUBS/*.cpp" % path)
lammps_library = Extension("_lammps_serial",
sources = libfiles,
define_macros = [("MPICH_IGNORE_CXX_SEEK",1),
("LAMMPS_GZIP",1),
("FFT_NONE",1),],
# src files for LAMMPS and MPI STUBS
include_dirs = ["../src", "../src/STUBS"]
)
setup(name = "lammps_serial",
- version = "26Oct10",
+ version = "28Nov11",
author = "Steve Plimpton",
author_email = "sjplimp@sandia.gov",
url = "http://lammps.sandia.gov",
description = """LAMMPS molecular dynamics library - serial""",
py_modules = ["lammps"],
ext_modules = [lammps_library]
)
diff --git a/src/GPU/Install.sh b/src/GPU/Install.sh
index a87928aba..1a1d8b9a1 100644
--- a/src/GPU/Install.sh
+++ b/src/GPU/Install.sh
@@ -1,162 +1,140 @@
# Install/unInstall package files in LAMMPS
# edit 2 Makefile.package files to include/exclude GPU info
# do not install child files if parent does not exist
if (test $1 = 1) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*gpu[^ \t]* //' ../Makefile.package
sed -i -e 's|^PKG_PATH =[ \t]*|&-L../../lib/gpu |' ../Makefile.package
sed -i -e 's|^PKG_LIB =[ \t]*|&-lgpu |' ../Makefile.package
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(gpu_SYSINC) |' ../Makefile.package
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(gpu_SYSLIB) |' ../Makefile.package
sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(gpu_SYSPATH) |' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*gpu.*$/d' ../Makefile.package.settings
sed -i '4 i include ..\/..\/lib\/gpu\/Makefile.lammps' ../Makefile.package.settings
fi
if (test -e ../pair_eam.cpp) then
cp pair_eam_gpu.cpp ..
cp pair_eam_gpu.h ..
fi
if (test -e ../pair_gayberne.cpp) then
cp pair_gayberne_gpu.cpp ..
cp pair_gayberne_gpu.h ..
cp pair_resquared_gpu.cpp ..
cp pair_resquared_gpu.h ..
fi
if (test -e ../pair_lj_cut_coul_long.cpp) then
cp pair_lj_cut_coul_long_gpu.cpp ..
cp pair_lj_cut_coul_long_gpu.h ..
fi
if (test -e ../pair_lj_class2.cpp) then
cp pair_lj_class2_gpu.cpp ..
cp pair_lj_class2_gpu.h ..
fi
if (test -e ../pair_lj_class2_coul_long.cpp) then
cp pair_lj_class2_coul_long_gpu.cpp ..
cp pair_lj_class2_coul_long_gpu.h ..
fi
if (test -e ../pair_lj_charmm_coul_long.cpp) then
cp pair_lj_charmm_coul_long_gpu.cpp ..
cp pair_lj_charmm_coul_long_gpu.h ..
fi
if (test -e ../pair_coul_long.cpp) then
cp pair_coul_long_gpu.cpp ..
cp pair_coul_long_gpu.h ..
fi
- if (test -e ../pair_cg_cmm.cpp) then
- cp pair_cg_cmm_gpu.cpp ..
- cp pair_cg_cmm_gpu.h ..
+ if (test -e ../pair_lj_sdk.cpp) then
+ cp pair_lj_sdk_gpu.cpp ..
+ cp pair_lj_sdk_gpu.h ..
fi
- if (test -e ../pair_cg_cmm_coul_long.cpp) then
- cp pair_cg_cmm_coul_long_gpu.cpp ..
- cp pair_cg_cmm_coul_long_gpu.h ..
- cp pair_cg_cmm_coul_msm.cpp ..
- cp pair_cg_cmm_coul_msm.h ..
- cp pair_cg_cmm_coul_msm_gpu.cpp ..
- cp pair_cg_cmm_coul_msm_gpu.h ..
+ if (test -e ../pair_lj_sdk_coul_long.cpp) then
+ cp pair_lj_sdk_coul_long_gpu.cpp ..
+ cp pair_lj_sdk_coul_long_gpu.h ..
fi
if (test -e ../pppm.cpp) then
cp pppm_gpu.cpp ..
cp pppm_gpu.h ..
fi
cp pair_lj_cut_gpu.cpp ..
cp pair_morse_gpu.cpp ..
cp pair_lj96_cut_gpu.cpp ..
cp pair_lj_expand_gpu.cpp ..
cp pair_lj_cut_coul_cut_gpu.cpp ..
- cp pair_lj_cut_tgpu.cpp ..
cp fix_gpu.cpp ..
cp pair_lj_cut_gpu.h ..
cp pair_morse_gpu.h ..
cp pair_lj96_cut_gpu.h ..
cp pair_lj_expand_gpu.h ..
cp pair_lj_cut_coul_cut_gpu.h ..
- cp pair_lj_cut_tgpu.h ..
cp fix_gpu.h ..
cp gpu_extra.h ..
- cp pair_omp_gpu.cpp ..
- cp pair_lj_cut_tgpu.cpp ..
-
- cp pair_omp_gpu.h ..
- cp pair_lj_cut_tgpu.h ..
-
elif (test $1 = 0) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*gpu[^ \t]* //' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*gpu.*$/d' ../Makefile.package.settings
fi
rm -f ../pppm_gpu.cpp
rm -f ../pair_eam_gpu.cpp
rm -f ../pair_gayberne_gpu.cpp
rm -f ../pair_resquared_gpu.cpp
rm -f ../pair_lj_cut_gpu.cpp
rm -f ../pair_morse_gpu.cpp
rm -f ../pair_lj96_cut_gpu.cpp
rm -f ../pair_lj_expand_gpu.cpp
rm -f ../pair_lj_cut_coul_cut_gpu.cpp
rm -f ../pair_lj_cut_coul_long_gpu.cpp
rm -f ../pair_lj_class2_gpu.cpp
rm -f ../pair_lj_class2_coul_long_gpu.cpp
rm -f ../pair_lj_charmm_coul_long_gpu.cpp
- rm -f ../pair_lj_cut_tgpu.cpp
rm -f ../pair_coul_long_gpu.cpp
- rm -f ../pair_cg_cmm_gpu.cpp
- rm -f ../pair_cg_cmm_coul_long_gpu.cpp
- rm -f ../pair_cg_cmm_coul_msm.cpp
- rm -f ../pair_cg_cmm_coul_msm_gpu.cpp
+ rm -f ../pair_lj_sdk_gpu.cpp
+ rm -f ../pair_lj_sdk_coul_long_gpu.cpp
rm -f ../fix_gpu.cpp
- rm -f ../pair_omp_gpu.cpp
- rm -f ../pair_lj_cut_tgpu.cpp
rm -f ../pppm_gpu.h
rm -f ../pair_eam_gpu.h
rm -f ../pair_gayberne_gpu.h
rm -f ../pair_resquared_gpu.h
rm -f ../pair_lj_cut_gpu.h
rm -f ../pair_morse_gpu.h
rm -f ../pair_lj96_cut_gpu.h
rm -f ../pair_lj_expand_gpu.h
rm -f ../pair_lj_cut_coul_cut_gpu.h
rm -f ../pair_lj_cut_coul_long_gpu.h
rm -f ../pair_lj_class2_gpu.h
rm -f ../pair_lj_class2_coul_long_gpu.h
rm -f ../pair_lj_charmm_coul_long_gpu.h
- rm -f ../pair_lj_cut_tgpu.h
rm -f ../pair_coul_long_gpu.h
- rm -f ../pair_cg_cmm_gpu.h
- rm -f ../pair_cg_cmm_coul_long_gpu.h
- rm -f ../pair_cg_cmm_coul_msm.h
- rm -f ../pair_cg_cmm_coul_msm_gpu.h
+ rm -f ../pair_lj_sdk_gpu.h
+ rm -f ../pair_lj_sdk_coul_long_gpu.h
rm -f ../fix_gpu.h
rm -f ../gpu_extra.h
- rm -f ../pair_omp_gpu.h
- rm -f ../pair_lj_cut_tgpu.h
fi
diff --git a/src/GPU/Package.sh b/src/GPU/Package.sh
index 2eb20755e..cb7213c2b 100644
--- a/src/GPU/Package.sh
+++ b/src/GPU/Package.sh
@@ -1,56 +1,44 @@
# Update package files in LAMMPS
# cp package file to src if doesn't exist or is different
# do not copy gayberne files if non-GPU version does not exist
for file in *.cpp *.h; do
if (test $file = pair_gayberne_gpu.cpp -a ! -e ../pair_gayberne.cpp) then
continue
fi
if (test $file = pair_gayberne_gpu.h -a ! -e ../pair_gayberne.cpp) then
continue
fi
if (test $file = pair_lj_cut_coul_long_gpu.cpp -a ! -e ../pair_lj_cut_coul_long.cpp) then
continue
fi
if (test $file = pair_lj_cut_coul_long_gpu.h -a ! -e ../pair_lj_cut_coul_long.cpp) then
continue
fi
if (test $file = pair_coul_long_gpu.cpp -a ! -e ../pair_coul_long.cpp) then
continue
fi
if (test $file = pair_coul_long_gpu.h -a ! -e ../pair_coul_long.cpp) then
continue
fi
if (test $file = pair_cg_cmm_gpu.cpp -a ! -e ../pair_cg_cmm.cpp) then
continue
fi
if (test $file = pair_cg_cmm_gpu.h -a ! -e ../pair_cg_cmm.cpp) then
continue
fi
if (test $file = pair_cg_cmm_coul_long_gpu.cpp -a ! -e ../pair_cg_cmm_coul_long.cpp) then
continue
fi
if (test $file = pair_cg_cmm_coul_long_gpu.h -a ! -e ../pair_cg_cmm_coul_long.cpp) then
continue
fi
- if (test $file = pair_cg_cmm_coul_msm.cpp -a ! -e ../pair_cg_cmm.cpp) then
- continue
- fi
- if (test $file = pair_cg_cmm_coul_msm.h -a ! -e ../pair_cg_cmm.cpp) then
- continue
- fi
- if (test $file = pair_cg_cmm_coul_msm_gpu.cpp -a ! -e ../pair_cg_cmm.cpp) then
- continue
- fi
- if (test $file = pair_cg_cmm_coul_msm_gpu.h -a ! -e ../pair_cg_cmm.cpp) then
- continue
- fi
if (test ! -e ../$file) then
echo " creating src/$file"
cp $file ..
elif (test "`diff --brief $file ../$file`" != "") then
echo " updating src/$file"
cp $file ..
fi
done
diff --git a/src/GPU/pair_cg_cmm_coul_long_gpu.h b/src/GPU/pair_cg_cmm_coul_long_gpu.h
deleted file mode 100644
index 6ce9d635a..000000000
--- a/src/GPU/pair_cg_cmm_coul_long_gpu.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(cg/cmm/coul/long/gpu,PairCGCMMCoulLongGPU)
-
-#else
-
-#ifndef LMP_PAIR_CG_CMM_COUL_LONG_GPU_H
-#define LMP_PAIR_CG_CMM_COUL_LONG_GPU_H
-
-#include "pair_cg_cmm_coul_long.h"
-
-namespace LAMMPS_NS {
-
-class PairCGCMMCoulLongGPU : public PairCGCMMCoulLong {
- public:
- PairCGCMMCoulLongGPU(LAMMPS *lmp);
- ~PairCGCMMCoulLongGPU();
- void cpu_compute(int, int, int, int, int *, int *, int **);
- void compute(int, int);
- void init_style();
- double memory_usage();
-
- enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH };
-
- private:
- int gpu_mode;
- double cpu_time;
- int *gpulist;
-};
-
-}
-#endif
-#endif
-
diff --git a/src/GPU/pair_cg_cmm_coul_msm.cpp b/src/GPU/pair_cg_cmm_coul_msm.cpp
deleted file mode 100644
index 5321945eb..000000000
--- a/src/GPU/pair_cg_cmm_coul_msm.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/* ----------------------------------------------------------------------
- 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.
-------------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------
- CMM coarse grained MD potentials. Coulomb with MSM version.
- Contributing author: Mike Brown <brownw@ornl.gov>
-------------------------------------------------------------------------- */
-
-#include "string.h"
-#include "pair_cg_cmm_coul_msm.h"
-#include "memory.h"
-#include "atom.h"
-#include "force.h"
-#include "kspace.h"
-
-using namespace LAMMPS_NS;
-
-enum {C3=0,C4=1};
-
-/* ---------------------------------------------------------------------- */
-
-PairCGCMMCoulMSM::PairCGCMMCoulMSM(LAMMPS *lmp) : PairCMMCommon(lmp)
-{
- respa_enable = 0;
- single_enable = 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-PairCGCMMCoulMSM::~PairCGCMMCoulMSM()
-{
- if (allocated_coul) {
- memory->destroy(cut_lj);
- memory->destroy(cut_ljsq);
- memory->destroy(cut_coul);
- memory->destroy(cut_coulsq);
- allocated_coul=0;
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::allocate()
-{
- PairCMMCommon::allocate();
- allocated_coul = 1;
-
- int n = atom->ntypes;
-
- memory->create(cut_lj,n+1,n+1,"paircg:cut_lj");
- memory->create(cut_ljsq,n+1,n+1,"paircg:cut_ljsq");
- memory->create(cut_coul,n+1,n+1,"paircg:cut_coul");
- memory->create(cut_coulsq,n+1,n+1,"paircg:cut_coulsq");
-}
-
-/* ----------------------------------------------------------------------
- global settings
-------------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::settings(int narg, char **arg)
-{
- // strip off smoothing type and send args to parent
-
- if (narg < 1) error->all(FLERR,"Illegal pair_style command");
-
- if (strcmp(arg[0],"C3") == 0)
- _smooth = C3;
- else if (strcmp(arg[0],"C4") == 0)
- _smooth = C4;
- else error->all(FLERR,"Illegal pair_style command");
-
- PairCMMCommon::settings(narg-1,&arg[1]);
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::init_style()
-{
- if (!atom->q_flag)
- error->all(FLERR,"Pair style cg/cut/coul/msm requires atom attribute q");
-
- PairCMMCommon::init_style();
- _ia=-1.0/cut_coul_global;
- _ia2=_ia*_ia;
- _ia3=_ia2*_ia;
-
- cut_respa = NULL;
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairCGCMMCoulMSM::init_one(int i, int j)
-{
- double mycut = PairCMMCommon::init_one(i,j);
-
- return mycut;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::compute(int eflag, int vflag)
-{
- int i,j,ii,jj,inum,jnum,itype,jtype,itable;
- double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
- double fraction,table;
- double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
- double grij,expm2,prefactor,t,erfc;
- int *ilist,*jlist,*numneigh,**firstneigh;
- double rsq;
-
- if (eflag || vflag) ev_setup(eflag,vflag);
- else evflag = vflag_fdotr = 0;
-
- double **x = atom->x;
- double **f = atom->f;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
- int newton_pair = force->newton_pair;
-
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
-
- // loop over neighbors of my atoms
-
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- qtmp = q[i];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- factor_lj = special_lj[sbmask(j)];
- factor_coul = special_coul[sbmask(j)];
- j &= NEIGHMASK;
-
- const double delx = xtmp - x[j][0];
- const double dely = ytmp - x[j][1];
- const double delz = ztmp - x[j][2];
- const double rsq = delx*delx + dely*dely + delz*delz;
- const int jtype = type[j];
-
- double evdwl = 0.0;
- double ecoul = 0.0;
- double fpair = 0.0;
-
- if (rsq < cutsq[itype][jtype]) {
- const double r2inv = 1.0/rsq;
- const int cgt=cg_type[itype][jtype];
-
- double forcelj = 0.0;
- double forcecoul = 0.0;
-
- if (rsq < cut_ljsq[itype][jtype]) {
- forcelj=factor_lj;
- if (eflag) evdwl=factor_lj;
-
- if (cgt == CG_LJ12_4) {
- const double r4inv=r2inv*r2inv;
- forcelj *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else if (cgt == CG_LJ9_6) {
- const double r3inv = r2inv*sqrt(r2inv);
- const double r6inv = r3inv*r3inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r3inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r3inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else {
- const double r6inv = r2inv*r2inv*r2inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r6inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r6inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- }
- }
-
- if (rsq < cut_coulsq_global) {
- const double ir = 1.0/sqrt(rsq);
- const double prefactor = qqrd2e * qtmp*q[j];
- const double r2_ia2 = rsq*_ia2;
- const double r4_ia4 = r2_ia2*r2_ia2;
- if (_smooth==C3) {
- forcecoul = prefactor*(_ia3*(-4.375+5.25*r2_ia2-1.875*r4_ia4)-
- ir/rsq);
- if (eflag)
- ecoul = prefactor*(ir+_ia*(2.1875-2.1875*r2_ia2+
- 1.3125*r4_ia4-0.3125*r2_ia2*r4_ia4));
- } else {
- const double r6_ia6 = r2_ia2*r4_ia4;
- forcecoul = prefactor*(_ia3*(-6.5625+11.8125*r2_ia2-8.4375*r4_ia4+
- 2.1875*r6_ia6)-ir/rsq);
- if (eflag)
- ecoul = prefactor*(ir+_ia*(2.4609375-3.28125*r2_ia2+
- 2.953125*r4_ia4-1.40625*r6_ia6+
- 0.2734375*r4_ia4*r4_ia4));
- }
- if (factor_coul < 1.0) {
- forcecoul -= (1.0-factor_coul)*prefactor*ir;
- if (eflag) ecoul -= (1.0-factor_coul)*prefactor*ir;
- }
- }
- fpair = forcecoul + forcelj * r2inv;
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
- if (newton_pair || j < nlocal) {
- f[j][0] -= delx*fpair;
- f[j][1] -= dely*fpair;
- f[j][2] -= delz*fpair;
- }
- if (evflag) ev_tally(i,j,nlocal,newton_pair,
- evdwl,ecoul,fpair,delx,dely,delz);
- }
- }
- }
-
- if (vflag_fdotr) virial_fdotr_compute();
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::write_restart(FILE *fp)
-{
- write_restart_settings(fp);
- PairCMMCommon::write_restart(fp);
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSM::read_restart(FILE *fp)
-{
- read_restart_settings(fp);
- allocate();
- PairCMMCommon::read_restart(fp);
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairCGCMMCoulMSM::memory_usage()
-{
- double bytes=PairCMMCommon::memory_usage();
-
- int n = atom->ntypes;
-
- // cut_coul/cut_coulsq/cut_ljsq
- bytes += (n+1)*(n+1)*sizeof(double)*4;
-
- return bytes;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void *PairCGCMMCoulMSM::extract(char *str)
-{
- if (strcmp(str,"cut_coul") == 0) return (void *) &cut_coul_global;
- return NULL;
-}
-
-/* ---------------------------------------------------------------------- */
diff --git a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp b/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp
deleted file mode 100644
index 7e0dcc079..000000000
--- a/src/GPU/pair_cg_cmm_coul_msm_gpu.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/* ----------------------------------------------------------------------
- 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: Mike Brown (SNL)
-------------------------------------------------------------------------- */
-
-#include "math.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "pair_cg_cmm_coul_msm_gpu.h"
-#include "atom.h"
-#include "atom_vec.h"
-#include "comm.h"
-#include "force.h"
-#include "neighbor.h"
-#include "neigh_list.h"
-#include "integrate.h"
-#include "memory.h"
-#include "error.h"
-#include "neigh_request.h"
-#include "universe.h"
-#include "update.h"
-#include "domain.h"
-#include "string.h"
-#include "kspace.h"
-#include "gpu_extra.h"
-
-// External functions from cuda library for atom decomposition
-
-int cmmm_gpu_init(const int ntypes, double **cutsq, int **cg_type,
- double **host_lj1, double **host_lj2, double **host_lj3,
- double **host_lj4, double **offset, double *special_lj,
- const int nlocal, const int nall, const int max_nbors,
- const int maxspecial, const double cell_size, int &gpu_mode,
- FILE *screen, double **host_cut_ljsq, double host_cut_coulsq,
- double *host_special_coul, const double qqrd2e,
- const int smooth);
-void cmmm_gpu_clear();
-int ** cmmm_gpu_compute_n(const int ago, const int inum, const int nall,
- double **host_x, int *host_type, double *sublo,
- double *subhi, int *tag, int **nspecial,
- int **special, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- int **ilist, int **jnum, const double cpu_time,
- bool &success, double *host_q, double *boxlo,
- double *prd);
-void cmmm_gpu_compute(const int ago, const int inum, const int nall,
- double **host_x, int *host_type, int *ilist, int *numj,
- int **firstneigh, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- const double cpu_time, bool &success, double *host_q,
- const int nlocal, double *boxlo, double *prd);
-double cmmm_gpu_bytes();
-
-using namespace LAMMPS_NS;
-
-enum {C3=0,C4=1};
-
-/* ---------------------------------------------------------------------- */
-
-PairCGCMMCoulMSMGPU::PairCGCMMCoulMSMGPU(LAMMPS *lmp) : PairCGCMMCoulMSM(lmp),
- gpu_mode(GPU_FORCE)
-{
- respa_enable = 0;
- cpu_time = 0.0;
-}
-
-/* ----------------------------------------------------------------------
- free all arrays
-------------------------------------------------------------------------- */
-
-PairCGCMMCoulMSMGPU::~PairCGCMMCoulMSMGPU()
-{
- cmmm_gpu_clear();
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSMGPU::compute(int eflag, int vflag)
-{
- if (eflag || vflag) ev_setup(eflag,vflag);
- else evflag = vflag_fdotr = 0;
-
- int nall = atom->nlocal + atom->nghost;
- int inum, host_start;
-
- bool success = true;
- int *ilist, *numneigh, **firstneigh;
- if (gpu_mode != GPU_FORCE) {
- inum = atom->nlocal;
- firstneigh = cmmm_gpu_compute_n(neighbor->ago, inum, nall, atom->x,
- atom->type, domain->sublo, domain->subhi,
- atom->tag, atom->nspecial, atom->special,
- eflag, vflag, eflag_atom, vflag_atom,
- host_start, &ilist, &numneigh, cpu_time,
- success, atom->q, domain->boxlo,
- domain->prd);
- } else {
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
- cmmm_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
- ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
- vflag_atom, host_start, cpu_time, success, atom->q,
- atom->nlocal, domain->boxlo, domain->prd);
- }
- if (!success)
- error->one(FLERR,"Out of memory on GPGPU");
-
- if (host_start<inum) {
- cpu_time = MPI_Wtime();
- cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh);
- cpu_time = MPI_Wtime() - cpu_time;
- }
-}
-
-/* ----------------------------------------------------------------------
- init specific to this pair style
-------------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSMGPU::init_style()
-{
- PairCGCMMCoulMSM::init_style();
- if (force->newton_pair)
- error->all(FLERR,"Cannot use newton pair with cg/cmm/coul/msm/gpu pair style");
-
- // Repeat cutsq calculation because done after call to init_style
- double maxcut = -1.0;
- double cut;
- for (int i = 1; i <= atom->ntypes; i++) {
- for (int j = i; j <= atom->ntypes; j++) {
- if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
- cut = init_one(i,j);
- cut *= cut;
- if (cut > maxcut)
- maxcut = cut;
- cutsq[i][j] = cutsq[j][i] = cut;
- } else
- cutsq[i][j] = cutsq[j][i] = 0.0;
- }
- }
- double cell_size = sqrt(maxcut) + neighbor->skin;
-
- int maxspecial=0;
- if (atom->molecular)
- maxspecial=atom->maxspecial;
- int success = cmmm_gpu_init(atom->ntypes+1, cutsq, cg_type, lj1, lj2, lj3,
- lj4, offset, force->special_lj, atom->nlocal,
- atom->nlocal+atom->nghost, 300, maxspecial,
- cell_size, gpu_mode, screen, cut_ljsq,
- cut_coulsq_global, force->special_coul,
- force->qqrd2e,_smooth);
- GPU_EXTRA::check_flag(success,error,world);
-
- if (gpu_mode == GPU_FORCE) {
- int irequest = neighbor->request(this);
- neighbor->requests[irequest]->half = 0;
- neighbor->requests[irequest]->full = 1;
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairCGCMMCoulMSMGPU::memory_usage()
-{
- double bytes = Pair::memory_usage();
- return bytes + cmmm_gpu_bytes();
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulMSMGPU::cpu_compute(int start, int inum, int eflag,
- int vflag, int *ilist, int *numneigh,
- int **firstneigh)
-{
- int i,j,ii,jj,jnum,itype,jtype,itable;
- double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
- double fraction,table;
- double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
- double grij,expm2,prefactor,t,erfc;
- int *jlist;
- double rsq;
-
- double **x = atom->x;
- double **f = atom->f;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
-
- // loop over neighbors of my atoms
-
- for (ii = start; ii < inum; ii++) {
- i = ilist[ii];
- qtmp = q[i];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- factor_lj = special_lj[sbmask(j)];
- factor_coul = special_coul[sbmask(j)];
- j &= NEIGHMASK;
-
- const double delx = xtmp - x[j][0];
- const double dely = ytmp - x[j][1];
- const double delz = ztmp - x[j][2];
- const double rsq = delx*delx + dely*dely + delz*delz;
- const int jtype = type[j];
-
- double evdwl = 0.0;
- double ecoul = 0.0;
- double fpair = 0.0;
-
- if (rsq < cutsq[itype][jtype]) {
- const double r2inv = 1.0/rsq;
- const int cgt=cg_type[itype][jtype];
-
- double forcelj = 0.0;
- double forcecoul = 0.0;
-
- if (rsq < cut_ljsq[itype][jtype]) {
- forcelj=factor_lj;
- if (eflag) evdwl=factor_lj;
-
- if (cgt == CG_LJ12_4) {
- const double r4inv=r2inv*r2inv;
- forcelj *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else if (cgt == CG_LJ9_6) {
- const double r3inv = r2inv*sqrt(r2inv);
- const double r6inv = r3inv*r3inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r3inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r3inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else {
- const double r6inv = r2inv*r2inv*r2inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r6inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r6inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- }
- }
-
- if (rsq < cut_coulsq_global) {
- const double ir = 1.0/sqrt(rsq);
- const double prefactor = qqrd2e * qtmp*q[j];
- const double r2_ia2 = rsq*_ia2;
- const double r4_ia4 = r2_ia2*r2_ia2;
- if (_smooth==C3) {
- forcecoul = prefactor*(_ia3*(-4.375+5.25*r2_ia2-1.875*r4_ia4)-
- ir/rsq);
- if (eflag)
- ecoul = prefactor*(ir+_ia*(2.1875-2.1875*r2_ia2+
- 1.3125*r4_ia4-0.3125*r2_ia2*r4_ia4));
- } else {
- const double r6_ia6 = r2_ia2*r4_ia4;
- forcecoul = prefactor*(_ia3*(-6.5625+11.8125*r2_ia2-8.4375*r4_ia4+
- 2.1875*r6_ia6)-ir/rsq);
- if (eflag)
- ecoul = prefactor*(ir+_ia*(2.4609375-3.28125*r2_ia2+
- 2.953125*r4_ia4-1.40625*r6_ia6+
- 0.2734375*r4_ia4*r4_ia4));
- }
- if (factor_coul < 1.0) {
- forcecoul -= (1.0-factor_coul)*prefactor*ir;
- if (eflag) ecoul -= (1.0-factor_coul)*prefactor*ir;
- }
- }
- fpair = forcecoul + forcelj * r2inv;
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
- if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
- }
- }
- }
-}
diff --git a/src/GPU/pair_lj_cut_coul_long_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_gpu.cpp
index 16f609f95..077e3eff7 100644
--- a/src/GPU/pair_lj_cut_coul_long_gpu.cpp
+++ b/src/GPU/pair_lj_cut_coul_long_gpu.cpp
@@ -1,313 +1,313 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "pair_lj_cut_coul_long_gpu.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "integrate.h"
#include "memory.h"
#include "error.h"
#include "neigh_request.h"
#include "universe.h"
#include "update.h"
#include "domain.h"
#include "string.h"
#include "kspace.h"
#include "gpu_extra.h"
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
// External functions from cuda library for atom decomposition
int ljcl_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
double **host_lj2, double **host_lj3, double **host_lj4,
double **offset, double *special_lj, const int nlocal,
const int nall, const int max_nbors, const int maxspecial,
const double cell_size, int &gpu_mode, FILE *screen,
double **host_cut_ljsq, double host_cut_coulsq,
double *host_special_coul, const double qqrd2e,
const double g_ewald);
void ljcl_gpu_clear();
int ** ljcl_gpu_compute_n(const int ago, const int inum,
const int nall, double **host_x, int *host_type,
double *sublo, double *subhi, int *tag,
int **nspecial, int **special, const bool eflag,
const bool vflag, const bool eatom, const bool vatom,
int &host_start, int **ilist, int **jnum,
const double cpu_time, bool &success, double *host_q,
double *boxlo, double *prd);
void ljcl_gpu_compute(const int ago, const int inum, const int nall,
double **host_x, int *host_type, int *ilist, int *numj,
int **firstneigh, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
const double cpu_time, bool &success, double *host_q,
const int nlocal, double *boxlo, double *prd);
double ljcl_gpu_bytes();
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
-PairLJCutCoulLongGPU::PairLJCutCoulLongGPU(LAMMPS *lmp) :
+PairLJCutCoulLongGPU::PairLJCutCoulLongGPU(LAMMPS *lmp) :
PairLJCutCoulLong(lmp), gpu_mode(GPU_FORCE)
{
respa_enable = 0;
cpu_time = 0.0;
}
/* ----------------------------------------------------------------------
free all arrays
------------------------------------------------------------------------- */
PairLJCutCoulLongGPU::~PairLJCutCoulLongGPU()
{
ljcl_gpu_clear();
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulLongGPU::compute(int eflag, int vflag)
{
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
int nall = atom->nlocal + atom->nghost;
int inum, host_start;
bool success = true;
int *ilist, *numneigh, **firstneigh;
if (gpu_mode != GPU_FORCE) {
inum = atom->nlocal;
firstneigh = ljcl_gpu_compute_n(neighbor->ago, inum, nall, atom->x,
atom->type, domain->sublo, domain->subhi,
atom->tag, atom->nspecial, atom->special,
eflag, vflag, eflag_atom, vflag_atom,
host_start, &ilist, &numneigh, cpu_time,
success, atom->q, domain->boxlo,
domain->prd);
} else {
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
ljcl_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
vflag_atom, host_start, cpu_time, success, atom->q,
atom->nlocal, domain->boxlo, domain->prd);
}
if (!success)
error->one(FLERR,"Out of memory on GPGPU");
if (host_start<inum) {
cpu_time = MPI_Wtime();
cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh);
cpu_time = MPI_Wtime() - cpu_time;
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairLJCutCoulLongGPU::init_style()
{
cut_respa = NULL;
if (!atom->q_flag)
error->all(FLERR,"Pair style lj/cut/coul/long/gpu requires atom attribute q");
if (force->newton_pair)
- error->all(FLERR,"Cannot use newton pair with lj/cut/could/cut/gpu pair style");
+ error->all(FLERR,"Cannot use newton pair with lj/cut/coul/long/gpu pair style");
// Repeat cutsq calculation because done after call to init_style
double maxcut = -1.0;
double cut;
for (int i = 1; i <= atom->ntypes; i++) {
for (int j = i; j <= atom->ntypes; j++) {
if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
cut = init_one(i,j);
cut *= cut;
if (cut > maxcut)
maxcut = cut;
cutsq[i][j] = cutsq[j][i] = cut;
} else
cutsq[i][j] = cutsq[j][i] = 0.0;
}
}
double cell_size = sqrt(maxcut) + neighbor->skin;
cut_coulsq = cut_coul * cut_coul;
// insure use of KSpace long-range solver, set g_ewald
if (force->kspace == NULL)
error->all(FLERR,"Pair style is incompatible with KSpace style");
g_ewald = force->kspace->g_ewald;
// setup force tables
if (ncoultablebits) init_tables();
int maxspecial=0;
if (atom->molecular)
maxspecial=atom->maxspecial;
int success = ljcl_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
offset, force->special_lj, atom->nlocal,
atom->nlocal+atom->nghost, 300, maxspecial,
cell_size, gpu_mode, screen, cut_ljsq, cut_coulsq,
force->special_coul, force->qqrd2e, g_ewald);
GPU_EXTRA::check_flag(success,error,world);
if (gpu_mode == GPU_FORCE) {
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCutCoulLongGPU::memory_usage()
{
double bytes = Pair::memory_usage();
return bytes + ljcl_gpu_bytes();
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulLongGPU::cpu_compute(int start, int inum, int eflag,
int vflag, int *ilist, int *numneigh,
int **firstneigh)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *jlist;
double rsq;
evdwl = ecoul = 0.0;
double **x = atom->x;
double **f = atom->f;
double *q = atom->q;
int *type = atom->type;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double qqrd2e = force->qqrd2e;
// loop over neighbors of my atoms
for (ii = start; ii < inum; ii++) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
} else forcelj = 0.0;
fpair = (forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (eflag) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
}
}
}
}
diff --git a/src/GPU/pair_lj_cut_tgpu.cpp b/src/GPU/pair_lj_cut_tgpu.cpp
deleted file mode 100644
index c39823ff7..000000000
--- a/src/GPU/pair_lj_cut_tgpu.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/* ----------------------------------------------------------------------
- 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: Mike Brown (SNL)
-------------------------------------------------------------------------- */
-
-#include "math.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "pair_lj_cut_tgpu.h"
-#include "atom.h"
-#include "atom_vec.h"
-#include "comm.h"
-#include "force.h"
-#include "neighbor.h"
-#include "neigh_list.h"
-#include "integrate.h"
-#include "memory.h"
-#include "error.h"
-#include "neigh_request.h"
-#include "universe.h"
-#include "update.h"
-#include "domain.h"
-#include "string.h"
-#include "gpu_extra.h"
-
-// External functions from cuda library for atom decomposition
-
-int ljl_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
- double **host_lj2, double **host_lj3, double **host_lj4,
- double **offset, double *special_lj, const int nlocal,
- const int nall, const int max_nbors, const int maxspecial,
- const double cell_size, int &gpu_mode, FILE *screen);
-void ljl_gpu_clear();
-int ** ljl_gpu_compute_n(const int ago, const int inum,
- const int nall, double **host_x, int *host_type,
- double *sublo, double *subhi, int *tag, int **nspecial,
- int **special, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- int **ilist, int **jnum,
- const double cpu_time, bool &success);
-void ljl_gpu_compute(const int ago, const int inum, const int nall,
- double **host_x, int *host_type, int *ilist, int *numj,
- int **firstneigh, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom, int &host_start,
- const double cpu_time, bool &success);
-double ljl_gpu_bytes();
-
-using namespace LAMMPS_NS;
-
-/* ---------------------------------------------------------------------- */
-
-PairLJCutTGPU::PairLJCutTGPU(LAMMPS *lmp) : PairLJCut(lmp), gpu_mode(GPU_FORCE)
-{
- respa_enable = 0;
- cpu_time = 0.0;
-
- omp = new PairOMPGPU(lmp);
-}
-
-/* ----------------------------------------------------------------------
- free all arrays
-------------------------------------------------------------------------- */
-
-PairLJCutTGPU::~PairLJCutTGPU()
-{
- ljl_gpu_clear();
- delete omp;
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairLJCutTGPU::compute(int eflag, int vflag)
-{
- if (eflag || vflag) {
- ev_setup(eflag,vflag);
- omp->ev_setup_thr(eflag,vflag,eflag_either,eflag_global,eflag_atom,
- vflag_either,vflag_global,vflag_atom);
- } else evflag = vflag_fdotr = 0;
-
- int nall = atom->nlocal + atom->nghost;
- int inum, host_start;
-
- bool success = true;
- int *ilist, *numneigh, **firstneigh;
- if (gpu_mode != GPU_FORCE) {
- inum = atom->nlocal;
- firstneigh = ljl_gpu_compute_n(neighbor->ago, inum, nall,
- atom->x, atom->type, domain->sublo,
- domain->subhi, atom->tag, atom->nspecial,
- atom->special, eflag, vflag, eflag_atom,
- vflag_atom, host_start, &ilist, &numneigh,
- cpu_time, success);
- } else {
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
- ljl_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
- ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
- vflag_atom, host_start, cpu_time, success);
- }
- if (!success)
- error->one(FLERR,"Out of memory on GPGPU");
-
- if (host_start<inum) {
- cpu_time = MPI_Wtime();
- #ifdef _OPENMP
- #pragma omp parallel default(shared)
- #endif
- {
- cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh);
- }
- if (evflag) omp->ev_reduce_thr(*this);
- cpu_time = MPI_Wtime() - cpu_time;
- }
-}
-
-/* ----------------------------------------------------------------------
- init specific to this pair style
-------------------------------------------------------------------------- */
-
-void PairLJCutTGPU::init_style()
-{
- omp->init_style();
- cut_respa = NULL;
-
- if (force->newton_pair)
- error->all(FLERR,"Cannot use newton pair with lj/cut/tgpu pair style");
-
- // Repeat cutsq calculation because done after call to init_style
- double maxcut = -1.0;
- double cut;
- for (int i = 1; i <= atom->ntypes; i++) {
- for (int j = i; j <= atom->ntypes; j++) {
- if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
- cut = init_one(i,j);
- cut *= cut;
- if (cut > maxcut)
- maxcut = cut;
- cutsq[i][j] = cutsq[j][i] = cut;
- } else
- cutsq[i][j] = cutsq[j][i] = 0.0;
- }
- }
- double cell_size = sqrt(maxcut) + neighbor->skin;
-
- int maxspecial=0;
- if (atom->molecular)
- maxspecial=atom->maxspecial;
- int success = ljl_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
- offset, force->special_lj, atom->nlocal,
- atom->nlocal+atom->nghost, 300, maxspecial,
- cell_size, gpu_mode, screen);
- GPU_EXTRA::check_flag(success,error,world);
-
- if (gpu_mode == GPU_FORCE) {
- int irequest = neighbor->request(this);
- neighbor->requests[irequest]->half = 0;
- neighbor->requests[irequest]->full = 1;
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairLJCutTGPU::memory_usage()
-{
- double bytes = Pair::memory_usage();
- return bytes + ljl_gpu_bytes()+omp->memory_usage();
-}
-
-/* ---------------------------------------------------------------------- */
-
-void PairLJCutTGPU::cpu_compute(int start, int inum, int eflag, int vflag,
- int *ilist, int *numneigh, int **firstneigh)
-{
- int i,j,ii,jj,jnum,itype,jtype;
- double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
- double rsq,r2inv,r6inv,forcelj,factor_lj;
- int *jlist;
-
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- double *special_lj = force->special_lj;
-
- // loop over neighbors of my atoms
- int iifrom, iito, tid;
- double **f = omp->loop_setup_thr_full(atom->f,iifrom,iito,tid,start,inum,
- nall);
- for (ii = iifrom; ii < iito; ii++) {
- i = ilist[ii];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
-
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- factor_lj = special_lj[sbmask(j)];
- j &= NEIGHMASK;
-
-
- delx = xtmp - x[j][0];
- dely = ytmp - x[j][1];
- delz = ztmp - x[j][2];
- rsq = delx*delx + dely*dely + delz*delz;
- jtype = type[j];
-
- if (rsq < cutsq[itype][jtype]) {
- r2inv = 1.0/rsq;
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
- fpair = factor_lj*forcelj*r2inv;
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
-
- if (eflag) {
- evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
- offset[itype][jtype];
- evdwl *= factor_lj;
- }
-
- #ifdef _OPENMP
- if (evflag) omp->ev_tally_full_thr(i,evdwl,0.0,fpair,delx,dely,delz,
- tid);
- #else
- if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
- #endif
- }
- }
- }
-}
diff --git a/src/GPU/pair_lj_cut_tgpu.h b/src/GPU/pair_lj_cut_tgpu.h
deleted file mode 100644
index b9640929c..000000000
--- a/src/GPU/pair_lj_cut_tgpu.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ----------------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-#ifdef PAIR_CLASS
-
-PairStyle(lj/cut/tgpu,PairLJCutTGPU)
-
-#else
-
-#ifndef LMP_PAIR_LJ_LIGHT_TGPU_H
-#define LMP_PAIR_LJ_LIGHT_TGPU_H
-
-#include "pair_lj_cut.h"
-#include "pair_omp_gpu.h"
-
-namespace LAMMPS_NS {
-
-class PairLJCutTGPU : public PairLJCut {
- public:
- PairLJCutTGPU(LAMMPS *lmp);
- ~PairLJCutTGPU();
- void cpu_compute(int, int, int, int, int *, int *, int **);
- void compute(int, int);
- void init_style();
- double memory_usage();
-
- enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH };
-
- private:
- int gpu_mode;
- double cpu_time;
- int *gpulist;
-
- PairOMPGPU *omp;
-};
-
-}
-#endif
-#endif
-
diff --git a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp b/src/GPU/pair_lj_sdk_coul_long_gpu.cpp
similarity index 70%
rename from src/GPU/pair_cg_cmm_coul_long_gpu.cpp
rename to src/GPU/pair_lj_sdk_coul_long_gpu.cpp
index b9439835d..4ce92e543 100644
--- a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp
+++ b/src/GPU/pair_lj_sdk_coul_long_gpu.cpp
@@ -1,337 +1,350 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
-#include "pair_cg_cmm_coul_long_gpu.h"
+#include "pair_lj_sdk_coul_long_gpu.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "integrate.h"
#include "memory.h"
#include "error.h"
#include "neigh_request.h"
#include "universe.h"
#include "update.h"
#include "domain.h"
#include "string.h"
#include "kspace.h"
#include "gpu_extra.h"
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
// External functions from cuda library for atom decomposition
-int cmml_gpu_init(const int ntypes, double **cutsq, int **cg_type,
+int cmml_gpu_init(const int ntypes, double **cutsq, int **lj_type,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **offset, double *special_lj,
const int nlocal, const int nall, const int max_nbors,
const int maxspecial, const double cell_size, int &gpu_mode,
FILE *screen, double **host_cut_ljsq, double host_cut_coulsq,
double *host_special_coul, const double qqrd2e,
const double g_ewald);
void cmml_gpu_clear();
int ** cmml_gpu_compute_n(const int ago, const int inum, const int nall,
double **host_x, int *host_type, double *sublo,
double *subhi, int *tag, int **nspecial,
int **special, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
int **ilist, int **jnum, const double cpu_time,
bool &success, double *host_q, double *boxlo,
double *prd);
void cmml_gpu_compute(const int ago, const int inum, const int nall,
double **host_x, int *host_type, int *ilist, int *numj,
int **firstneigh, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
const double cpu_time, bool &success, double *host_q,
const int nlocal, double *boxlo, double *prd);
double cmml_gpu_bytes();
+#include "lj_sdk_common.h"
+
using namespace LAMMPS_NS;
+using namespace LJSDKParms;
/* ---------------------------------------------------------------------- */
-PairCGCMMCoulLongGPU::PairCGCMMCoulLongGPU(LAMMPS *lmp) : PairCGCMMCoulLong(lmp), gpu_mode(GPU_FORCE)
+PairLJSDKCoulLongGPU::PairLJSDKCoulLongGPU(LAMMPS *lmp) :
+ PairLJSDKCoulLong(lmp), gpu_mode(GPU_FORCE)
{
respa_enable = 0;
cpu_time = 0.0;
}
/* ----------------------------------------------------------------------
free all arrays
------------------------------------------------------------------------- */
-PairCGCMMCoulLongGPU::~PairCGCMMCoulLongGPU()
+PairLJSDKCoulLongGPU::~PairLJSDKCoulLongGPU()
{
cmml_gpu_clear();
}
/* ---------------------------------------------------------------------- */
-void PairCGCMMCoulLongGPU::compute(int eflag, int vflag)
+void PairLJSDKCoulLongGPU::compute(int eflag, int vflag)
{
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
int nall = atom->nlocal + atom->nghost;
int inum, host_start;
bool success = true;
int *ilist, *numneigh, **firstneigh;
if (gpu_mode != GPU_FORCE) {
inum = atom->nlocal;
firstneigh = cmml_gpu_compute_n(neighbor->ago, inum, nall, atom->x,
atom->type, domain->sublo, domain->subhi,
atom->tag, atom->nspecial, atom->special,
eflag, vflag, eflag_atom, vflag_atom,
host_start, &ilist, &numneigh, cpu_time,
success, atom->q, domain->boxlo,
domain->prd);
} else {
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
cmml_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
vflag_atom, host_start, cpu_time, success, atom->q,
atom->nlocal, domain->boxlo, domain->prd);
}
if (!success)
error->one(FLERR,"Out of memory on GPGPU");
if (host_start<inum) {
cpu_time = MPI_Wtime();
- cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh);
+ if (evflag) {
+ if (eflag) cpu_compute<1,1>(host_start, inum, ilist, numneigh, firstneigh);
+ else cpu_compute<1,0>(host_start, inum, ilist, numneigh, firstneigh);
+ } else cpu_compute<0,0>(host_start, inum, ilist, numneigh, firstneigh);
cpu_time = MPI_Wtime() - cpu_time;
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
-void PairCGCMMCoulLongGPU::init_style()
+void PairLJSDKCoulLongGPU::init_style()
{
- cut_respa = NULL;
-
if (!atom->q_flag)
- error->all(FLERR,"Pair style cg/cmm/coul/long/gpu requires atom attribute q");
+ error->all(FLERR,"Pair style lj/sdk/coul/long/gpu requires atom attribute q");
if (force->newton_pair)
- error->all(FLERR,"Cannot use newton pair with cg/cmm/coul/long/gpu pair style");
+ error->all(FLERR,"Cannot use newton pair with lj/sdk/coul/long/gpu pair style");
// Repeat cutsq calculation because done after call to init_style
double maxcut = -1.0;
double cut;
for (int i = 1; i <= atom->ntypes; i++) {
for (int j = i; j <= atom->ntypes; j++) {
if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
cut = init_one(i,j);
cut *= cut;
if (cut > maxcut)
maxcut = cut;
cutsq[i][j] = cutsq[j][i] = cut;
} else
cutsq[i][j] = cutsq[j][i] = 0.0;
}
}
double cell_size = sqrt(maxcut) + neighbor->skin;
+ cut_coulsq = cut_coul * cut_coul;
+
// insure use of KSpace long-range solver, set g_ewald
if (force->kspace == NULL)
error->all(FLERR,"Pair style is incompatible with KSpace style");
g_ewald = force->kspace->g_ewald;
// setup force tables
if (ncoultablebits) init_tables();
int maxspecial=0;
if (atom->molecular)
maxspecial=atom->maxspecial;
- int success = cmml_gpu_init(atom->ntypes+1, cutsq, cg_type, lj1, lj2, lj3,
+ int success = cmml_gpu_init(atom->ntypes+1, cutsq, lj_type, lj1, lj2, lj3,
lj4, offset, force->special_lj, atom->nlocal,
atom->nlocal+atom->nghost, 300, maxspecial,
cell_size, gpu_mode, screen, cut_ljsq,
- cut_coulsq_global, force->special_coul,
+ cut_coulsq, force->special_coul,
force->qqrd2e, g_ewald);
GPU_EXTRA::check_flag(success,error,world);
if (gpu_mode == GPU_FORCE) {
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
}
}
/* ---------------------------------------------------------------------- */
-double PairCGCMMCoulLongGPU::memory_usage()
+double PairLJSDKCoulLongGPU::memory_usage()
{
double bytes = Pair::memory_usage();
return bytes + cmml_gpu_bytes();
}
/* ---------------------------------------------------------------------- */
-
-void PairCGCMMCoulLongGPU::cpu_compute(int start, int inum, int eflag,
- int vflag, int *ilist, int *numneigh,
- int **firstneigh)
+template <int EVFLAG, int EFLAG>
+void PairLJSDKCoulLongGPU::cpu_compute(int start, int inum, int *ilist,
+ int *numneigh, int **firstneigh)
{
- int i,j,ii,jj,jnum,itype,jtype,itable;
- double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
- double fraction,table;
- double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
- double grij,expm2,prefactor,t,erfc;
- int *jlist;
- double rsq;
-
- double **x = atom->x;
- double **f = atom->f;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ int i,j,ii,jj;
+ double qtmp,xtmp,ytmp,ztmp;
+ double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+
+ const double * const * const x = atom->x;
+ double * const * const f = atom->f;
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
// loop over neighbors of my atoms
for (ii = start; ii < inum; ii++) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
const double delx = xtmp - x[j][0];
const double dely = ytmp - x[j][1];
const double delz = ztmp - x[j][2];
const double rsq = delx*delx + dely*dely + delz*delz;
const int jtype = type[j];
double evdwl = 0.0;
double ecoul = 0.0;
double fpair = 0.0;
if (rsq < cutsq[itype][jtype]) {
- const double r2inv = 1.0/rsq;
- const int cgt=cg_type[itype][jtype];
-
- double forcelj = 0.0;
- double forcecoul = 0.0;
-
- if (rsq < cut_ljsq[itype][jtype]) {
- forcelj=factor_lj;
- if (eflag) evdwl=factor_lj;
-
- if (cgt == CG_LJ12_4) {
- const double r4inv=r2inv*r2inv;
- forcelj *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else if (cgt == CG_LJ9_6) {
- const double r3inv = r2inv*sqrt(r2inv);
- const double r6inv = r3inv*r3inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r3inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r3inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else {
- const double r6inv = r2inv*r2inv*r2inv;
- forcelj *= r6inv*(lj1[itype][jtype]*r6inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r6inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- }
- }
+ r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
- if (rsq < cut_coulsq_global) {
- if (!ncoultablebits || rsq <= tabinnersq) {
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq) {
const double r = sqrt(rsq);
const double grij = g_ewald * r;
const double expm2 = exp(-grij*grij);
const double t = 1.0 / (1.0 + EWALD_P*grij);
const double erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
const double prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
- if (eflag) ecoul = prefactor*erfc;
+ if (EFLAG) ecoul = prefactor*erfc;
if (factor_coul < 1.0) {
forcecoul -= (1.0-factor_coul)*prefactor;
- if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
+ if (EFLAG) ecoul -= (1.0-factor_coul)*prefactor;
}
- } else {
+ } else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
int itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
const double fraction = (rsq_lookup.f - rtable[itable]) *
drtable[itable];
const double table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
- if (eflag) {
+ if (EFLAG) {
const double table2 = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table2;
}
if (factor_coul < 1.0) {
const double table2 = ctable[itable] + fraction*dctable[itable];
const double prefactor = qtmp*q[j] * table2;
forcecoul -= (1.0-factor_coul)*prefactor;
- if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
+ if (EFLAG) ecoul -= (1.0-factor_coul)*prefactor;
}
- }
- }
- fpair = (forcecoul + forcelj) * r2inv;
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
-
- if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
+ }
+ } else {
+ forcecoul = 0.0;
+ ecoul = 0.0;
+ }
+
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ }
+
+ if (EFLAG) evdwl *= factor_lj;
+
+ } else {
+ forcelj=0.0;
+ evdwl = 0.0;
+ }
+
+ fpair = (forcecoul + factor_lj*forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+
+ if (EVFLAG) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
}
}
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
}
}
diff --git a/src/GPU/pair_cg_cmm_coul_msm_gpu.h b/src/GPU/pair_lj_sdk_coul_long_gpu.h
similarity index 68%
rename from src/GPU/pair_cg_cmm_coul_msm_gpu.h
rename to src/GPU/pair_lj_sdk_coul_long_gpu.h
index a7746f488..cb6cb4fe3 100644
--- a/src/GPU/pair_cg_cmm_coul_msm_gpu.h
+++ b/src/GPU/pair_lj_sdk_coul_long_gpu.h
@@ -1,47 +1,49 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm/coul/msm/gpu,PairCGCMMCoulMSMGPU)
+PairStyle(lj/sdk/coul/long/gpu,PairLJSDKCoulLongGPU)
+PairStyle(cg/cmm/coul/long/gpu,PairLJSDKCoulLongGPU)
#else
-#ifndef LMP_PAIR_CG_CMM_COUL_MSM_GPU_H
-#define LMP_PAIR_CG_CMM_COUL_MSM_GPU_H
+#ifndef LMP_PAIR_LJ_SDK_COUL_LONG_GPU_H
+#define LMP_PAIR_LJ_SDK_COUL_LONG_GPU_H
-#include "pair_cg_cmm_coul_msm.h"
+#include "pair_lj_sdk_coul_long.h"
namespace LAMMPS_NS {
-class PairCGCMMCoulMSMGPU : public PairCGCMMCoulMSM {
+class PairLJSDKCoulLongGPU : public PairLJSDKCoulLong {
public:
- PairCGCMMCoulMSMGPU(LAMMPS *lmp);
- ~PairCGCMMCoulMSMGPU();
- void cpu_compute(int, int, int, int, int *, int *, int **);
+ PairLJSDKCoulLongGPU(LAMMPS *lmp);
+ ~PairLJSDKCoulLongGPU();
+ template <int, int>
+ void cpu_compute(int, int, int *, int *, int **);
void compute(int, int);
void init_style();
double memory_usage();
enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH };
private:
int gpu_mode;
double cpu_time;
int *gpulist;
};
}
#endif
#endif
diff --git a/src/GPU/pair_cg_cmm_gpu.cpp b/src/GPU/pair_lj_sdk_gpu.cpp
similarity index 72%
rename from src/GPU/pair_cg_cmm_gpu.cpp
rename to src/GPU/pair_lj_sdk_gpu.cpp
index 4e409bd37..bb5e7d3e0 100644
--- a/src/GPU/pair_cg_cmm_gpu.cpp
+++ b/src/GPU/pair_lj_sdk_gpu.cpp
@@ -1,253 +1,260 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
-#include "pair_cg_cmm_gpu.h"
+#include "pair_lj_sdk_gpu.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "integrate.h"
#include "memory.h"
#include "error.h"
#include "neigh_request.h"
#include "universe.h"
#include "update.h"
#include "domain.h"
#include "string.h"
#include "gpu_extra.h"
// External functions from cuda library for atom decomposition
int cmm_gpu_init(const int ntypes, double **cutsq, int **cg_types,
double **host_lj1, double **host_lj2, double **host_lj3,
double **host_lj4, double **offset, double *special_lj,
const int nlocal, const int nall, const int max_nbors,
const int maxspecial, const double cell_size, int &gpu_mode,
FILE *screen);
void cmm_gpu_clear();
int ** cmm_gpu_compute_n(const int ago, const int inum, const int nall,
double **host_x, int *host_type, double *sublo,
double *subhi, int *tag, int **nspecial,
int **special, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
int **ilist, int **jnum,
const double cpu_time, bool &success);
void cmm_gpu_compute(const int ago, const int inum, const int nall,
double **host_x, int *host_type, int *ilist, int *numj,
int **firstneigh, const bool eflag, const bool vflag,
const bool eatom, const bool vatom, int &host_start,
const double cpu_time, bool &success);
double cmm_gpu_bytes();
+#include "lj_sdk_common.h"
+
using namespace LAMMPS_NS;
+using namespace LJSDKParms;
/* ---------------------------------------------------------------------- */
-PairCGCMMGPU::PairCGCMMGPU(LAMMPS *lmp) : PairCGCMM(lmp), gpu_mode(GPU_FORCE)
+PairLJSDKGPU::PairLJSDKGPU(LAMMPS *lmp) : PairLJSDK(lmp), gpu_mode(GPU_FORCE)
{
respa_enable = 0;
cpu_time = 0.0;
}
/* ----------------------------------------------------------------------
free all arrays
------------------------------------------------------------------------- */
-PairCGCMMGPU::~PairCGCMMGPU()
+PairLJSDKGPU::~PairLJSDKGPU()
{
cmm_gpu_clear();
}
/* ---------------------------------------------------------------------- */
-void PairCGCMMGPU::compute(int eflag, int vflag)
+void PairLJSDKGPU::compute(int eflag, int vflag)
{
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
int nall = atom->nlocal + atom->nghost;
int inum, host_start;
bool success = true;
int *ilist, *numneigh, **firstneigh;
if (gpu_mode != GPU_FORCE) {
inum = atom->nlocal;
firstneigh = cmm_gpu_compute_n(neighbor->ago, inum, nall, atom->x,
atom->type, domain->sublo, domain->subhi,
atom->tag, atom->nspecial, atom->special,
eflag, vflag, eflag_atom, vflag_atom,
host_start, &ilist, &numneigh, cpu_time,
success);
} else {
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
cmm_gpu_compute(neighbor->ago, inum, nall, atom->x, atom->type,
ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
vflag_atom, host_start, cpu_time, success);
}
if (!success)
error->one(FLERR,"Out of memory on GPGPU");
if (host_start<inum) {
cpu_time = MPI_Wtime();
- cpu_compute(host_start, inum, eflag, vflag, ilist, numneigh, firstneigh);
+ if (evflag) {
+ if (eflag) cpu_compute<1,1>(host_start, inum, ilist, numneigh, firstneigh);
+ else cpu_compute<1,0>(host_start, inum, ilist, numneigh, firstneigh);
+ } else cpu_compute<0,0>(host_start, inum, ilist, numneigh, firstneigh);
cpu_time = MPI_Wtime() - cpu_time;
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
-void PairCGCMMGPU::init_style()
+void PairLJSDKGPU::init_style()
{
- cut_respa = NULL;
-
if (force->newton_pair)
- error->all(FLERR,"Cannot use newton pair with cg/cmm/gpu pair style");
+ error->all(FLERR,"Cannot use newton pair with lj/sdk/gpu pair style");
// Repeat cutsq calculation because done after call to init_style
double maxcut = -1.0;
double cut;
for (int i = 1; i <= atom->ntypes; i++) {
for (int j = i; j <= atom->ntypes; j++) {
if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
cut = init_one(i,j);
cut *= cut;
if (cut > maxcut)
maxcut = cut;
cutsq[i][j] = cutsq[j][i] = cut;
} else
cutsq[i][j] = cutsq[j][i] = 0.0;
}
}
double cell_size = sqrt(maxcut) + neighbor->skin;
int maxspecial=0;
if (atom->molecular)
maxspecial=atom->maxspecial;
- int success = cmm_gpu_init(atom->ntypes+1,cutsq,cg_type,lj1,lj2,lj3,lj4,
+ int success = cmm_gpu_init(atom->ntypes+1,cutsq,lj_type,lj1,lj2,lj3,lj4,
offset, force->special_lj, atom->nlocal,
atom->nlocal+atom->nghost, 300, maxspecial,
cell_size, gpu_mode, screen);
GPU_EXTRA::check_flag(success,error,world);
if (gpu_mode == GPU_FORCE) {
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
}
}
/* ---------------------------------------------------------------------- */
-double PairCGCMMGPU::memory_usage()
+double PairLJSDKGPU::memory_usage()
{
double bytes = Pair::memory_usage();
return bytes + cmm_gpu_bytes();
}
/* ---------------------------------------------------------------------- */
-
-void PairCGCMMGPU::cpu_compute(int start, int inum, int eflag, int vflag,
- int *ilist, int *numneigh, int **firstneigh)
+template <int EVFLAG, int EFLAG>
+void PairLJSDKGPU::cpu_compute(int start, int inum, int *ilist,
+ int *numneigh, int **firstneigh)
{
- int i,j,ii,jj,jnum,itype,jtype;
+ int i,j,ii,jj,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
- double rsq,r2inv,r6inv,forcelj,factor_lj;
- int *jlist;
+ double rsq,r2inv,forcelj,factor_lj;
- double **x = atom->x;
- double **f = atom->f;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = atom->f;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
// loop over neighbors of my atoms
for (ii = start; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
+ fxtmp=fytmp=fztmp=0.0;
+
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
- const int cgt=cg_type[itype][jtype];
- r2inv = 1.0/rsq;
-
- fpair = factor_lj;
- if (eflag) evdwl = factor_lj;
- if (cgt == CG_LJ12_4) {
- const double r4inv = r2inv*r2inv;
- fpair *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else if (cgt == CG_LJ9_6) {
+ r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
const double r3inv = r2inv*sqrt(r2inv);
const double r6inv = r3inv*r3inv;
- fpair *= r6inv*(lj1[itype][jtype]*r3inv
- - lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r3inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- } else {
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
const double r6inv = r2inv*r2inv*r2inv;
- fpair *= r6inv*(lj1[itype][jtype]*r6inv
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
- lj2[itype][jtype]);
- if (eflag) {
- evdwl *= r6inv*(lj3[itype][jtype]*r6inv
- - lj4[itype][jtype]) - offset[itype][jtype];
- }
- }
- fpair *= r2inv;
-
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
-
- if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ } else continue;
+
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+
+ if (EVFLAG) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
}
}
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
}
}
diff --git a/src/GPU/pair_cg_cmm_gpu.h b/src/GPU/pair_lj_sdk_gpu.h
similarity index 73%
rename from src/GPU/pair_cg_cmm_gpu.h
rename to src/GPU/pair_lj_sdk_gpu.h
index 481e01af2..cb5e30bd4 100644
--- a/src/GPU/pair_cg_cmm_gpu.h
+++ b/src/GPU/pair_lj_sdk_gpu.h
@@ -1,46 +1,48 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm/gpu,PairCGCMMGPU)
+PairStyle(lj/sdk/gpu,PairLJSDKGPU)
+PairStyle(cg/cmm/gpu,PairLJSDKGPU)
#else
-#ifndef LMP_PAIR_CG_CMM_GPU_H
-#define LMP_PAIR_CG_CMM_GPU_H
+#ifndef LMP_PAIR_LJ_SDK_GPU_H
+#define LMP_PAIR_LJ_SDK_GPU_H
-#include "pair_cg_cmm.h"
+#include "pair_lj_sdk.h"
namespace LAMMPS_NS {
-class PairCGCMMGPU : public PairCGCMM {
+class PairLJSDKGPU : public PairLJSDK {
public:
- PairCGCMMGPU(LAMMPS *lmp);
- ~PairCGCMMGPU();
- void cpu_compute(int, int, int, int, int *, int *, int **);
+ PairLJSDKGPU(LAMMPS *lmp);
+ ~PairLJSDKGPU();
+ template <int, int>
+ void cpu_compute(int, int, int *, int *, int **);
void compute(int, int);
void init_style();
double memory_usage();
enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH };
private:
int gpu_mode;
double cpu_time;
int *gpulist;
};
}
#endif
#endif
diff --git a/src/GPU/pair_omp_gpu.cpp b/src/GPU/pair_omp_gpu.cpp
deleted file mode 100644
index dc6229fd5..000000000
--- a/src/GPU/pair_omp_gpu.cpp
+++ /dev/null
@@ -1,665 +0,0 @@
-/* ----------------------------------------------------------------------
- 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: Axel Kohlmeyer (Temple U)
- Modified by Mike for use with GPU library
-------------------------------------------------------------------------- */
-
-#if defined(_OPENMP)
-
-#include "atom.h"
-#include "comm.h"
-#include "force.h"
-#include "pair_omp_gpu.h"
-#include "memory.h"
-
-using namespace LAMMPS_NS;
-
-/* ---------------------------------------------------------------------- */
-
-PairOMPGPU::PairOMPGPU(LAMMPS *lmp) : Pointers(lmp)
-{
- eng_vdwl_thr = NULL;
- eng_coul_thr = NULL;
- virial_thr = NULL;
- eatom_thr = NULL;
- vatom_thr = NULL;
- f_thr = NULL;
-}
-
-/* ---------------------------------------------------------------------- */
-
-PairOMPGPU::~PairOMPGPU()
-{
- free_mem();
-}
-
-/* ----------------------------------------------------------------------
- free any allocated memory
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::free_mem() {
- memory->sfree(eng_vdwl_thr);
- memory->sfree(eng_coul_thr);
- memory->destroy(virial_thr);
- memory->destroy(eatom_thr);
- memory->destroy(vatom_thr);
- memory->destroy(f_thr);
- eng_vdwl_thr = NULL;
- eng_coul_thr = NULL;
- virial_thr = NULL;
- eatom_thr = NULL;
- vatom_thr = NULL;
- f_thr = NULL;
- _nmax = 0;
-}
-
-/* ----------------------------------------------------------------------
- init specific to this pair style
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::init_style()
-{
- free_mem();
-
- #pragma omp parallel
- {
- int th_id = omp_get_thread_num();
- #pragma omp barrier
- if (th_id == 0)
- _nthreads = omp_get_num_threads();
- }
-
- // for hybrid OpenMP/MPI we need multiple copies
- // of some accumulators to avoid race conditions
-
- eng_vdwl_thr = (double *)memory->smalloc(_nthreads*sizeof(double),
- "pair:eng_vdwl_thr");
- eng_coul_thr = (double *)memory->smalloc(_nthreads*sizeof(double),
- "pair:eng_coul_thr");
- memory->create(virial_thr,_nthreads,6,"pair:virial_thr");
-
- maxeatom_thr = maxvatom_thr = 0;
-}
-
-/* ----------------------------------------------------------------------
- setup for energy, virial computation. additional code for multi-threading
- see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_setup_thr(int eflag, int vflag, int _eflag_either,
- int _eflag_global, int _eflag_atom,
- int _vflag_either, int _vflag_global,
- int _vflag_atom)
-{
- eflag_either=_eflag_either;
- eflag_global=_eflag_global;
- eflag_atom=_eflag_atom;
- vflag_either=_vflag_either;
- vflag_global=_vflag_global;
- vflag_atom=_vflag_atom;
- int i,n,t;
-
- // reallocate per-atom arrays if necessary
- if (eflag_atom && atom->nmax > maxeatom_thr) {
- maxeatom_thr = atom->nmax;
- memory->destroy(eatom_thr);
- memory->create(eatom_thr,_nthreads,maxeatom_thr,"pair:eatom_thr");
- }
- if (vflag_atom && atom->nmax > maxvatom_thr) {
- maxvatom_thr = atom->nmax;
- memory->destroy(vatom_thr);
- memory->create(vatom_thr,_nthreads,maxvatom_thr,6,"pair:vatom_thr");
- }
-
- // zero per thread accumulators
- // use force->newton instead of newton_pair
- // b/c some bonds/dihedrals call pair::ev_tally with pairwise info
- const int ntotal = (force->newton) ?
- (atom->nlocal + atom->nghost) : atom->nlocal;
- for (t = 0; t < _nthreads; ++t) {
- if (eflag_global) eng_vdwl_thr[t] = eng_coul_thr[t] = 0.0;
- if (vflag_global) for (i = 0; i < 6; ++i) virial_thr[t][i] = 0.0;
- if (eflag_atom) {
- for (i = 0; i < ntotal; ++i) eatom_thr[t][i] = 0.0;
- }
- if (vflag_atom) {
- for (i = 0; i < ntotal; ++i) {
- vatom_thr[t][i][0] = 0.0;
- vatom_thr[t][i][1] = 0.0;
- vatom_thr[t][i][2] = 0.0;
- vatom_thr[t][i][3] = 0.0;
- vatom_thr[t][i][4] = 0.0;
- vatom_thr[t][i][5] = 0.0;
- }
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- tally eng_vdwl and virial into per thread global and per-atom accumulators
- need i < nlocal test since called by bond_quartic and dihedral_charmm
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally_thr(int i, int j, int nlocal, int newton_pair,
- double evdwl, double ecoul, double fpair,
- double delx, double dely, double delz, int tid)
-{
- double evdwlhalf,ecoulhalf,epairhalf,v[6];
-
- if (eflag_either) {
- if (eflag_global) {
- if (newton_pair) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
- } else {
- evdwlhalf = 0.5*evdwl;
- ecoulhalf = 0.5*ecoul;
- if (i < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- if (j < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- }
- }
- if (eflag_atom) {
- epairhalf = 0.5 * (evdwl + ecoul);
- if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf;
- if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf;
- }
- }
-
- if (vflag_either) {
- v[0] = delx*delx*fpair;
- v[1] = dely*dely*fpair;
- v[2] = delz*delz*fpair;
- v[3] = delx*dely*fpair;
- v[4] = delx*delz*fpair;
- v[5] = dely*delz*fpair;
-
- if (vflag_global) {
- if (newton_pair) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- } else {
- if (i < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- if (j < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- }
- }
-
- if (vflag_atom) {
- if (newton_pair || i < nlocal) {
- vatom_thr[tid][i][0] += 0.5*v[0];
- vatom_thr[tid][i][1] += 0.5*v[1];
- vatom_thr[tid][i][2] += 0.5*v[2];
- vatom_thr[tid][i][3] += 0.5*v[3];
- vatom_thr[tid][i][4] += 0.5*v[4];
- vatom_thr[tid][i][5] += 0.5*v[5];
- }
- if (newton_pair || j < nlocal) {
- vatom_thr[tid][j][0] += 0.5*v[0];
- vatom_thr[tid][j][1] += 0.5*v[1];
- vatom_thr[tid][j][2] += 0.5*v[2];
- vatom_thr[tid][j][3] += 0.5*v[3];
- vatom_thr[tid][j][4] += 0.5*v[4];
- vatom_thr[tid][j][5] += 0.5*v[5];
- }
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- tally eng_vdwl and virial into per thread global and per-atom accumulators
- need i < nlocal test since called by bond_quartic and dihedral_charmm
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally_full_thr(int i, double evdwl,
- double ecoul, double fpair, double delx,
- double dely, double delz, int tid)
-{
- double evdwlhalf,ecoulhalf,epairhalf,v[6];
-
- if (eflag_either) {
- if (eflag_global) {
- evdwlhalf = 0.5*evdwl;
- ecoulhalf = 0.5*ecoul;
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- if (eflag_atom) {
- epairhalf = 0.5 * (evdwl + ecoul);
- eatom_thr[tid][i] += epairhalf;
- }
- }
-
- if (vflag_either) {
- v[0] = delx*delx*fpair;
- v[1] = dely*dely*fpair;
- v[2] = delz*delz*fpair;
- v[3] = delx*dely*fpair;
- v[4] = delx*delz*fpair;
- v[5] = dely*delz*fpair;
-
- if (vflag_global) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
-
- if (vflag_atom) {
- vatom_thr[tid][i][0] += 0.5*v[0];
- vatom_thr[tid][i][1] += 0.5*v[1];
- vatom_thr[tid][i][2] += 0.5*v[2];
- vatom_thr[tid][i][3] += 0.5*v[3];
- vatom_thr[tid][i][4] += 0.5*v[4];
- vatom_thr[tid][i][5] += 0.5*v[5];
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- tally eng_vdwl and virial into global and per-atom accumulators
- for virial, have delx,dely,delz and fx,fy,fz
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally_xyz_thr(int i, int j, int nlocal, int newton_pair,
- double evdwl, double ecoul,
- double fx, double fy, double fz,
- double delx, double dely, double delz, int tid)
-{
- double evdwlhalf,ecoulhalf,epairhalf,v[6];
-
- if (eflag_either) {
- if (eflag_global) {
- if (newton_pair) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
- } else {
- evdwlhalf = 0.5*evdwl;
- ecoulhalf = 0.5*ecoul;
- if (i < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- if (j < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- }
- }
- if (eflag_atom) {
- epairhalf = 0.5 * (evdwl + ecoul);
- if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf;
- if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf;
- }
- }
-
- if (vflag_either) {
- v[0] = delx*fx;
- v[1] = dely*fy;
- v[2] = delz*fz;
- v[3] = delx*fy;
- v[4] = delx*fz;
- v[5] = dely*fz;
-
- if (vflag_global) {
- if (newton_pair) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- } else {
- if (i < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- if (j < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- }
- }
-
- if (vflag_atom) {
- if (newton_pair || i < nlocal) {
- vatom_thr[tid][i][0] += 0.5*v[0];
- vatom_thr[tid][i][1] += 0.5*v[1];
- vatom_thr[tid][i][2] += 0.5*v[2];
- vatom_thr[tid][i][3] += 0.5*v[3];
- vatom_thr[tid][i][4] += 0.5*v[4];
- vatom_thr[tid][i][5] += 0.5*v[5];
- }
- if (newton_pair || j < nlocal) {
- vatom_thr[tid][j][0] += 0.5*v[0];
- vatom_thr[tid][j][1] += 0.5*v[1];
- vatom_thr[tid][j][2] += 0.5*v[2];
- vatom_thr[tid][j][3] += 0.5*v[3];
- vatom_thr[tid][j][4] += 0.5*v[4];
- vatom_thr[tid][j][5] += 0.5*v[5];
- }
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- tally eng_vdwl and virial into global and per-atom accumulators
- called by SW potential, newton_pair is always on
- virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk
- ------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally3_thr(int i, int j, int k, double evdwl, double ecoul,
- double *fj, double *fk, double *drji, double *drki, int tid,
- double THIRD)
-{
- double epairthird,v[6];
-
- if (eflag_either) {
- if (eflag_global) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
- }
- if (eflag_atom) {
- epairthird = THIRD * (evdwl + ecoul);
- eatom_thr[tid][i] += epairthird;
- eatom_thr[tid][j] += epairthird;
- eatom_thr[tid][k] += epairthird;
- }
- }
-
- if (vflag_atom) {
- v[0] = THIRD * (drji[0]*fj[0] + drki[0]*fk[0]);
- v[1] = THIRD * (drji[1]*fj[1] + drki[1]*fk[1]);
- v[2] = THIRD * (drji[2]*fj[2] + drki[2]*fk[2]);
- v[3] = THIRD * (drji[0]*fj[1] + drki[0]*fk[1]);
- v[4] = THIRD * (drji[0]*fj[2] + drki[0]*fk[2]);
- v[5] = THIRD * (drji[1]*fj[2] + drki[1]*fk[2]);
-
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1];
- vatom_thr[tid][i][2] += v[2]; vatom_thr[tid][i][3] += v[3];
- vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2]; vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1];
- vatom_thr[tid][k][2] += v[2]; vatom_thr[tid][k][3] += v[3];
- vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
- }
-}
-
-/* ----------------------------------------------------------------------
- tally eng_vdwl and virial into global and per-atom accumulators
- called by AIREBO potential, newton_pair is always on
- ------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally4_thr(int i, int j, int k, int m, double evdwl,
- double *fi, double *fj, double *fk,
- double *drim, double *drjm, double *drkm, int tid)
-{
- double epairfourth,v[6];
-
- if (eflag_either) {
- if (eflag_global) eng_vdwl_thr[tid] += evdwl;
- if (eflag_atom) {
- epairfourth = 0.25 * evdwl;
- eatom_thr[tid][i] += epairfourth;
- eatom_thr[tid][j] += epairfourth;
- eatom_thr[tid][k] += epairfourth;
- eatom_thr[tid][m] += epairfourth;
- }
- }
-
- if (vflag_atom) {
- v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
- v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
- v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
- v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
- v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
- v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
-
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1];
- vatom_thr[tid][i][2] += v[2]; vatom_thr[tid][i][3] += v[3];
- vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2]; vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1];
- vatom_thr[tid][k][2] += v[2]; vatom_thr[tid][k][3] += v[3];
- vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
- vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1];
- vatom_thr[tid][m][2] += v[2]; vatom_thr[tid][m][3] += v[3];
- vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
- }
-}
-
-/* ----------------------------------------------------------------------
- tally ecoul and virial into each of n atoms in list
- called by TIP4P potential, newton_pair is always on
- changes v values by dividing by n
- ------------------------------------------------------------------------- */
-
-void PairOMPGPU::ev_tally_list_thr(int n, int *list, double ecoul, double *v, int tid)
-{
- int i,j;
-
- if (eflag_either) {
- if (eflag_global) eng_coul_thr[tid] += ecoul;
- if (eflag_atom) {
- double epairatom = ecoul/n;
- for (i = 0; i < n; i++) eatom_thr[tid][list[i]] += epairatom;
- }
- }
-
- if (vflag_either) {
- if (vflag_global) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- }
-
- if (vflag_atom) {
- v[0] /= n;
- v[1] /= n;
- v[2] /= n;
- v[3] /= n;
- v[4] /= n;
- v[5] /= n;
- for (i = 0; i < n; i++) {
- j = list[i];
- vatom_thr[tid][j][0] += v[0];
- vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4];
- vatom_thr[tid][j][5] += v[5];
- }
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- tally virial into per-atom accumulators
- called by AIREBO potential, newton_pair is always on
- fpair is magnitude of force on atom I
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::v_tally2_thr(int i, int j, double fpair, double *drij, int tid)
-{
- double v[6];
-
- v[0] = 0.5 * drij[0]*drij[0]*fpair;
- v[1] = 0.5 * drij[1]*drij[1]*fpair;
- v[2] = 0.5 * drij[2]*drij[2]*fpair;
- v[3] = 0.5 * drij[0]*drij[1]*fpair;
- v[4] = 0.5 * drij[0]*drij[2]*fpair;
- v[5] = 0.5 * drij[1]*drij[2]*fpair;
-
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1];
- vatom_thr[tid][i][2] += v[2]; vatom_thr[tid][i][3] += v[3];
- vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2]; vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
-}
-
-/* ----------------------------------------------------------------------
- tally virial into per-atom accumulators
- called by AIREBO and Tersoff potential, newton_pair is always on
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::v_tally3_thr(int i, int j, int k, double *fi, double *fj,
- double *drik, double *drjk, int tid,
- double THIRD)
-{
- double v[6];
-
- v[0] = THIRD * (drik[0]*fi[0] + drjk[0]*fj[0]);
- v[1] = THIRD * (drik[1]*fi[1] + drjk[1]*fj[1]);
- v[2] = THIRD * (drik[2]*fi[2] + drjk[2]*fj[2]);
- v[3] = THIRD * (drik[0]*fi[1] + drjk[0]*fj[1]);
- v[4] = THIRD * (drik[0]*fi[2] + drjk[0]*fj[2]);
- v[5] = THIRD * (drik[1]*fi[2] + drjk[1]*fj[2]);
-
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1];
- vatom_thr[tid][i][2] += v[2]; vatom_thr[tid][i][3] += v[3];
- vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2]; vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1];
- vatom_thr[tid][k][2] += v[2]; vatom_thr[tid][k][3] += v[3];
- vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
-}
-
-/* ----------------------------------------------------------------------
- tally virial into per-atom accumulators
- called by AIREBO potential, newton_pair is always on
-------------------------------------------------------------------------- */
-
-void PairOMPGPU::v_tally4_thr(int i, int j, int k, int m,
- double *fi, double *fj, double *fk,
- double *drim, double *drjm, double *drkm, int tid)
-{
- double v[6];
-
- v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
- v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
- v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
- v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
- v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
- v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
-
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1];
- vatom_thr[tid][i][2] += v[2]; vatom_thr[tid][i][3] += v[3];
- vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2]; vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1];
- vatom_thr[tid][k][2] += v[2]; vatom_thr[tid][k][3] += v[3];
- vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
- vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1];
- vatom_thr[tid][m][2] += v[2]; vatom_thr[tid][m][3] += v[3];
- vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
-}
-
-/* ----------------------------------------------------------------------
- reduce the per thread accumulated E/V data into the canonical accumulators.
-------------------------------------------------------------------------- */
-void PairOMPGPU::ev_reduce_thr(Pair &p)
-{
- const int ntotal = (force->newton) ?
- (atom->nlocal + atom->nghost) : atom->nlocal;
-
- for (int n = 0; n < _nthreads; ++n) {
- p.eng_vdwl += eng_vdwl_thr[n];
- p.eng_coul += eng_coul_thr[n];
- if (vflag_either) {
- p.virial[0] += virial_thr[n][0];
- p.virial[1] += virial_thr[n][1];
- p.virial[2] += virial_thr[n][2];
- p.virial[3] += virial_thr[n][3];
- p.virial[4] += virial_thr[n][4];
- p.virial[5] += virial_thr[n][5];
- if (vflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- p.vatom[i][0] += vatom_thr[n][i][0];
- p.vatom[i][1] += vatom_thr[n][i][1];
- p.vatom[i][2] += vatom_thr[n][i][2];
- p.vatom[i][3] += vatom_thr[n][i][3];
- p.vatom[i][4] += vatom_thr[n][i][4];
- p.vatom[i][5] += vatom_thr[n][i][5];
- }
- }
- }
- if (eflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- p.eatom[i] += eatom_thr[n][i];
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairOMPGPU::memory_usage()
-{
- double bytes = 0.0;
-
- bytes += _nthreads * (2 + 7) * sizeof(double);
- bytes += _nthreads * maxeatom_thr * sizeof(double);
- bytes += _nthreads * maxvatom_thr * 6 * sizeof(double);
-
- if (f_thr != NULL)
- bytes += _nthreads * _nmax * sizeof(double);
- return bytes;
-}
-
-#endif
diff --git a/src/GPU/pair_omp_gpu.h b/src/GPU/pair_omp_gpu.h
deleted file mode 100644
index 4532cf572..000000000
--- a/src/GPU/pair_omp_gpu.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- c++ -*- -------------------------------------------------------------
- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
- http://lammps.sandia.gov, Sandia National Laboratories
- Steve Plimpton, sjplimp@sandia.gov
-
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
-
- See the README file in the top-level LAMMPS directory.
-------------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
- Modified by Mike for use with GPU library
-------------------------------------------------------------------------- */
-
-#ifndef LMP_PAIR_OMP_GPU_H
-#define LMP_PAIR_OMP_GPU_H
-
-#include "pair.h"
-#include <cassert>
-
-#if defined(_OPENMP)
-#include "atom.h"
-#include "memory.h"
-#include <omp.h>
-#endif
-
-namespace LAMMPS_NS {
-
-#if defined(_OPENMP)
-
-class PairOMPGPU : protected Pointers {
-
- protected:
- double *eng_vdwl_thr; // per thread accumulated vdw energy
- double *eng_coul_thr; // per thread accumulated coulomb energies
- double **virial_thr; // per thread virial
- double **eatom_thr; // per thread per atom energy
- double ***vatom_thr; // per thread per atom virial
- double **f_thr; // per thread force (for thread id>0)
-
- int maxeatom_thr, maxvatom_thr;
- int _nthreads, _nmax;
-
- int eflag_either,eflag_global,eflag_atom;
- int vflag_either,vflag_global,vflag_atom;
-
- public:
- PairOMPGPU(LAMMPS *);
- ~PairOMPGPU();
-
- void free_mem();
- void init_style();
- double memory_usage();
-
- // set loop range for, thread id, and force array offset for threaded runs.
- double **loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
- const int start, const int inum, const int nall)
- {
- if (_nthreads > 1) {
- tid = omp_get_thread_num();
- if (nall > _nmax) {
-#pragma omp master
- memory->grow(f_thr,atom->nmax*(_nthreads-1),3,"pair:f_thr");
-#pragma omp barrier
- if (tid == 0)
- _nmax = atom->nmax;
- }
-
- // each thread works on a fixed chunk of atoms.
- const int idelta = 1 + (inum - start)/_nthreads;
- ifrom = tid * idelta + start;
- ito = ifrom + idelta;
- if (ito > inum)
- ito = inum;
-
- // zero per thread force array
- // keep thread memory access same as for force accumulation
- if (tid > 0) {
- double **f_zero = f_thr + nall * (tid - 1);
- for (int i = 0; i < nall; i++) {
- f_zero[i][0] = 0.0;
- f_zero[i][1] = 0.0;
- f_zero[i][2] = 0.0;
- }
- return f_zero;
- }
- return f;
- } else {
- tid = 0;
- ifrom = start;
- ito = inum;
- return f;
- }
- };
-
- // set loop range for, thread id, and force array offset for threaded runs.
- double **loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
- const int inum, const int nall)
- { return loop_setup_thr(f,ifrom,ito,tid,0,inum,nall); }
-
- // loop setup with full neighbor list and nonzero starting index
- double **loop_setup_thr_full(double **f, int &ifrom, int &ito, int &tid,
- const int start, const int inum, const int nall)
- {
- if (_nthreads > 1) {
- tid = omp_get_thread_num();
-
- // each thread works on a fixed chunk of atoms.
- const int idelta = 1 + (inum - start) / _nthreads;
- ifrom = start + tid * idelta;
- ito = ifrom + idelta;
- if (ito > inum)
- ito = inum;
-
- return f;
-
- } else {
- tid = 0;
- ifrom = start;
- ito = inum;
- return f;
- }
- };
-
- // threading adapted versions of the ev_tally infrastructure.
- void ev_setup_thr(int, int, int, int, int, int, int, int);
- void ev_reduce_thr(Pair &);
- void ev_tally_thr(int, int, int, int, double, double, double,
- double, double, double, int);
- void ev_tally_full_thr(int, double, double, double,
- double, double, double, int);
- void ev_tally_xyz_thr(int, int, int, int, double, double,
- double, double, double, double, double, double, int);
- void ev_tally3_thr(int, int, int, double, double,
- double *, double *, double *, double *, int, double);
- void ev_tally4_thr(int, int, int, int, double,
- double *, double *, double *, double *, double *,
- double *, int);
- void ev_tally_list_thr(int, int *, double, double *, int);
- void v_tally2_thr(int, int, double, double *, int);
- void v_tally3_thr(int, int, int, double *, double *, double *, double *, int,
- double);
- void v_tally4_thr(int, int, int, int, double *, double *, double *,
- double *, double *, double *, int);
-
- // reduce per thread forces into the first part of the force
- // array that is used for the non-threaded parts and reset
- // the temporary storage to 0.0.
- // this is in the header to be inlined.
- // need to post a barrier to wait until all threads are done
- // with computing forces. the reduction can be threaded as well.
- void force_reduce_thr(double **fall, const int nall, const int tid)
- {
- // NOOP in non-threaded execution.
- if (_nthreads == 1) return;
-#pragma omp barrier
- {
- double **f;
- const int idelta = 1 + nall/_nthreads;
- const int ifrom = tid*idelta;
- const int ito = ((ifrom + idelta) > nall) ? nall : (ifrom + idelta);
- for (int n = 1; n < _nthreads; ++n) {
- const int toffs = (n-1)*nall;
- f = f_thr + toffs;
- for (int m = ifrom; m < ito; ++m) {
- fall[m][0] += f[m][0];
- f[m][0] = 0.0;
- fall[m][1] += f[m][1];
- f[m][1] = 0.0;
- fall[m][2] += f[m][2];
- f[m][2] = 0.0;
- }
- }
- }
- };
-
- // reduce per thread density into the first part of the rho
- // array that is used for the non-threaded parts. for use with EAM.
- // this is in the header to be inlined.
- // we need to post a barrier to wait until all threads are done.
- // the reduction can be threaded as well.
- void rho_reduce_thr(double *rho, const int nmax, const int nrange,
- const int tid)
- {
- // NOOP in non-threaded execution.
- if (_nthreads == 1) return;
-#pragma omp barrier
- {
- double *rho_thr;
- const int idelta = 1 + nrange/_nthreads;
- const int ifrom = tid*idelta;
- const int ito = ((ifrom + idelta) > nrange) ? nrange : (ifrom + idelta);
- for (int n = 1; n < _nthreads; ++n) {
- const int toffs = n*nmax;
- rho_thr = rho + toffs;
- for (int m = ifrom; m < ito; ++m)
- rho[m] += rho_thr[m];
- }
- }
- };
-
-};
-
-#else
-
-class PairOMPGPU {
-
- public:
- inline PairOMPGPU(LAMMPS *) {};
- virtual inline ~PairOMPGPU() {};
-
- inline void init_style() {}
- inline double memory_usage() { return 0.0; }
-
- inline void ev_setup_thr(int, int, int, int, int, int, int, int) {}
- inline void ev_reduce_thr(Pair &) {}
- inline double **loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
- const int start, const int inum,
- const int nall)
- {
- ifrom = start;
- ito = inum;
- return f;
- };
-
- inline double **loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
- const int inum, const int nall)
- { return loop_setup_thr(f,ifrom,ito,tid,0,inum,nall); }
-
- // loop setup with full neighbor list and nonzero starting index
- double **loop_setup_thr_full(double **f, int &ifrom, int &ito, int &tid,
- const int start, const int inum, const int nall)
- {
- ifrom = start;
- ito = inum;
- return f;
- };
-
- inline void force_reduce_thr(double **fall, const int nall, const int tid) {};
- inline void rho_reduce_thr(double *rho, const int nmax, const int nrange,
- const int tid) {};
-
-};
-
-#endif
-
-}
-
-#endif
-
diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp
index b707e7fab..9dc736286 100644
--- a/src/GPU/pppm_gpu.cpp
+++ b/src/GPU/pppm_gpu.cpp
@@ -1,843 +1,843 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Mike Brown (ORNL), Axel Kohlmeyer (Temple)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "pppm_gpu.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
#include "gpu_extra.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXORDER 7
#define OFFSET 16384
#define SMALL 0.00001
#define LARGE 10000.0
#define EPS_HOC 1.0e-7
#ifdef FFT_SINGLE
#define ZEROF 0.0f
#define ONEF 1.0f
#else
#define ZEROF 0.0
#define ONEF 1.0
#endif
// External functions from cuda library for atom decomposition
#ifdef FFT_SINGLE
#define PPPM_GPU_API(api) pppm_gpu_ ## api ## _f
#else
#define PPPM_GPU_API(api) pppm_gpu_ ## api ## _d
#endif
FFT_SCALAR* PPPM_GPU_API(init)(const int nlocal, const int nall, FILE *screen,
const int order, const int nxlo_out,
const int nylo_out, const int nzlo_out,
const int nxhi_out, const int nyhi_out,
const int nzhi_out, FFT_SCALAR **rho_coeff,
FFT_SCALAR **_vd_brick, const double slab_volfactor,
const int nx_pppm, const int ny_pppm,
const int nz_pppm, int &success);
void PPPM_GPU_API(clear)(const double poisson_time);
int PPPM_GPU_API(spread)(const int ago, const int nlocal, const int nall,
double **host_x, int *host_type, bool &success,
double *host_q, double *boxlo, const double delxinv,
const double delyinv, const double delzinv);
void PPPM_GPU_API(interp)(const FFT_SCALAR qqrd2e_scale);
double PPPM_GPU_API(bytes)();
/* ---------------------------------------------------------------------- */
PPPMGPU::PPPMGPU(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg)
{
if (narg != 1) error->all(FLERR,"Illegal kspace_style pppm/gpu command");
density_brick_gpu = vd_brick = NULL;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
PPPMGPU::~PPPMGPU()
{
PPPM_GPU_API(clear)(poisson_time);
}
/* ----------------------------------------------------------------------
called once before run
------------------------------------------------------------------------- */
void PPPMGPU::init()
{
PPPM::init();
// GPU precision specific init.
if (order>8)
error->all(FLERR,"Cannot use order greater than 8 with pppm/gpu.");
PPPM_GPU_API(clear)(poisson_time);
int success;
FFT_SCALAR *data, *h_brick;
h_brick = PPPM_GPU_API(init)(atom->nlocal, atom->nlocal+atom->nghost, screen,
order, nxlo_out, nylo_out, nzlo_out, nxhi_out,
nyhi_out, nzhi_out, rho_coeff, &data,
slab_volfactor,nx_pppm,ny_pppm,nz_pppm,success);
GPU_EXTRA::check_flag(success,error,world);
density_brick_gpu =
create_3d_offset(nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:density_brick_gpu",h_brick,1);
vd_brick =
create_3d_offset(nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vd_brick",data,4);
poisson_time=0;
}
/* ----------------------------------------------------------------------
compute the PPPMGPU long-range force, energy, virial
------------------------------------------------------------------------- */
void PPPMGPU::compute(int eflag, int vflag)
{
bool success = true;
int flag=PPPM_GPU_API(spread)(neighbor->ago, atom->nlocal, atom->nlocal +
atom->nghost, atom->x, atom->type, success,
atom->q, domain->boxlo, delxinv, delyinv,
delzinv);
if (!success)
error->one(FLERR,"Out of memory on GPGPU");
if (flag != 0)
error->one(FLERR,"Out of range atoms - cannot compute PPPM");
int i;
// convert atoms from box to lamda coords
if (triclinic == 0) boxlo = domain->boxlo;
else {
boxlo = domain->boxlo_lamda;
domain->x2lamda(atom->nlocal);
}
energy = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
double t3=MPI_Wtime();
// all procs communicate density values from their ghost cells
// to fully sum contribution in their 3d bricks
// remap from 3d decomposition to FFT decomposition
brick2fft();
// compute potential gradient on my FFT grid and
// portion of e_long on this proc's FFT grid
// return gradients (electric fields) in 3d brick decomposition
poisson(eflag,vflag);
// all procs communicate E-field values to fill ghost cells
// surrounding their 3d bricks
fillbrick();
poisson_time+=MPI_Wtime()-t3;
// calculate the force on my particles
- FFT_SCALAR qqrd2e_scale=qqrd2e*scale;
- PPPM_GPU_API(interp)(qqrd2e_scale);
+ FFT_SCALAR qscale = force->qqrd2e * scale;
+ PPPM_GPU_API(interp)(qscale);
// sum energy across procs and add in volume-dependent term
if (eflag) {
double energy_all;
MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
energy = energy_all;
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/1.772453851 +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
- energy *= qqrd2e*scale;
+ energy *= qscale;
}
// sum virial across procs
if (vflag) {
double virial_all[6];
MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world);
- for (i = 0; i < 6; i++) virial[i] = 0.5*qqrd2e*scale*volume*virial_all[i];
+ for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i];
}
// 2d slab correction
if (slabflag) slabcorr(eflag);
// convert atoms back from lamda to box coords
if (triclinic) domain->lamda2x(atom->nlocal);
}
/* ----------------------------------------------------------------------
allocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPMGPU::allocate()
{
memory->create(density_fft,nfft_both,"pppm:density_fft");
memory->create(greensfn,nfft_both,"pppm:greensfn");
memory->create(work1,2*nfft_both,"pppm:work1");
memory->create(work2,2*nfft_both,"pppm:work2");
memory->create(vg,nfft_both,6,"pppm:vg");
memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm:fkx");
memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm:fky");
memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm:fkz");
memory->create(buf1,nbuf,"pppm:buf1");
memory->create(buf2,nbuf,"pppm:buf2");
// summation coeffs
memory->create(gf_b,order,"pppm:gf_b");
memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm:rho1d");
memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm:rho_coeff");
// create 2 FFTs and a Remap
// 1st FFT keeps data in FFT decompostion
// 2nd FFT returns data in 3d brick decomposition
// remap takes data from 3d brick to FFT decomposition
int tmp;
fft1 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
0,0,&tmp);
fft2 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
0,0,&tmp);
remap = new Remap(lmp,world,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
1,0,0,FFT_PRECISION);
}
/* ----------------------------------------------------------------------
deallocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPMGPU::deallocate()
{
destroy_3d_offset(density_brick_gpu,nzlo_out,nylo_out);
destroy_3d_offset(vd_brick,nzlo_out,nylo_out);
memory->destroy(density_fft);
memory->destroy(greensfn);
memory->destroy(work1);
memory->destroy(work2);
memory->destroy(vg);
memory->destroy1d_offset(fkx,nxlo_fft);
memory->destroy1d_offset(fky,nylo_fft);
memory->destroy1d_offset(fkz,nzlo_fft);
memory->destroy(buf1);
memory->destroy(buf2);
memory->destroy(gf_b);
memory->destroy2d_offset(rho1d,-order/2);
memory->destroy2d_offset(rho_coeff,(1-order)/2);
delete fft1;
delete fft2;
delete remap;
}
/* ----------------------------------------------------------------------
ghost-swap to accumulate full density in brick decomposition
remap density from 3d brick decomposition to FFT decomposition
------------------------------------------------------------------------- */
void PPPMGPU::brick2fft()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my ghosts for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// pack my ghosts for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// pack my ghosts for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// pack my ghosts for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// pack my ghosts for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// pack my ghosts for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick_gpu[iz][iy][ix];
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick_gpu[iz][iy][ix] += buf2[n++];
// remap from 3d brick decomposition to FFT decomposition
// copy grabs inner portion of density from 3d brick
// remap could be done as pre-stage of FFT,
// but this works optimally on only double values, not complex values
n = 0;
for (iz = nzlo_in; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_fft[n++] = density_brick_gpu[iz][iy][ix];
remap->perform(density_fft,density_fft,work1);
}
/* ----------------------------------------------------------------------
ghost-swap to fill ghost cells of my brick with field values
------------------------------------------------------------------------- */
void PPPMGPU::fillbrick()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my real cells for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my ghost cells
n = 0;
int x_lo = nxlo_in * 4;
int x_hi = nxhi_in * 4 + 1;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
// pack my real cells for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
// pack my real cells for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
// pack my real cells for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
// pack my real cells for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my ghost cells
n = 0;
x_lo = (nxhi_in-nxhi_ghost+1) * 4;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
x_lo = nxlo_out * 4;
x_hi = nxlo_in * 4;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
// pack my real cells for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my ghost cells
n = 0;
x_lo = x_hi;
x_hi = (nxlo_in+nxlo_ghost) * 4;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
buf1[n++] = vd_brick[iz][iy][ix];
buf1[n++] = vd_brick[iz][iy][ix+1];
buf1[n++] = vd_brick[iz][iy][ix+2];
}
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
x_lo = (nxhi_in + 1) * 4;
x_hi = nxhi_out * 4 + 1;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = x_lo; ix < x_hi; ix+=4) {
vd_brick[iz][iy][ix] = buf2[n++];
vd_brick[iz][iy][ix+1] = buf2[n++];
vd_brick[iz][iy][ix+2] = buf2[n++];
}
}
/* ----------------------------------------------------------------------
FFT-based Poisson solver
------------------------------------------------------------------------- */
void PPPMGPU::poisson(int eflag, int vflag)
{
int i,j,k,n;
double eng;
// transform charge density (r -> k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] = density_fft[i];
work1[n++] = ZEROF;
}
fft1->compute(work1,work1,1);
// if requested, compute energy and virial contribution
double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm);
double s2 = scaleinv*scaleinv;
if (eflag || vflag) {
if (vflag) {
n = 0;
for (i = 0; i < nfft; i++) {
eng = s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
for (j = 0; j < 6; j++) virial[j] += eng*vg[i][j];
energy += eng;
n += 2;
}
} else {
n = 0;
for (i = 0; i < nfft; i++) {
energy +=
s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
n += 2;
}
}
}
// scale by 1/total-grid-pts to get rho(k)
// multiply by Green's function to get V(k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] *= scaleinv * greensfn[i];
work1[n++] *= scaleinv * greensfn[i];
}
// compute gradients of V(r) in each of 3 dims by transformimg -ik*V(k)
// FFT leaves data in 3d brick decomposition
// copy it into inner portion of vdx,vdy,vdz arrays
// x direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkx[i]*work1[n+1];
work2[n+1] = -fkx[i]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
int x_hi = nxhi_in * 4 + 3;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in * 4; i < x_hi; i+=4) {
vd_brick[k][j][i] = work2[n];
n += 2;
}
// y direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fky[j]*work1[n+1];
work2[n+1] = -fky[j]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in * 4 + 1; i < x_hi; i+=4) {
vd_brick[k][j][i] = work2[n];
n += 2;
}
// z direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkz[k]*work1[n+1];
work2[n+1] = -fkz[k]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in * 4 + 2; i < x_hi; i+=4) {
vd_brick[k][j][i] = work2[n];
n += 2;
}
}
/* ----------------------------------------------------------------------
Create array using offsets from pinned memory allocation
------------------------------------------------------------------------- */
FFT_SCALAR ***PPPMGPU::create_3d_offset(int n1lo, int n1hi, int n2lo, int n2hi,
int n3lo, int n3hi, const char *name,
FFT_SCALAR *data, int vec_length)
{
int i,j;
int n1 = n1hi - n1lo + 1;
int n2 = n2hi - n2lo + 1;
int n3 = n3hi - n3lo + 1;
FFT_SCALAR **plane = (FFT_SCALAR **)memory->smalloc(n1*n2*sizeof(FFT_SCALAR *),name);
FFT_SCALAR ***array = (FFT_SCALAR ***)memory->smalloc(n1*sizeof(FFT_SCALAR **),name);
int n = 0;
for (i = 0; i < n1; i++) {
array[i] = &plane[i*n2];
for (j = 0; j < n2; j++) {
plane[i*n2+j] = &data[n];
n += n3*vec_length;
}
}
for (i = 0; i < n1*n2; i++) array[0][i] -= n3lo*vec_length;
for (i = 0; i < n1; i++) array[i] -= n2lo;
return array-n1lo;
}
/* ----------------------------------------------------------------------
3d memory offsets
------------------------------------------------------------------------- */
void PPPMGPU::destroy_3d_offset(FFT_SCALAR ***array, int n1_offset,
int n2_offset)
{
if (array == NULL) return;
memory->sfree(&array[n1_offset][n2_offset]);
memory->sfree(array + n1_offset);
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double PPPMGPU::memory_usage()
{
double bytes = nmax*3 * sizeof(double);
int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
(nzhi_out-nzlo_out+1);
bytes += 4 * nbrick * sizeof(FFT_SCALAR);
bytes += 6 * nfft_both * sizeof(double);
bytes += nfft_both * sizeof(double);
bytes += nfft_both*5 * sizeof(FFT_SCALAR);
bytes += 2 * nbuf * sizeof(double);
return bytes + PPPM_GPU_API(bytes)();
}
diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp
index a418e9352..1afecdf94 100644
--- a/src/GRANULAR/pair_gran_hertz_history.cpp
+++ b/src/GRANULAR/pair_gran_hertz_history.cpp
@@ -1,278 +1,424 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Leo Silbert (SNL), Gary Grest (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "pair_gran_hertz_history.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "neigh_list.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHertzHistory::PairGranHertzHistory(LAMMPS *lmp) :
PairGranHookeHistory(lmp) {}
/* ---------------------------------------------------------------------- */
void PairGranHertzHistory::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3;
double shrmag,rsht,polyhertz;
int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch;
double *shear,*allshear,**firstshear;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
int shearupdate = 0;
if (update->ntimestep > laststep) shearupdate = 1;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
firsttouch = list->listgranhistory->firstneigh;
firstshear = list->listgranhistory->firstdouble;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
touch = firsttouch[i];
allshear = firstshear[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq >= radsum*radsum) {
// unset non-touching neighbors
touch[jj] = 0;
shear = &allshear[3*jj];
shear[0] = 0.0;
shear[1] = 0.0;
shear[2] = 0.0;
} else {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal force = Hertzian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
polyhertz = sqrt((radsum-r)*radi*radj / radsum);
ccel *= polyhertz;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// shear history effects
touch[jj] = 1;
shear = &allshear[3*jj];
if (shearupdate) {
shear[0] += vtr1*dt;
shear[1] += vtr2*dt;
shear[2] += vtr3*dt;
}
shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
shear[2]*shear[2]);
// rotate shear displacements
rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
rsht *= rsqinv;
if (shearupdate) {
shear[0] -= rsht*delx;
shear[1] -= rsht*dely;
shear[2] -= rsht*delz;
}
// tangential forces = shear + tangential velocity damping
fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1);
fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2);
fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3);
// rescale frictional displacements and forces if needed
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
fn = xmu * fabs(ccel*r);
if (fs > fn) {
if (shrmag != 0.0) {
shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) -
meff*gammat*vtr1/kt;
shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) -
meff*gammat*vtr2/kt;
shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) -
meff*gammat*vtr3/kt;
fs1 *= fn/fs;
fs2 *= fn/fs;
fs3 *= fn/fs;
} else fs1 = fs2 = fs3 = 0.0;
}
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
torque[i][0] -= radi*tor1;
torque[i][1] -= radi*tor2;
torque[i][2] -= radi*tor3;
if (j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (evflag) ev_tally_xyz(i,j,nlocal,0,
0.0,0.0,fx,fy,fz,delx,dely,delz);
}
}
}
laststep = update->ntimestep;
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairGranHertzHistory::settings(int narg, char **arg)
{
if (narg != 6) error->all(FLERR,"Illegal pair_style command");
kn = force->numeric(arg[0]);
if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0;
else kt = force->numeric(arg[1]);
gamman = force->numeric(arg[2]);
if (strcmp(arg[3],"NULL") == 0) gammat = 0.5 * gamman;
else gammat = force->numeric(arg[3]);
xmu = force->numeric(arg[4]);
dampflag = force->inumeric(arg[5]);
if (dampflag == 0) gammat = 0.0;
if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 ||
xmu < 0.0 || xmu > 1.0 || dampflag < 0 || dampflag > 1)
error->all(FLERR,"Illegal pair_style command");
// convert Kn and Kt from pressure units to force/distance^2
kn /= force->nktv2p;
kt /= force->nktv2p;
}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHertzHistory::single(int i, int j, int itype, int jtype,
+ double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double radi,radj,radsum;
+ double r,rinv,rsqinv,delx,dely,delz;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3;
+ double meff,damp,ccel,polyhertz;
+ double vtr1,vtr2,vtr3,vrel,shrmag,rsht;
+ double fs1,fs2,fs3,fs,fn;
+
+ double *radius = atom->radius;
+ radi = radius[i];
+ radj = radius[j];
+ radsum = radi + radj;
+
+ if (rsq >= radsum*radsum) {
+ fforce = 0.0;
+ svector[0] = svector[1] = svector[2] = svector[3] = 0.0;
+ return 0.0;
+ }
+
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ double **v = atom->v;
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ double **x = atom->x;
+ delx = x[i][0] - x[j][0];
+ dely = x[i][1] - x[j][1];
+ delz = x[i][2] - x[j][2];
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ double **omega = atom->omega;
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal force = Hertzian contact + normal velocity damping
+
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *mask = atom->mask;
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+ polyhertz = sqrt((radsum-r)*radi*radj / radsum);
+ ccel *= polyhertz;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // shear history effects
+ // neighprev = index of found neigh on previous call
+ // search entire jnum list of neighbors of I for neighbor J
+ // start from neighprev, since will typically be next neighbor
+ // reset neighprev to 0 as necessary
+
+ int *jlist = list->firstneigh[i];
+ int jnum = list->numneigh[i];
+ int *touch = list->listgranhistory->firstneigh[i];
+ double *allshear = list->listgranhistory->firstdouble[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ neighprev++;
+ if (neighprev >= jnum) neighprev = 0;
+ if (touch[neighprev] == j) break;
+ }
+
+ double *shear = &allshear[3*neighprev];
+ shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
+ shear[2]*shear[2]);
+
+ // rotate shear displacements
+
+ rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
+ rsht *= rsqinv;
+
+ // tangential forces = shear + tangential velocity damping
+
+ fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1);
+ fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2);
+ fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3);
+
+ // rescale frictional displacements and forces if needed
+
+ fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
+ fn = xmu * fabs(ccel*r);
+
+ if (fs > fn) {
+ if (shrmag != 0.0) {
+ fs1 *= fn/fs;
+ fs2 *= fn/fs;
+ fs3 *= fn/fs;
+ fs *= fn/fs;
+ } else fs1 = fs2 = fs3 = fs = 0.0;
+ }
+
+ // set all forces and return no energy
+
+ fforce = ccel;
+ svector[0] = fs1;
+ svector[1] = fs2;
+ svector[2] = fs3;
+ svector[3] = fs;
+ return 0.0;
+}
diff --git a/src/GRANULAR/pair_gran_hertz_history.h b/src/GRANULAR/pair_gran_hertz_history.h
index 5c5877a16..1b86354fb 100644
--- a/src/GRANULAR/pair_gran_hertz_history.h
+++ b/src/GRANULAR/pair_gran_hertz_history.h
@@ -1,37 +1,38 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hertz/history,PairGranHertzHistory)
#else
#ifndef LMP_PAIR_GRAN_HERTZ_HISTORY_H
#define LMP_PAIR_GRAN_HERTZ_HISTORY_H
#include "pair_gran_hooke_history.h"
namespace LAMMPS_NS {
class PairGranHertzHistory : public PairGranHookeHistory {
public:
PairGranHertzHistory(class LAMMPS *);
virtual void compute(int, int);
void settings(int, char **);
+ double single(int, int, int, int, double, double, double, double &);
};
}
#endif
#endif
diff --git a/src/GRANULAR/pair_gran_hooke.cpp b/src/GRANULAR/pair_gran_hooke.cpp
index 95651e760..4f2c00e27 100644
--- a/src/GRANULAR/pair_gran_hooke.cpp
+++ b/src/GRANULAR/pair_gran_hooke.cpp
@@ -1,193 +1,301 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Leo Silbert (SNL), Gary Grest (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "pair_gran_hooke.h"
#include "atom.h"
#include "force.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHooke::PairGranHooke(LAMMPS *lmp) : PairGranHookeHistory(lmp)
{
no_virial_fdotr_compute = 0;
history = 0;
}
/* ---------------------------------------------------------------------- */
void PairGranHooke::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,ft,fs1,fs2,fs3;
int *ilist,*jlist,*numneigh,**firstneigh;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq < radsum*radsum) {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal forces = Hookian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// force normalization
fn = xmu * fabs(ccel*r);
fs = meff*gammat*vrel;
if (vrel != 0.0) ft = MIN(fn,fs) / vrel;
else ft = 0.0;
// tangential force due to tangential velocity damping
fs1 = -ft*vtr1;
fs2 = -ft*vtr2;
fs3 = -ft*vtr3;
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
torque[i][0] -= radi*tor1;
torque[i][1] -= radi*tor2;
torque[i][2] -= radi*tor3;
if (newton_pair || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,fx,fy,fz,delx,dely,delz);
}
}
}
if (vflag_fdotr) virial_fdotr_compute();
}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHooke::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double radi,radj,radsum,r,rinv,rsqinv;
+ double delx,dely,delz;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3;
+ double vtr1,vtr2,vtr3,vrel;
+ double meff,damp,ccel;
+ double fn,fs,ft,fs1,fs2,fs3;
+
+ double *radius = atom->radius;
+ radi = radius[i];
+ radj = radius[j];
+ radsum = radi + radj;
+
+ // zero out forces if caller requests non-touching pair outside cutoff
+
+ if (rsq >= radsum*radsum) {
+ fforce = 0.0;
+ svector[0] = svector[1] = svector[2] = svector[3] = 0.0;
+ return 0.0;
+ }
+
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ double **v = atom->v;
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ double **x = atom->x;
+ delx = x[i][0] - x[j][0];
+ dely = x[i][1] - x[j][1];
+ delz = x[i][2] - x[j][2];
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ double **omega = atom->omega;
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal forces = Hookian contact + normal velocity damping
+
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *mask = atom->mask;
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // force normalization
+
+ fn = xmu * fabs(ccel*r);
+ fs = meff*gammat*vrel;
+ if (vrel != 0.0) ft = MIN(fn,fs) / vrel;
+ else ft = 0.0;
+
+ // set all forces and return no energy
+
+ fforce = ccel;
+ svector[0] = -ft*vtr1;
+ svector[1] = -ft*vtr2;
+ svector[2] = -ft*vtr3;
+ svector[3] = sqrt(svector[0]*svector[0] +
+ svector[1]*svector[1] +
+ svector[2]*svector[2]);
+ return 0.0;
+}
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/GRANULAR/pair_gran_hooke.h
index d5cff796f..20c2c3c1b 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/GRANULAR/pair_gran_hooke.h
@@ -1,36 +1,37 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hooke,PairGranHooke)
#else
#ifndef LMP_PAIR_GRAN_HOOKE_H
#define LMP_PAIR_GRAN_HOOKE_H
#include "pair_gran_hooke_history.h"
namespace LAMMPS_NS {
class PairGranHooke : public PairGranHookeHistory {
public:
PairGranHooke(class LAMMPS *);
virtual void compute(int, int);
+ double single(int, int, int, int, double, double, double, double &);
};
}
#endif
#endif
diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp
index 847ed84a5..7e8cbc22f 100644
--- a/src/GRANULAR/pair_gran_hooke_history.cpp
+++ b/src/GRANULAR/pair_gran_hooke_history.cpp
@@ -1,547 +1,696 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Leo Silbert (SNL), Gary Grest (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_gran_hooke_history.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_pour.h"
#include "fix_shear_history.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp)
{
- single_enable = 0;
+ single_enable = 1;
no_virial_fdotr_compute = 1;
history = 1;
fix_history = NULL;
suffix = NULL;
+ single_extra = 4;
+ svector = new double[4];
+
laststep = -1;
+ neighprev = 0;
}
/* ---------------------------------------------------------------------- */
PairGranHookeHistory::~PairGranHookeHistory()
{
+ delete [] svector;
if (fix_history) modify->delete_fix("SHEAR_HISTORY");
if (suffix) delete[] suffix;
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
delete [] onerad_dynamic;
delete [] onerad_frozen;
delete [] maxrad_dynamic;
delete [] maxrad_frozen;
}
}
/* ---------------------------------------------------------------------- */
void PairGranHookeHistory::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3;
double shrmag,rsht;
int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch;
double *shear,*allshear,**firstshear;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
int shearupdate = 0;
if (update->ntimestep > laststep) shearupdate = 1;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **torque = atom->torque;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
firsttouch = listgranhistory->firstneigh;
firstshear = listgranhistory->firstdouble;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
touch = firsttouch[i];
allshear = firstshear[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq >= radsum*radsum) {
// unset non-touching neighbors
touch[jj] = 0;
shear = &allshear[3*jj];
shear[0] = 0.0;
shear[1] = 0.0;
shear[2] = 0.0;
} else {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal forces = Hookian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// shear history effects
touch[jj] = 1;
shear = &allshear[3*jj];
if (shearupdate) {
shear[0] += vtr1*dt;
shear[1] += vtr2*dt;
shear[2] += vtr3*dt;
}
shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
shear[2]*shear[2]);
// rotate shear displacements
rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
rsht *= rsqinv;
if (shearupdate) {
shear[0] -= rsht*delx;
shear[1] -= rsht*dely;
shear[2] -= rsht*delz;
}
// tangential forces = shear + tangential velocity damping
fs1 = - (kt*shear[0] + meff*gammat*vtr1);
fs2 = - (kt*shear[1] + meff*gammat*vtr2);
fs3 = - (kt*shear[2] + meff*gammat*vtr3);
// rescale frictional displacements and forces if needed
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
fn = xmu * fabs(ccel*r);
if (fs > fn) {
if (shrmag != 0.0) {
shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) -
meff*gammat*vtr1/kt;
shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) -
meff*gammat*vtr2/kt;
shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) -
meff*gammat*vtr3/kt;
fs1 *= fn/fs;
fs2 *= fn/fs;
fs3 *= fn/fs;
} else fs1 = fs2 = fs3 = 0.0;
}
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
torque[i][0] -= radi*tor1;
torque[i][1] -= radi*tor2;
torque[i][2] -= radi*tor3;
if (j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (evflag) ev_tally_xyz(i,j,nlocal,0,
0.0,0.0,fx,fy,fz,delx,dely,delz);
}
}
}
laststep = update->ntimestep;
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairGranHookeHistory::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
onerad_dynamic = new double[n+1];
onerad_frozen = new double[n+1];
maxrad_dynamic = new double[n+1];
maxrad_frozen = new double[n+1];
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairGranHookeHistory::settings(int narg, char **arg)
{
if (narg != 6) error->all(FLERR,"Illegal pair_style command");
kn = force->numeric(arg[0]);
if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0;
else kt = force->numeric(arg[1]);
gamman = force->numeric(arg[2]);
if (strcmp(arg[3],"NULL") == 0) gammat = 0.5 * gamman;
else gammat = force->numeric(arg[3]);
xmu = force->numeric(arg[4]);
dampflag = force->inumeric(arg[5]);
if (dampflag == 0) gammat = 0.0;
if (kn < 0.0 || kt < 0.0 || gamman < 0.0 || gammat < 0.0 ||
xmu < 0.0 || xmu > 1.0 || dampflag < 0 || dampflag > 1)
error->all(FLERR,"Illegal pair_style command");
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairGranHookeHistory::coeff(int narg, char **arg)
{
if (narg > 2) error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairGranHookeHistory::init_style()
{
int i;
// error and warning checks
if (!atom->sphere_flag)
error->all(FLERR,"Pair granular requires atom style sphere");
if (comm->ghost_velocity == 0)
error->all(FLERR,"Pair granular requires ghost atoms store velocity");
// need a half neigh list and optionally a granular history neigh list
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->gran = 1;
if (history) {
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 1;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->granhistory = 1;
neighbor->requests[irequest]->dnum = 3;
}
dt = update->dt;
// if shear history is stored:
// check if newton flag is valid
// if first init, create Fix needed for storing shear history
if (history && force->newton_pair == 1)
error->all(FLERR,"Pair granular with shear history requires newton pair off");
if (history && fix_history == NULL) {
char **fixarg = new char*[3];
fixarg[0] = (char *) "SHEAR_HISTORY";
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "SHEAR_HISTORY";
modify->add_fix(3,fixarg,suffix);
delete [] fixarg;
fix_history = (FixShearHistory *) modify->fix[modify->nfix-1];
fix_history->pair = this;
}
// check for Fix freeze and set freeze_group_bit
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"freeze") == 0) break;
if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit;
else freeze_group_bit = 0;
// check for Fix pour and set pour_type and pour_maxdiam
int pour_type = 0;
double pour_maxrad = 0.0;
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"pour") == 0) break;
if (i < modify->nfix) {
pour_type = ((FixPour *) modify->fix[i])->ntype;
pour_maxrad = ((FixPour *) modify->fix[i])->radius_hi;
}
// set maxrad_dynamic and maxrad_frozen for each type
// include future Fix pour particles as dynamic
for (i = 1; i <= atom->ntypes; i++)
onerad_dynamic[i] = onerad_frozen[i] = 0.0;
if (pour_type) onerad_dynamic[pour_type] = pour_maxrad;
double *radius = atom->radius;
int *mask = atom->mask;
int *type = atom->type;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (mask[i] & freeze_group_bit)
onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]);
else
onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]);
MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes,
MPI_DOUBLE,MPI_MAX,world);
MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes,
MPI_DOUBLE,MPI_MAX,world);
}
/* ----------------------------------------------------------------------
neighbor callback to inform pair style of neighbor list to use
optional granular history list
------------------------------------------------------------------------- */
void PairGranHookeHistory::init_list(int id, NeighList *ptr)
{
if (id == 0) list = ptr;
else if (id == 1) listgranhistory = ptr;
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairGranHookeHistory::init_one(int i, int j)
{
if (!allocated) allocate();
// cutoff = sum of max I,J radii for
// dynamic/dynamic & dynamic/frozen interactions, but not frozen/frozen
double cutoff = maxrad_dynamic[i]+maxrad_dynamic[j];
cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]);
cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]);
return cutoff;
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairGranHookeHistory::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++)
fwrite(&setflag[i][j],sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairGranHookeHistory::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairGranHookeHistory::write_restart_settings(FILE *fp)
{
fwrite(&kn,sizeof(double),1,fp);
fwrite(&kt,sizeof(double),1,fp);
fwrite(&gamman,sizeof(double),1,fp);
fwrite(&gammat,sizeof(double),1,fp);
fwrite(&xmu,sizeof(double),1,fp);
fwrite(&dampflag,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairGranHookeHistory::read_restart_settings(FILE *fp)
{
if (comm->me == 0) {
fread(&kn,sizeof(double),1,fp);
fread(&kt,sizeof(double),1,fp);
fread(&gamman,sizeof(double),1,fp);
fread(&gammat,sizeof(double),1,fp);
fread(&xmu,sizeof(double),1,fp);
fread(&dampflag,sizeof(int),1,fp);
}
MPI_Bcast(&kn,1,MPI_DOUBLE,0,world);
MPI_Bcast(&kt,1,MPI_DOUBLE,0,world);
MPI_Bcast(&gamman,1,MPI_DOUBLE,0,world);
MPI_Bcast(&gammat,1,MPI_DOUBLE,0,world);
MPI_Bcast(&xmu,1,MPI_DOUBLE,0,world);
MPI_Bcast(&dampflag,1,MPI_INT,0,world);
}
/* ---------------------------------------------------------------------- */
void PairGranHookeHistory::reset_dt()
{
dt = update->dt;
}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGranHookeHistory::single(int i, int j, int itype, int jtype,
+ double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double radi,radj,radsum;
+ double r,rinv,rsqinv,delx,dely,delz;
+ double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3;
+ double meff,damp,ccel,polyhertz;
+ double vtr1,vtr2,vtr3,vrel,shrmag,rsht;
+ double fs1,fs2,fs3,fs,fn;
+
+ double *radius = atom->radius;
+ radi = radius[i];
+ radj = radius[j];
+ radsum = radi + radj;
+
+ if (rsq >= radsum*radsum) {
+ fforce = 0.0;
+ svector[0] = svector[1] = svector[2] = svector[3] = 0.0;
+ return 0.0;
+ }
+
+ r = sqrt(rsq);
+ rinv = 1.0/r;
+ rsqinv = 1.0/rsq;
+
+ // relative translational velocity
+
+ double **v = atom->v;
+ vr1 = v[i][0] - v[j][0];
+ vr2 = v[i][1] - v[j][1];
+ vr3 = v[i][2] - v[j][2];
+
+ // normal component
+
+ double **x = atom->x;
+ delx = x[i][0] - x[j][0];
+ dely = x[i][1] - x[j][1];
+ delz = x[i][2] - x[j][2];
+
+ vnnr = vr1*delx + vr2*dely + vr3*delz;
+ vn1 = delx*vnnr * rsqinv;
+ vn2 = dely*vnnr * rsqinv;
+ vn3 = delz*vnnr * rsqinv;
+
+ // tangential component
+
+ vt1 = vr1 - vn1;
+ vt2 = vr2 - vn2;
+ vt3 = vr3 - vn3;
+
+ // relative rotational velocity
+
+ double **omega = atom->omega;
+ wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
+ wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
+ wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
+
+ // normal force = Hertzian contact + normal velocity damping
+
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *mask = atom->mask;
+
+ if (rmass) {
+ meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
+ if (mask[i] & freeze_group_bit) meff = rmass[j];
+ if (mask[j] & freeze_group_bit) meff = rmass[i];
+ } else {
+ meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
+ if (mask[i] & freeze_group_bit) meff = mass[jtype];
+ if (mask[j] & freeze_group_bit) meff = mass[itype];
+ }
+
+ damp = meff*gamman*vnnr*rsqinv;
+ ccel = kn*(radsum-r)*rinv - damp;
+
+ // relative velocities
+
+ vtr1 = vt1 - (delz*wr2-dely*wr3);
+ vtr2 = vt2 - (delx*wr3-delz*wr1);
+ vtr3 = vt3 - (dely*wr1-delx*wr2);
+ vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
+ vrel = sqrt(vrel);
+
+ // shear history effects
+ // neighprev = index of found neigh on previous call
+ // search entire jnum list of neighbors of I for neighbor J
+ // start from neighprev, since will typically be next neighbor
+ // reset neighprev to 0 as necessary
+
+ int *jlist = list->firstneigh[i];
+ int jnum = list->numneigh[i];
+ int *touch = list->listgranhistory->firstneigh[i];
+ double *allshear = list->listgranhistory->firstdouble[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ neighprev++;
+ if (neighprev >= jnum) neighprev = 0;
+ if (touch[neighprev] == j) break;
+ }
+
+ double *shear = &allshear[3*neighprev];
+ shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
+ shear[2]*shear[2]);
+
+ // rotate shear displacements
+
+ rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
+ rsht *= rsqinv;
+
+ // tangential forces = shear + tangential velocity damping
+
+ fs1 = - (kt*shear[0] + meff*gammat*vtr1);
+ fs2 = - (kt*shear[1] + meff*gammat*vtr2);
+ fs3 = - (kt*shear[2] + meff*gammat*vtr3);
+
+ // rescale frictional displacements and forces if needed
+
+ fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
+ fn = xmu * fabs(ccel*r);
+
+ if (fs > fn) {
+ if (shrmag != 0.0) {
+ fs1 *= fn/fs;
+ fs2 *= fn/fs;
+ fs3 *= fn/fs;
+ fs *= fn/fs;
+ } else fs1 = fs2 = fs3 = fs = 0.0;
+ }
+
+ // set all forces and return no energy
+
+ fforce = ccel;
+ svector[0] = fs1;
+ svector[1] = fs2;
+ svector[2] = fs3;
+ svector[3] = fs;
+ return 0.0;
+}
diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h
index e645c12bf..2e88fc2d4 100644
--- a/src/GRANULAR/pair_gran_hooke_history.h
+++ b/src/GRANULAR/pair_gran_hooke_history.h
@@ -1,64 +1,67 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hooke/history,PairGranHookeHistory)
#else
#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_H
#define LMP_PAIR_GRAN_HOOKE_HISTORY_H
#include "pair.h"
namespace LAMMPS_NS {
class PairGranHookeHistory : public Pair {
public:
PairGranHookeHistory(class LAMMPS *);
virtual ~PairGranHookeHistory();
virtual void compute(int, int);
virtual void settings(int, char **);
void coeff(int, char **);
void init_style();
void init_list(int, class NeighList *);
double init_one(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
+ double single(int, int, int, int, double, double, double, double &);
void reset_dt();
protected:
double kn,kt,gamman,gammat,xmu;
int dampflag;
double dt;
int freeze_group_bit;
int history;
bigint laststep;
class FixShearHistory *fix_history;
char *suffix;
double *onerad_dynamic,*onerad_frozen;
double *maxrad_dynamic,*maxrad_frozen;
+ int neighprev;
+
void allocate();
};
}
#endif
#endif
diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp
index b6cff3d93..4e2782ff0 100644
--- a/src/KSPACE/ewald.cpp
+++ b/src/KSPACE/ewald.cpp
@@ -1,844 +1,846 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Roy Pollock (LLNL), Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "ewald.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.00001
/* ---------------------------------------------------------------------- */
Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
{
if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command");
precision = atof(arg[0]);
kmax = 0;
kxvecs = kyvecs = kzvecs = NULL;
ug = NULL;
eg = vg = NULL;
sfacrl = sfacim = sfacrl_all = sfacim_all = NULL;
nmax = 0;
ek = NULL;
cs = sn = NULL;
kcount = 0;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
Ewald::~Ewald()
{
deallocate();
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
}
/* ---------------------------------------------------------------------- */
void Ewald::init()
{
if (comm->me == 0) {
if (screen) fprintf(screen,"Ewald initialization ...\n");
if (logfile) fprintf(logfile,"Ewald initialization ...\n");
}
// error check
if (domain->triclinic) error->all(FLERR,"Cannot use Ewald with triclinic box");
if (domain->dimension == 2)
error->all(FLERR,"Cannot use Ewald with 2d simulation");
if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q");
if (slabflag == 0 && domain->nonperiodic > 0)
error->all(FLERR,"Cannot use nonperiodic boundaries with Ewald");
if (slabflag == 1) {
if (domain->xperiodic != 1 || domain->yperiodic != 1 ||
domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1)
error->all(FLERR,"Incorrect boundaries with slab Ewald");
}
// extract short-range Coulombic cutoff from pair style
- qqrd2e = force->qqrd2e;
scale = 1.0;
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
if (p_cutoff == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
double cutoff = *p_cutoff;
qsum = qsqsum = 0.0;
for (int i = 0; i < atom->nlocal; i++) {
qsum += atom->q[i];
qsqsum += atom->q[i]*atom->q[i];
}
double tmp;
MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsum = tmp;
MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsqsum = tmp;
if (qsqsum == 0.0)
error->all(FLERR,"Cannot use kspace solver on system with no charge");
if (fabs(qsum) > SMALL && comm->me == 0) {
char str[128];
sprintf(str,"System is not charge neutral, net charge = %g",qsum);
error->warning(FLERR,str);
}
// setup K-space resolution
if (!gewaldflag) g_ewald = (1.35 - 0.15*log(precision))/cutoff;
gsqmx = -4.0*g_ewald*g_ewald*log(precision);
if (comm->me == 0) {
if (screen) fprintf(screen," G vector = %g\n",g_ewald);
if (logfile) fprintf(logfile," G vector = %g\n",g_ewald);
}
// setup Ewald coefficients so can print stats
setup();
if (comm->me == 0) {
if (screen) fprintf(screen," vectors: actual 1d max = %d %d %d\n",
kcount,kmax,kmax3d);
if (logfile) fprintf(logfile," vectors: actual 1d max = %d %d %d\n",
kcount,kmax,kmax3d);
}
}
/* ----------------------------------------------------------------------
adjust Ewald coeffs, called initially and whenever volume has changed
------------------------------------------------------------------------- */
void Ewald::setup()
{
// volume-dependent factors
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
// adjustment of z dimension for 2d slab Ewald
// 3d Ewald just uses zprd since slab_volfactor = 1.0
double zprd_slab = zprd*slab_volfactor;
volume = xprd * yprd * zprd_slab;
unitk[0] = 2.0*MY_PI/xprd;
unitk[1] = 2.0*MY_PI/yprd;
unitk[2] = 2.0*MY_PI/zprd_slab;
// determine kmax
// function of current box size, precision, G_ewald (short-range cutoff)
int nkxmx = static_cast<int> ((g_ewald*xprd/MY_PI) * sqrt(-log(precision)));
int nkymx = static_cast<int> ((g_ewald*yprd/MY_PI) * sqrt(-log(precision)));
int nkzmx =
static_cast<int> ((g_ewald*zprd_slab/MY_PI) * sqrt(-log(precision)));
int kmax_old = kmax;
kmax = MAX(nkxmx,nkymx);
kmax = MAX(kmax,nkzmx);
kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax;
// if size has grown, reallocate k-dependent and nlocal-dependent arrays
if (kmax > kmax_old) {
deallocate();
allocate();
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
nmax = atom->nmax;
memory->create(ek,nmax,3,"ewald:ek");
memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs");
memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn");
kmax_created = kmax;
}
// pre-compute Ewald coefficients
coeffs();
}
/* ----------------------------------------------------------------------
compute the Ewald long-range force, energy, virial
------------------------------------------------------------------------- */
void Ewald::compute(int eflag, int vflag)
{
int i,k,n;
energy = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0;
// extend size of per-atom arrays if necessary
if (atom->nlocal > nmax) {
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
nmax = atom->nmax;
memory->create(ek,nmax,3,"ewald:ek");
memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs");
memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn");
kmax_created = kmax;
}
// partial structure factors on each processor
// total structure factor by summing over procs
eik_dot_r();
MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world);
// K-space portion of electric field
// double loop over K-vectors and local atoms
double **f = atom->f;
double *q = atom->q;
int nlocal = atom->nlocal;
int kx,ky,kz;
double cypz,sypz,exprl,expim,partial;
for (i = 0; i < nlocal; i++) {
ek[i][0] = 0.0;
ek[i][1] = 0.0;
ek[i][2] = 0.0;
}
for (k = 0; k < kcount; k++) {
kx = kxvecs[k];
ky = kyvecs[k];
kz = kzvecs[k];
for (i = 0; i < nlocal; i++) {
cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i];
sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i];
exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz;
expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz;
partial = expim*sfacrl_all[k] - exprl*sfacim_all[k];
ek[i][0] += partial*eg[k][0];
ek[i][1] += partial*eg[k][1];
ek[i][2] += partial*eg[k][2];
}
}
// convert E-field to force
+ const double qscale = force->qqrd2e * scale;
+
for (i = 0; i < nlocal; i++) {
- f[i][0] += qqrd2e*scale * q[i]*ek[i][0];
- f[i][1] += qqrd2e*scale * q[i]*ek[i][1];
- f[i][2] += qqrd2e*scale * q[i]*ek[i][2];
+ f[i][0] += qscale * q[i]*ek[i][0];
+ f[i][1] += qscale * q[i]*ek[i][1];
+ f[i][2] += qscale * q[i]*ek[i][2];
}
// energy if requested
if (eflag) {
for (k = 0; k < kcount; k++)
energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] +
sfacim_all[k]*sfacim_all[k]);
energy -= g_ewald*qsqsum/MY_PIS +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
- energy *= qqrd2e*scale;
+ energy *= qscale;
}
// virial if requested
if (vflag) {
double uk;
for (k = 0; k < kcount; k++) {
uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]);
for (n = 0; n < 6; n++) virial[n] += uk*vg[k][n];
}
- for (n = 0; n < 6; n++) virial[n] *= qqrd2e*scale;
+ for (n = 0; n < 6; n++) virial[n] *= qscale;
}
if (slabflag) slabcorr(eflag);
}
/* ---------------------------------------------------------------------- */
void Ewald::eik_dot_r()
{
int i,k,l,m,n,ic;
double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4;
double sqk,clpm,slpm;
double **x = atom->x;
double *q = atom->q;
int nlocal = atom->nlocal;
n = 0;
// (k,0,0), (0,l,0), (0,0,m)
for (ic = 0; ic < 3; ic++) {
sqk = unitk[ic]*unitk[ic];
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
for (i = 0; i < nlocal; i++) {
cs[0][ic][i] = 1.0;
sn[0][ic][i] = 0.0;
cs[1][ic][i] = cos(unitk[ic]*x[i][ic]);
sn[1][ic][i] = sin(unitk[ic]*x[i][ic]);
cs[-1][ic][i] = cs[1][ic][i];
sn[-1][ic][i] = -sn[1][ic][i];
cstr1 += q[i]*cs[1][ic][i];
sstr1 += q[i]*sn[1][ic][i];
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
}
}
for (m = 2; m <= kmax; m++) {
for (ic = 0; ic < 3; ic++) {
sqk = m*unitk[ic] * m*unitk[ic];
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
for (i = 0; i < nlocal; i++) {
cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] -
sn[m-1][ic][i]*sn[1][ic][i];
sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] +
cs[m-1][ic][i]*sn[1][ic][i];
cs[-m][ic][i] = cs[m][ic][i];
sn[-m][ic][i] = -sn[m][ic][i];
cstr1 += q[i]*cs[m][ic][i];
sstr1 += q[i]*sn[m][ic][i];
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
}
}
}
// 1 = (k,l,0), 2 = (k,-l,0)
for (k = 1; k <= kmax; k++) {
for (l = 1; l <= kmax; l++) {
sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[k][0][i]*cs[l][1][i] - sn[k][0][i]*sn[l][1][i]);
sstr1 += q[i]*(sn[k][0][i]*cs[l][1][i] + cs[k][0][i]*sn[l][1][i]);
cstr2 += q[i]*(cs[k][0][i]*cs[l][1][i] + sn[k][0][i]*sn[l][1][i]);
sstr2 += q[i]*(sn[k][0][i]*cs[l][1][i] - cs[k][0][i]*sn[l][1][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (0,l,m), 2 = (0,l,-m)
for (l = 1; l <= kmax; l++) {
for (m = 1; m <= kmax; m++) {
sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]);
sstr1 += q[i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]);
cstr2 += q[i]*(cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]);
sstr2 += q[i]*(sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (k,0,m), 2 = (k,0,-m)
for (k = 1; k <= kmax; k++) {
for (m = 1; m <= kmax; m++) {
sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[k][0][i]*cs[m][2][i] - sn[k][0][i]*sn[m][2][i]);
sstr1 += q[i]*(sn[k][0][i]*cs[m][2][i] + cs[k][0][i]*sn[m][2][i]);
cstr2 += q[i]*(cs[k][0][i]*cs[m][2][i] + sn[k][0][i]*sn[m][2][i]);
sstr2 += q[i]*(sn[k][0][i]*cs[m][2][i] - cs[k][0][i]*sn[m][2][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m)
for (k = 1; k <= kmax; k++) {
for (l = 1; l <= kmax; l++) {
for (m = 1; m <= kmax; m++) {
sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) +
(m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
cstr3 = 0.0;
sstr3 = 0.0;
cstr4 = 0.0;
sstr4 = 0.0;
for (i = 0; i < nlocal; i++) {
clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
cstr1 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr1 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
cstr2 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr2 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
cstr3 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr3 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
cstr4 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr4 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
sfacrl[n] = cstr3;
sfacim[n++] = sstr3;
sfacrl[n] = cstr4;
sfacim[n++] = sstr4;
}
}
}
}
}
/* ----------------------------------------------------------------------
pre-compute coefficients for each Ewald K-vector
------------------------------------------------------------------------- */
void Ewald::coeffs()
{
int k,l,m;
double sqk,vterm;
double unitkx = unitk[0];
double unitky = unitk[1];
double unitkz = unitk[2];
double g_ewald_sq_inv = 1.0 / (g_ewald*g_ewald);
double preu = 4.0*MY_PI/volume;
kcount = 0;
// (k,0,0), (0,l,0), (0,0,m)
for (m = 1; m <= kmax; m++) {
sqk = (m*unitkx) * (m*unitkx);
if (sqk <= gsqmx) {
kxvecs[kcount] = m;
kyvecs[kcount] = 0;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*m*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitkx*m)*(unitkx*m);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0;
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
sqk = (m*unitky) * (m*unitky);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = m;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitky*m*ug[kcount];
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitky*m)*(unitky*m);
vg[kcount][2] = 1.0;
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
sqk = (m*unitkz) * (m*unitkz);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = 0;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 0.0;
eg[kcount][2] = 2.0*unitkz*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
}
// 1 = (k,l,0), 2 = (k,-l,0)
for (k = 1; k <= kmax; k++) {
for (l = 1; l <= kmax; l++) {
sqk = (unitkx*k) * (unitkx*k) + (unitky*l) * (unitky*l);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = 2.0*unitky*l*ug[kcount];
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0;
vg[kcount][3] = vterm*unitkx*k*unitky*l;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = -2.0*unitky*l*ug[kcount];
eg[kcount][2] = 0.0;
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0;
vg[kcount][3] = -vterm*unitkx*k*unitky*l;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;;
}
}
}
// 1 = (0,l,m), 2 = (0,l,-m)
for (l = 1; l <= kmax; l++) {
for (m = 1; m <= kmax; m++) {
sqk = (unitky*l) * (unitky*l) + (unitkz*m) * (unitkz*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitky*l*ug[kcount];
eg[kcount][2] = 2.0*unitkz*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = vterm*unitky*l*unitkz*m;
kcount++;
kxvecs[kcount] = 0;
kyvecs[kcount] = l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitky*l*ug[kcount];
eg[kcount][2] = -2.0*unitkz*m*ug[kcount];
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = -vterm*unitky*l*unitkz*m;
kcount++;
}
}
}
// 1 = (k,0,m), 2 = (k,0,-m)
for (k = 1; k <= kmax; k++) {
for (m = 1; m <= kmax; m++) {
sqk = (unitkx*k) * (unitkx*k) + (unitkz*m) * (unitkz*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = 0;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = 2.0*unitkz*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = vterm*unitkx*k*unitkz*m;
vg[kcount][5] = 0.0;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = 0;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = -2.0*unitkz*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = -vterm*unitkx*k*unitkz*m;
vg[kcount][5] = 0.0;
kcount++;
}
}
}
// 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m)
for (k = 1; k <= kmax; k++) {
for (l = 1; l <= kmax; l++) {
for (m = 1; m <= kmax; m++) {
sqk = (unitkx*k) * (unitkx*k) + (unitky*l) * (unitky*l) +
(unitkz*m) * (unitkz*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = 2.0*unitky*l*ug[kcount];
eg[kcount][2] = 2.0*unitkz*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = vterm*unitkx*k*unitky*l;
vg[kcount][4] = vterm*unitkx*k*unitkz*m;
vg[kcount][5] = vterm*unitky*l*unitkz*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = -2.0*unitky*l*ug[kcount];
eg[kcount][2] = 2.0*unitkz*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = -vterm*unitkx*k*unitky*l;
vg[kcount][4] = vterm*unitkx*k*unitkz*m;
vg[kcount][5] = -vterm*unitky*l*unitkz*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = 2.0*unitky*l*ug[kcount];
eg[kcount][2] = -2.0*unitkz*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = vterm*unitkx*k*unitky*l;
vg[kcount][4] = -vterm*unitkx*k*unitkz*m;
vg[kcount][5] = -vterm*unitky*l*unitkz*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitkx*k*ug[kcount];
eg[kcount][1] = -2.0*unitky*l*ug[kcount];
eg[kcount][2] = -2.0*unitkz*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitkx*k)*(unitkx*k);
vg[kcount][1] = 1.0 + vterm*(unitky*l)*(unitky*l);
vg[kcount][2] = 1.0 + vterm*(unitkz*m)*(unitkz*m);
vg[kcount][3] = -vterm*unitkx*k*unitky*l;
vg[kcount][4] = -vterm*unitkx*k*unitkz*m;
vg[kcount][5] = vterm*unitky*l*unitkz*m;
kcount++;;
}
}
}
}
}
/* ----------------------------------------------------------------------
allocate memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::allocate()
{
kxvecs = new int[kmax3d];
kyvecs = new int[kmax3d];
kzvecs = new int[kmax3d];
ug = new double[kmax3d];
memory->create(eg,kmax3d,3,"ewald:eg");
memory->create(vg,kmax3d,6,"ewald:vg");
sfacrl = new double[kmax3d];
sfacim = new double[kmax3d];
sfacrl_all = new double[kmax3d];
sfacim_all = new double[kmax3d];
}
/* ----------------------------------------------------------------------
deallocate memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::deallocate()
{
delete [] kxvecs;
delete [] kyvecs;
delete [] kzvecs;
delete [] ug;
memory->destroy(eg);
memory->destroy(vg);
delete [] sfacrl;
delete [] sfacim;
delete [] sfacrl_all;
delete [] sfacim_all;
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2-D Ewald if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void Ewald::slabcorr(int eflag)
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
double dipole = 0.0;
for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2];
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
- double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double qscale = force->qqrd2e * scale;
- if (eflag) energy += qqrd2e*scale * e_slabcorr;
+ if (eflag) energy += qscale * e_slabcorr;
// add on force corrections
double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
- for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact;
+ for (int i = 0; i < nlocal; i++) f[i][2] += qscale * q[i]*ffact;
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double Ewald::memory_usage()
{
double bytes = 3 * kmax3d * sizeof(int);
bytes += (1 + 3 + 6) * kmax3d * sizeof(double);
bytes += 4 * kmax3d * sizeof(double);
bytes += nmax*3 * sizeof(double);
bytes += 2 * (2*kmax+1)*3*nmax * sizeof(double);
return bytes;
}
diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h
index cd22f987f..e88b8989a 100644
--- a/src/KSPACE/ewald.h
+++ b/src/KSPACE/ewald.h
@@ -1,61 +1,60 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
KSpaceStyle(ewald,Ewald)
#else
#ifndef LMP_EWALD_H
#define LMP_EWALD_H
#include "kspace.h"
namespace LAMMPS_NS {
class Ewald : public KSpace {
public:
Ewald(class LAMMPS *, int, char **);
virtual ~Ewald();
void init();
void setup();
virtual void compute(int, int);
double memory_usage();
protected:
double precision;
int kcount,kmax,kmax3d,kmax_created;
- double qqrd2e;
double gsqmx,qsum,qsqsum,volume;
int nmax;
double unitk[3];
int *kxvecs,*kyvecs,*kzvecs;
double *ug;
double **eg,**vg;
double **ek;
double *sfacrl,*sfacim,*sfacrl_all,*sfacim_all;
double ***cs,***sn;
virtual void eik_dot_r();
void coeffs();
virtual void allocate();
void deallocate();
void slabcorr(int);
};
}
#endif
#endif
diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp
index e2d017a6e..89054a768 100644
--- a/src/KSPACE/pppm.cpp
+++ b/src/KSPACE/pppm.cpp
@@ -1,1956 +1,1963 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Roy Pollock (LLNL), Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "pppm.h"
+#include "math_const.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
#include "memory.h"
#include "error.h"
-#include "math_const.h"
-
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXORDER 7
#define OFFSET 16384
#define SMALL 0.00001
#define LARGE 10000.0
#define EPS_HOC 1.0e-7
#ifdef FFT_SINGLE
#define ZEROF 0.0f
#define ONEF 1.0f
#else
#define ZEROF 0.0
#define ONEF 1.0
#endif
/* ---------------------------------------------------------------------- */
PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
{
if (narg < 1) error->all(FLERR,"Illegal kspace_style pppm command");
precision = atof(arg[0]);
nfactors = 3;
factors = new int[nfactors];
factors[0] = 2;
factors[1] = 3;
factors[2] = 5;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
density_brick = vdx_brick = vdy_brick = vdz_brick = NULL;
density_fft = NULL;
greensfn = NULL;
work1 = work2 = NULL;
vg = NULL;
fkx = fky = fkz = NULL;
buf1 = buf2 = NULL;
gf_b = NULL;
rho1d = rho_coeff = NULL;
fft1 = fft2 = NULL;
remap = NULL;
nmax = 0;
part2grid = NULL;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
PPPM::~PPPM()
{
delete [] factors;
deallocate();
memory->destroy(part2grid);
}
/* ----------------------------------------------------------------------
called once before run
------------------------------------------------------------------------- */
void PPPM::init()
{
if (me == 0) {
if (screen) fprintf(screen,"PPPM initialization ...\n");
if (logfile) fprintf(logfile,"PPPM initialization ...\n");
}
// error check
if (domain->triclinic)
error->all(FLERR,"Cannot (yet) use PPPM with triclinic box");
- if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPM with 2d simulation");
+ if (domain->dimension == 2) error->all(FLERR,
+ "Cannot use PPPM with 2d simulation");
if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q");
if (slabflag == 0 && domain->nonperiodic > 0)
error->all(FLERR,"Cannot use nonperiodic boundaries with PPPM");
if (slabflag == 1) {
if (domain->xperiodic != 1 || domain->yperiodic != 1 ||
domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1)
error->all(FLERR,"Incorrect boundaries with slab PPPM");
}
if (order > MAXORDER) {
char str[128];
sprintf(str,"PPPM order cannot be greater than %d",MAXORDER);
error->all(FLERR,str);
}
// free all arrays previously allocated
deallocate();
// extract short-range Coulombic cutoff from pair style
- qqrd2e = force->qqrd2e;
scale = 1.0;
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
if (p_cutoff == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
cutoff = *p_cutoff;
// if kspace is TIP4P, extract TIP4P params from pair style
// bond/angle are not yet init(), so insure equilibrium request is valid
qdist = 0.0;
if ( (strcmp(force->kspace_style,"pppm/tip4p") == 0) ||
(strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) {
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
double *p_qdist = (double *) force->pair->extract("qdist",itmp);
int *p_typeO = (int *) force->pair->extract("typeO",itmp);
int *p_typeH = (int *) force->pair->extract("typeH",itmp);
int *p_typeA = (int *) force->pair->extract("typeA",itmp);
int *p_typeB = (int *) force->pair->extract("typeB",itmp);
if (!p_qdist || !p_typeO || !p_typeH || !p_typeA || !p_typeB)
error->all(FLERR,"KSpace style is incompatible with Pair style");
qdist = *p_qdist;
typeO = *p_typeO;
typeH = *p_typeH;
int typeA = *p_typeA;
int typeB = *p_typeB;
if (force->angle == NULL || force->bond == NULL)
error->all(FLERR,"Bond and angle potentials must be defined for TIP4P");
if (typeA < 1 || typeA > atom->nangletypes ||
force->angle->setflag[typeA] == 0)
error->all(FLERR,"Bad TIP4P angle type for PPPM/TIP4P");
if (typeB < 1 || typeB > atom->nbondtypes ||
force->bond->setflag[typeB] == 0)
error->all(FLERR,"Bad TIP4P bond type for PPPM/TIP4P");
double theta = force->angle->equilibrium_angle(typeA);
double blen = force->bond->equilibrium_distance(typeB);
alpha = qdist / (cos(0.5*theta) * blen);
}
// if we have a /proxy pppm version check if the pair style is compatible
- if ( (strcmp(force->kspace_style,"pppm/proxy") == 0) ||
- (strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) {
+ if ((strcmp(force->kspace_style,"pppm/proxy") == 0) ||
+ (strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) {
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
if (strstr(force->pair_style,"pppm/") == NULL )
error->all(FLERR,"KSpace style is incompatible with Pair style");
}
// compute qsum & qsqsum and warn if not charge-neutral
qsum = qsqsum = 0.0;
for (int i = 0; i < atom->nlocal; i++) {
qsum += atom->q[i];
qsqsum += atom->q[i]*atom->q[i];
}
double tmp;
MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsum = tmp;
MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsqsum = tmp;
if (qsqsum == 0.0)
error->all(FLERR,"Cannot use kspace solver on system with no charge");
if (fabs(qsum) > SMALL && me == 0) {
char str[128];
sprintf(str,"System is not charge neutral, net charge = %g",qsum);
error->warning(FLERR,str);
}
// setup FFT grid resolution and g_ewald
// normally one iteration thru while loop is all that is required
// if grid stencil extends beyond neighbor proc, reduce order and try again
int iteration = 0;
while (order > 0) {
if (iteration && me == 0)
error->warning(FLERR,"Reducing PPPM order b/c stencil extends "
"beyond neighbor processor");
iteration++;
set_grid();
if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET)
error->all(FLERR,"PPPM grid is too large");
// global indices of PPPM grid range from 0 to N-1
// nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of
// global PPPM grid that I own without ghost cells
// for slab PPPM, assign z grid as if it were not extended
nxlo_in = comm->myloc[0]*nx_pppm / comm->procgrid[0];
nxhi_in = (comm->myloc[0]+1)*nx_pppm / comm->procgrid[0] - 1;
nylo_in = comm->myloc[1]*ny_pppm / comm->procgrid[1];
nyhi_in = (comm->myloc[1]+1)*ny_pppm / comm->procgrid[1] - 1;
nzlo_in = comm->myloc[2] *
(static_cast<int> (nz_pppm/slab_volfactor)) / comm->procgrid[2];
nzhi_in = (comm->myloc[2]+1) *
(static_cast<int> (nz_pppm/slab_volfactor)) / comm->procgrid[2] - 1;
// nlower,nupper = stencil size for mapping particles to PPPM grid
nlower = -(order-1)/2;
nupper = order/2;
// shift values for particle <-> grid mapping
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
if (order % 2) shift = OFFSET + 0.5;
else shift = OFFSET;
if (order % 2) shiftone = 0.0;
else shiftone = 0.5;
// nlo_out,nhi_out = lower/upper limits of the 3d sub-brick of
// global PPPM grid that my particles can contribute charge to
// effectively nlo_in,nhi_in + ghost cells
// nlo,nhi = global coords of grid pt to "lower left" of smallest/largest
// position a particle in my box can be at
// dist[3] = particle position bound = subbox + skin/2.0 + qdist
// qdist = offset due to TIP4P fictitious charge
// convert to triclinic if necessary
// nlo_out,nhi_out = nlo,nhi + stencil size for particle mapping
// for slab PPPM, assign z grid as if it were not extended
triclinic = domain->triclinic;
double *prd,*sublo,*subhi;
if (triclinic == 0) {
prd = domain->prd;
boxlo = domain->boxlo;
sublo = domain->sublo;
subhi = domain->subhi;
} else {
prd = domain->prd_lamda;
boxlo = domain->boxlo_lamda;
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
}
double xprd = prd[0];
double yprd = prd[1];
double zprd = prd[2];
double zprd_slab = zprd*slab_volfactor;
double dist[3];
double cuthalf = 0.5*neighbor->skin + qdist;
if (triclinic == 0) dist[0] = dist[1] = dist[2] = cuthalf;
else {
dist[0] = cuthalf/domain->prd[0];
dist[1] = cuthalf/domain->prd[1];
dist[2] = cuthalf/domain->prd[2];
}
int nlo,nhi;
nlo = static_cast<int> ((sublo[0]-dist[0]-boxlo[0]) *
nx_pppm/xprd + shift) - OFFSET;
nhi = static_cast<int> ((subhi[0]+dist[0]-boxlo[0]) *
nx_pppm/xprd + shift) - OFFSET;
nxlo_out = nlo + nlower;
nxhi_out = nhi + nupper;
nlo = static_cast<int> ((sublo[1]-dist[1]-boxlo[1]) *
ny_pppm/yprd + shift) - OFFSET;
nhi = static_cast<int> ((subhi[1]+dist[1]-boxlo[1]) *
ny_pppm/yprd + shift) - OFFSET;
nylo_out = nlo + nlower;
nyhi_out = nhi + nupper;
nlo = static_cast<int> ((sublo[2]-dist[2]-boxlo[2]) *
nz_pppm/zprd_slab + shift) - OFFSET;
nhi = static_cast<int> ((subhi[2]+dist[2]-boxlo[2]) *
nz_pppm/zprd_slab + shift) - OFFSET;
nzlo_out = nlo + nlower;
nzhi_out = nhi + nupper;
// for slab PPPM, change the grid boundary for processors at +z end
// to include the empty volume between periodically repeating slabs
// for slab PPPM, want charge data communicated from -z proc to +z proc,
// but not vice versa, also want field data communicated from +z proc to
// -z proc, but not vice versa
// this is accomplished by nzhi_in = nzhi_out on +z end (no ghost cells)
if (slabflag && ((comm->myloc[2]+1) == (comm->procgrid[2]))) {
nzhi_in = nz_pppm - 1;
nzhi_out = nz_pppm - 1;
}
// nlo_ghost,nhi_ghost = # of planes I will recv from 6 directions
// that overlay domain I own
// proc in that direction tells me via sendrecv()
// if no neighbor proc, value is from self since I have ghosts regardless
int nplanes;
MPI_Status status;
nplanes = nxlo_in - nxlo_out;
if (comm->procneigh[0][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][0],0,
&nxhi_ghost,1,MPI_INT,comm->procneigh[0][1],0,
world,&status);
else nxhi_ghost = nplanes;
nplanes = nxhi_out - nxhi_in;
if (comm->procneigh[0][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][1],0,
&nxlo_ghost,1,MPI_INT,comm->procneigh[0][0],
0,world,&status);
else nxlo_ghost = nplanes;
nplanes = nylo_in - nylo_out;
if (comm->procneigh[1][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][0],0,
&nyhi_ghost,1,MPI_INT,comm->procneigh[1][1],0,
world,&status);
else nyhi_ghost = nplanes;
nplanes = nyhi_out - nyhi_in;
if (comm->procneigh[1][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][1],0,
&nylo_ghost,1,MPI_INT,comm->procneigh[1][0],0,
world,&status);
else nylo_ghost = nplanes;
nplanes = nzlo_in - nzlo_out;
if (comm->procneigh[2][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][0],0,
&nzhi_ghost,1,MPI_INT,comm->procneigh[2][1],0,
world,&status);
else nzhi_ghost = nplanes;
nplanes = nzhi_out - nzhi_in;
if (comm->procneigh[2][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][1],0,
&nzlo_ghost,1,MPI_INT,comm->procneigh[2][0],0,
world,&status);
else nzlo_ghost = nplanes;
// test that ghost overlap is not bigger than my sub-domain
int flag = 0;
if (nxlo_ghost > nxhi_in-nxlo_in+1) flag = 1;
if (nxhi_ghost > nxhi_in-nxlo_in+1) flag = 1;
if (nylo_ghost > nyhi_in-nylo_in+1) flag = 1;
if (nyhi_ghost > nyhi_in-nylo_in+1) flag = 1;
if (nzlo_ghost > nzhi_in-nzlo_in+1) flag = 1;
if (nzhi_ghost > nzhi_in-nzlo_in+1) flag = 1;
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all == 0) break;
order--;
}
if (order == 0) error->all(FLERR,"PPPM order has been reduced to 0");
// decomposition of FFT mesh
// global indices range from 0 to N-1
// proc owns entire x-dimension, clump of columns in y,z dimensions
// npey_fft,npez_fft = # of procs in y,z dims
// if nprocs is small enough, proc can own 1 or more entire xy planes,
// else proc owns 2d sub-blocks of yz plane
// me_y,me_z = which proc (0-npe_fft-1) I am in y,z dimensions
// nlo_fft,nhi_fft = lower/upper limit of the section
// of the global FFT mesh that I own
int npey_fft,npez_fft;
if (nz_pppm >= nprocs) {
npey_fft = 1;
npez_fft = nprocs;
} else procs2grid2d(nprocs,ny_pppm,nz_pppm,&npey_fft,&npez_fft);
int me_y = me % npey_fft;
int me_z = me / npey_fft;
nxlo_fft = 0;
nxhi_fft = nx_pppm - 1;
nylo_fft = me_y*ny_pppm/npey_fft;
nyhi_fft = (me_y+1)*ny_pppm/npey_fft - 1;
nzlo_fft = me_z*nz_pppm/npez_fft;
nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1;
// PPPM grid for this proc, including ghosts
ngrid = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
(nzhi_out-nzlo_out+1);
// FFT arrays on this proc, without ghosts
// nfft = FFT points in FFT decomposition on this proc
// nfft_brick = FFT points in 3d brick-decomposition on this proc
// nfft_both = greater of 2 values
nfft = (nxhi_fft-nxlo_fft+1) * (nyhi_fft-nylo_fft+1) *
(nzhi_fft-nzlo_fft+1);
int nfft_brick = (nxhi_in-nxlo_in+1) * (nyhi_in-nylo_in+1) *
(nzhi_in-nzlo_in+1);
nfft_both = MAX(nfft,nfft_brick);
// buffer space for use in brick2fft and fillbrick
// idel = max # of ghost planes to send or recv in +/- dir of each dim
// nx,ny,nz = owned planes (including ghosts) in each dim
// nxx,nyy,nzz = max # of grid cells to send in each dim
// nbuf = max in any dim, augment by 3x for components of vd_xyz in fillbrick
int idelx,idely,idelz,nx,ny,nz,nxx,nyy,nzz;
idelx = MAX(nxlo_ghost,nxhi_ghost);
idelx = MAX(idelx,nxhi_out-nxhi_in);
idelx = MAX(idelx,nxlo_in-nxlo_out);
idely = MAX(nylo_ghost,nyhi_ghost);
idely = MAX(idely,nyhi_out-nyhi_in);
idely = MAX(idely,nylo_in-nylo_out);
idelz = MAX(nzlo_ghost,nzhi_ghost);
idelz = MAX(idelz,nzhi_out-nzhi_in);
idelz = MAX(idelz,nzlo_in-nzlo_out);
nx = nxhi_out - nxlo_out + 1;
ny = nyhi_out - nylo_out + 1;
nz = nzhi_out - nzlo_out + 1;
nxx = idelx * ny * nz;
nyy = idely * nx * nz;
nzz = idelz * nx * ny;
nbuf = MAX(nxx,nyy);
nbuf = MAX(nbuf,nzz);
nbuf *= 3;
// print stats
int ngrid_max,nfft_both_max,nbuf_max;
MPI_Allreduce(&ngrid,&ngrid_max,1,MPI_INT,MPI_MAX,world);
MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world);
MPI_Allreduce(&nbuf,&nbuf_max,1,MPI_INT,MPI_MAX,world);
if (me == 0) {
if (screen) fprintf(screen," brick FFT buffer size/proc = %d %d %d\n",
ngrid_max,nfft_both_max,nbuf_max);
if (logfile) fprintf(logfile," brick FFT buffer size/proc = %d %d %d\n",
ngrid_max,nfft_both_max,nbuf_max);
}
// allocate K-space dependent memory
allocate();
// pre-compute Green's function denomiator expansion
// pre-compute 1d charge distribution coefficients
compute_gf_denom();
compute_rho_coeff();
}
/* ----------------------------------------------------------------------
adjust PPPM coeffs, called initially and whenever volume has changed
------------------------------------------------------------------------- */
void PPPM::setup()
{
int i,j,k,l,m,n;
double *prd;
// volume-dependent factors
// adjust z dimension for 2d slab PPPM
// z dimension for 3d PPPM is zprd since slab_volfactor = 1.0
if (triclinic == 0) prd = domain->prd;
else prd = domain->prd_lamda;
double xprd = prd[0];
double yprd = prd[1];
double zprd = prd[2];
double zprd_slab = zprd*slab_volfactor;
volume = xprd * yprd * zprd_slab;
delxinv = nx_pppm/xprd;
delyinv = ny_pppm/yprd;
delzinv = nz_pppm/zprd_slab;
delvolinv = delxinv*delyinv*delzinv;
double unitkx = (2.0*MY_PI/xprd);
double unitky = (2.0*MY_PI/yprd);
double unitkz = (2.0*MY_PI/zprd_slab);
// fkx,fky,fkz for my FFT grid pts
double per;
for (i = nxlo_fft; i <= nxhi_fft; i++) {
per = i - nx_pppm*(2*i/nx_pppm);
fkx[i] = unitkx*per;
}
for (i = nylo_fft; i <= nyhi_fft; i++) {
per = i - ny_pppm*(2*i/ny_pppm);
fky[i] = unitky*per;
}
for (i = nzlo_fft; i <= nzhi_fft; i++) {
per = i - nz_pppm*(2*i/nz_pppm);
fkz[i] = unitkz*per;
}
// virial coefficients
double sqk,vterm;
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++) {
for (j = nylo_fft; j <= nyhi_fft; j++) {
for (i = nxlo_fft; i <= nxhi_fft; i++) {
sqk = fkx[i]*fkx[i] + fky[j]*fky[j] + fkz[k]*fkz[k];
if (sqk == 0.0) {
vg[n][0] = 0.0;
vg[n][1] = 0.0;
vg[n][2] = 0.0;
vg[n][3] = 0.0;
vg[n][4] = 0.0;
vg[n][5] = 0.0;
} else {
vterm = -2.0 * (1.0/sqk + 0.25/(g_ewald*g_ewald));
vg[n][0] = 1.0 + vterm*fkx[i]*fkx[i];
vg[n][1] = 1.0 + vterm*fky[j]*fky[j];
vg[n][2] = 1.0 + vterm*fkz[k]*fkz[k];
vg[n][3] = vterm*fkx[i]*fky[j];
vg[n][4] = vterm*fkx[i]*fkz[k];
vg[n][5] = vterm*fky[j]*fkz[k];
}
n++;
}
}
}
// modified (Hockney-Eastwood) Coulomb Green's function
int nx,ny,nz,kper,lper,mper;
double snx,sny,snz,snx2,sny2,snz2;
double argx,argy,argz,wx,wy,wz,sx,sy,sz,qx,qy,qz;
double sum1,dot1,dot2;
double numerator,denominator;
int nbx = static_cast<int> ((g_ewald*xprd/(MY_PI*nx_pppm)) *
pow(-log(EPS_HOC),0.25));
int nby = static_cast<int> ((g_ewald*yprd/(MY_PI*ny_pppm)) *
pow(-log(EPS_HOC),0.25));
int nbz = static_cast<int> ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) *
pow(-log(EPS_HOC),0.25));
double form = 1.0;
n = 0;
for (m = nzlo_fft; m <= nzhi_fft; m++) {
mper = m - nz_pppm*(2*m/nz_pppm);
snz = sin(0.5*unitkz*mper*zprd_slab/nz_pppm);
snz2 = snz*snz;
for (l = nylo_fft; l <= nyhi_fft; l++) {
lper = l - ny_pppm*(2*l/ny_pppm);
sny = sin(0.5*unitky*lper*yprd/ny_pppm);
sny2 = sny*sny;
for (k = nxlo_fft; k <= nxhi_fft; k++) {
kper = k - nx_pppm*(2*k/nx_pppm);
snx = sin(0.5*unitkx*kper*xprd/nx_pppm);
snx2 = snx*snx;
sqk = pow(unitkx*kper,2.0) + pow(unitky*lper,2.0) +
pow(unitkz*mper,2.0);
if (sqk != 0.0) {
numerator = form*12.5663706/sqk;
denominator = gf_denom(snx2,sny2,snz2);
sum1 = 0.0;
for (nx = -nbx; nx <= nbx; nx++) {
qx = unitkx*(kper+nx_pppm*nx);
sx = exp(-.25*pow(qx/g_ewald,2.0));
wx = 1.0;
argx = 0.5*qx*xprd/nx_pppm;
if (argx != 0.0) wx = pow(sin(argx)/argx,order);
for (ny = -nby; ny <= nby; ny++) {
qy = unitky*(lper+ny_pppm*ny);
sy = exp(-.25*pow(qy/g_ewald,2.0));
wy = 1.0;
argy = 0.5*qy*yprd/ny_pppm;
if (argy != 0.0) wy = pow(sin(argy)/argy,order);
for (nz = -nbz; nz <= nbz; nz++) {
qz = unitkz*(mper+nz_pppm*nz);
sz = exp(-.25*pow(qz/g_ewald,2.0));
wz = 1.0;
argz = 0.5*qz*zprd_slab/nz_pppm;
if (argz != 0.0) wz = pow(sin(argz)/argz,order);
dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz;
dot2 = qx*qx+qy*qy+qz*qz;
sum1 += (dot1/dot2) * sx*sy*sz * pow(wx*wy*wz,2.0);
}
}
}
greensfn[n++] = numerator*sum1/denominator;
} else greensfn[n++] = 0.0;
}
}
}
}
/* ----------------------------------------------------------------------
compute the PPPM long-range force, energy, virial
------------------------------------------------------------------------- */
void PPPM::compute(int eflag, int vflag)
{
int i;
// convert atoms from box to lamda coords
if (triclinic == 0) boxlo = domain->boxlo;
else {
boxlo = domain->boxlo_lamda;
domain->x2lamda(atom->nlocal);
}
// extend size of per-atom arrays if necessary
if (atom->nlocal > nmax) {
memory->destroy(part2grid);
nmax = atom->nmax;
memory->create(part2grid,nmax,3,"pppm:part2grid");
}
energy = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
// find grid points for all my particles
// map my particle charge onto my local 3d density grid
particle_map();
make_rho();
// all procs communicate density values from their ghost cells
// to fully sum contribution in their 3d bricks
// remap from 3d decomposition to FFT decomposition
brick2fft();
// compute potential gradient on my FFT grid and
// portion of e_long on this proc's FFT grid
// return gradients (electric fields) in 3d brick decomposition
poisson(eflag,vflag);
// all procs communicate E-field values to fill ghost cells
// surrounding their 3d bricks
fillbrick();
// calculate the force on my particles
fieldforce();
// sum energy across procs and add in volume-dependent term
+ const double qscale = force->qqrd2e * scale;
+
if (eflag) {
double energy_all;
MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
energy = energy_all;
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/MY_PIS +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
- energy *= qqrd2e*scale;
+ energy *= qscale;
}
// sum virial across procs
if (vflag) {
double virial_all[6];
MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world);
- for (i = 0; i < 6; i++) virial[i] = 0.5*qqrd2e*scale*volume*virial_all[i];
+ for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i];
}
// 2d slab correction
if (slabflag) slabcorr(eflag);
// convert atoms back from lamda to box coords
if (triclinic) domain->lamda2x(atom->nlocal);
}
/* ----------------------------------------------------------------------
allocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::allocate()
{
memory->create3d_offset(density_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:density_brick");
memory->create3d_offset(vdx_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdx_brick");
memory->create3d_offset(vdy_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdy_brick");
memory->create3d_offset(vdz_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdz_brick");
memory->create(density_fft,nfft_both,"pppm:density_fft");
memory->create(greensfn,nfft_both,"pppm:greensfn");
memory->create(work1,2*nfft_both,"pppm:work1");
memory->create(work2,2*nfft_both,"pppm:work2");
memory->create(vg,nfft_both,6,"pppm:vg");
memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm:fkx");
memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm:fky");
memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm:fkz");
memory->create(buf1,nbuf,"pppm:buf1");
memory->create(buf2,nbuf,"pppm:buf2");
// summation coeffs
memory->create(gf_b,order,"pppm:gf_b");
memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm:rho1d");
memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm:rho_coeff");
// create 2 FFTs and a Remap
// 1st FFT keeps data in FFT decompostion
// 2nd FFT returns data in 3d brick decomposition
// remap takes data from 3d brick to FFT decomposition
int tmp;
fft1 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
0,0,&tmp);
fft2 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
0,0,&tmp);
remap = new Remap(lmp,world,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
1,0,0,FFT_PRECISION);
}
/* ----------------------------------------------------------------------
deallocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::deallocate()
{
memory->destroy3d_offset(density_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdx_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdy_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdz_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy(density_fft);
memory->destroy(greensfn);
memory->destroy(work1);
memory->destroy(work2);
memory->destroy(vg);
memory->destroy1d_offset(fkx,nxlo_fft);
memory->destroy1d_offset(fky,nylo_fft);
memory->destroy1d_offset(fkz,nzlo_fft);
memory->destroy(buf1);
memory->destroy(buf2);
memory->destroy(gf_b);
memory->destroy2d_offset(rho1d,-order/2);
memory->destroy2d_offset(rho_coeff,(1-order)/2);
delete fft1;
delete fft2;
delete remap;
}
/* ----------------------------------------------------------------------
set size of FFT grid (nx,ny,nz_pppm) and g_ewald
------------------------------------------------------------------------- */
void PPPM::set_grid()
{
// see JCP 109, pg 7698 for derivation of coefficients
// higher order coefficients may be computed if needed
double **acons;
memory->create(acons,8,7,"pppm:acons");
acons[1][0] = 2.0 / 3.0;
acons[2][0] = 1.0 / 50.0;
acons[2][1] = 5.0 / 294.0;
acons[3][0] = 1.0 / 588.0;
acons[3][1] = 7.0 / 1440.0;
acons[3][2] = 21.0 / 3872.0;
acons[4][0] = 1.0 / 4320.0;
acons[4][1] = 3.0 / 1936.0;
acons[4][2] = 7601.0 / 2271360.0;
acons[4][3] = 143.0 / 28800.0;
acons[5][0] = 1.0 / 23232.0;
acons[5][1] = 7601.0 / 13628160.0;
acons[5][2] = 143.0 / 69120.0;
acons[5][3] = 517231.0 / 106536960.0;
acons[5][4] = 106640677.0 / 11737571328.0;
acons[6][0] = 691.0 / 68140800.0;
acons[6][1] = 13.0 / 57600.0;
acons[6][2] = 47021.0 / 35512320.0;
acons[6][3] = 9694607.0 / 2095994880.0;
acons[6][4] = 733191589.0 / 59609088000.0;
acons[6][5] = 326190917.0 / 11700633600.0;
acons[7][0] = 1.0 / 345600.0;
acons[7][1] = 3617.0 / 35512320.0;
acons[7][2] = 745739.0 / 838397952.0;
acons[7][3] = 56399353.0 / 12773376000.0;
acons[7][4] = 25091609.0 / 1560084480.0;
acons[7][5] = 1755948832039.0 / 36229939200000.0;
acons[7][6] = 4887769399.0 / 37838389248.0;
double q2 = qsqsum / force->dielectric;
bigint natoms = atom->natoms;
// use xprd,yprd,zprd even if triclinic so grid size is the same
// adjust z dimension for 2d slab PPPM
// 3d PPPM just uses zprd since slab_volfactor = 1.0
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double zprd_slab = zprd*slab_volfactor;
// make initial g_ewald estimate
// based on desired error and real space cutoff
// fluid-occupied volume used to estimate real-space error
// zprd used rather than zprd_slab
double h_x,h_y,h_z;
if (!gewaldflag)
g_ewald = sqrt(-log(precision*sqrt(natoms*cutoff*xprd*yprd*zprd) /
(2.0*q2))) / cutoff;
// set optimal nx_pppm,ny_pppm,nz_pppm based on order and precision
// nz_pppm uses extended zprd_slab instead of zprd
// h = 1/g_ewald is upper bound on h such that h*g_ewald <= 1
// reduce it until precision target is met
if (!gridflag) {
double err;
h_x = h_y = h_z = 1/g_ewald;
nx_pppm = static_cast<int> (xprd/h_x + 1);
ny_pppm = static_cast<int> (yprd/h_y + 1);
nz_pppm = static_cast<int> (zprd_slab/h_z + 1);
err = rms(h_x,xprd,natoms,q2,acons);
while (err > precision) {
err = rms(h_x,xprd,natoms,q2,acons);
nx_pppm++;
h_x = xprd/nx_pppm;
}
err = rms(h_y,yprd,natoms,q2,acons);
while (err > precision) {
err = rms(h_y,yprd,natoms,q2,acons);
ny_pppm++;
h_y = yprd/ny_pppm;
}
err = rms(h_z,zprd_slab,natoms,q2,acons);
while (err > precision) {
err = rms(h_z,zprd_slab,natoms,q2,acons);
nz_pppm++;
h_z = zprd_slab/nz_pppm;
}
}
// boost grid size until it is factorable
while (!factorable(nx_pppm)) nx_pppm++;
while (!factorable(ny_pppm)) ny_pppm++;
while (!factorable(nz_pppm)) nz_pppm++;
// adjust g_ewald for new grid size
h_x = xprd/nx_pppm;
h_y = yprd/ny_pppm;
h_z = zprd_slab/nz_pppm;
if (!gewaldflag) {
double gew1,gew2,dgew,f,fmid,hmin,rtb;
int ncount;
gew1 = 0.0;
g_ewald = gew1;
f = diffpr(h_x,h_y,h_z,q2,acons);
hmin = MIN(h_x,MIN(h_y,h_z));
gew2 = 10/hmin;
g_ewald = gew2;
fmid = diffpr(h_x,h_y,h_z,q2,acons);
if (f*fmid >= 0.0) error->all(FLERR,"Cannot compute PPPM G");
rtb = f < 0.0 ? (dgew=gew2-gew1,gew1) : (dgew=gew1-gew2,gew2);
ncount = 0;
while (fabs(dgew) > SMALL && fmid != 0.0) {
dgew *= 0.5;
g_ewald = rtb + dgew;
fmid = diffpr(h_x,h_y,h_z,q2,acons);
if (fmid <= 0.0) rtb = g_ewald;
ncount++;
if (ncount > LARGE) error->all(FLERR,"Cannot compute PPPM G");
}
}
// final RMS precision
double lprx = rms(h_x,xprd,natoms,q2,acons);
double lpry = rms(h_y,yprd,natoms,q2,acons);
double lprz = rms(h_z,zprd_slab,natoms,q2,acons);
double lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0);
double spr = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) /
sqrt(natoms*cutoff*xprd*yprd*zprd_slab);
// free local memory
memory->destroy(acons);
// print info
if (me == 0) {
#ifdef FFT_SINGLE
const char fft_prec[] = "single";
#else
const char fft_prec[] = "double";
#endif
if (screen) {
fprintf(screen," G vector = %g\n",g_ewald);
fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm);
fprintf(screen," stencil order = %d\n",order);
fprintf(screen," RMS precision = %g\n",MAX(lpr,spr));
fprintf(screen," using %s precision FFTs\n",fft_prec);
}
if (logfile) {
fprintf(logfile," G vector = %g\n",g_ewald);
fprintf(logfile," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm);
fprintf(logfile," stencil order = %d\n",order);
fprintf(logfile," RMS precision = %g\n",MAX(lpr,spr));
fprintf(logfile," using %s precision FFTs\n",fft_prec);
}
}
}
/* ----------------------------------------------------------------------
check if all factors of n are in list of factors
return 1 if yes, 0 if no
------------------------------------------------------------------------- */
int PPPM::factorable(int n)
{
int i;
while (n > 1) {
for (i = 0; i < nfactors; i++) {
if (n % factors[i] == 0) {
n /= factors[i];
break;
}
}
if (i == nfactors) return 0;
}
return 1;
}
/* ----------------------------------------------------------------------
compute RMS precision for a dimension
------------------------------------------------------------------------- */
double PPPM::rms(double h, double prd, bigint natoms,
double q2, double **acons)
{
double sum = 0.0;
for (int m = 0; m < order; m++)
sum += acons[order][m] * pow(h*g_ewald,2.0*m);
double value = q2 * pow(h*g_ewald,order) *
sqrt(g_ewald*prd*sqrt(2.0*MY_PI)*sum/natoms) / (prd*prd);
return value;
}
/* ----------------------------------------------------------------------
compute difference in real-space and kspace RMS precision
------------------------------------------------------------------------- */
-double PPPM::diffpr(double h_x, double h_y, double h_z, double q2, double **acons)
+double PPPM::diffpr(double h_x, double h_y, double h_z, double q2,
+ double **acons)
{
double lprx,lpry,lprz,kspace_prec,real_prec;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
bigint natoms = atom->natoms;
lprx = rms(h_x,xprd,natoms,q2,acons);
lpry = rms(h_y,yprd,natoms,q2,acons);
lprz = rms(h_z,zprd*slab_volfactor,natoms,q2,acons);
kspace_prec = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0);
real_prec = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) /
sqrt(static_cast<double>(natoms)*cutoff*xprd*yprd*zprd);
double value = kspace_prec - real_prec;
return value;
}
/* ----------------------------------------------------------------------
denominator for Hockney-Eastwood Green's function
of x,y,z = sin(kx*deltax/2), etc
inf n-1
S(n,k) = Sum W(k+pi*j)**2 = Sum b(l)*(z*z)**l
j=-inf l=0
= -(z*z)**n /(2n-1)! * (d/dx)**(2n-1) cot(x) at z = sin(x)
gf_b = denominator expansion coeffs
------------------------------------------------------------------------- */
double PPPM::gf_denom(double x, double y, double z)
{
double sx,sy,sz;
sz = sy = sx = 0.0;
for (int l = order-1; l >= 0; l--) {
sx = gf_b[l] + sx*x;
sy = gf_b[l] + sy*y;
sz = gf_b[l] + sz*z;
}
double s = sx*sy*sz;
return s*s;
}
/* ----------------------------------------------------------------------
pre-compute Green's function denominator expansion coeffs, Gamma(2n)
------------------------------------------------------------------------- */
void PPPM::compute_gf_denom()
{
int k,l,m;
for (l = 1; l < order; l++) gf_b[l] = 0.0;
gf_b[0] = 1.0;
for (m = 1; m < order; m++) {
for (l = m; l > 0; l--)
gf_b[l] = 4.0 * (gf_b[l]*(l-m)*(l-m-0.5)-gf_b[l-1]*(l-m-1)*(l-m-1));
gf_b[0] = 4.0 * (gf_b[0]*(l-m)*(l-m-0.5));
}
int ifact = 1;
for (k = 1; k < 2*order; k++) ifact *= k;
double gaminv = 1.0/ifact;
for (l = 0; l < order; l++) gf_b[l] *= gaminv;
}
/* ----------------------------------------------------------------------
ghost-swap to accumulate full density in brick decomposition
remap density from 3d brick decomposition to FFT decomposition
------------------------------------------------------------------------- */
void PPPM::brick2fft()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my ghosts for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// remap from 3d brick decomposition to FFT decomposition
// copy grabs inner portion of density from 3d brick
// remap could be done as pre-stage of FFT,
// but this works optimally on only double values, not complex values
n = 0;
for (iz = nzlo_in; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_fft[n++] = density_brick[iz][iy][ix];
remap->perform(density_fft,density_fft,work1);
}
/* ----------------------------------------------------------------------
ghost-swap to fill ghost cells of my brick with field values
------------------------------------------------------------------------- */
void PPPM::fillbrick()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my real cells for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
}
/* ----------------------------------------------------------------------
find center grid pt for each of my particles
check that full stencil for the particle will fit in my 3d brick
store central grid pt indices in part2grid array
------------------------------------------------------------------------- */
void PPPM::particle_map()
{
int nx,ny,nz;
double **x = atom->x;
int nlocal = atom->nlocal;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// current particle coord can be outside global and local box
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
nx = static_cast<int> ((x[i][0]-boxlo[0])*delxinv+shift) - OFFSET;
ny = static_cast<int> ((x[i][1]-boxlo[1])*delyinv+shift) - OFFSET;
nz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv+shift) - OFFSET;
part2grid[i][0] = nx;
part2grid[i][1] = ny;
part2grid[i][2] = nz;
// check that entire stencil around nx,ny,nz will fit in my 3d brick
if (nx+nlower < nxlo_out || nx+nupper > nxhi_out ||
ny+nlower < nylo_out || ny+nupper > nyhi_out ||
- nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag = 1;
+ nz+nlower < nzlo_out || nz+nupper > nzhi_out)
+ flag = 1;
}
if (flag) error->one(FLERR,"Out of range atoms - cannot compute PPPM");
}
/* ----------------------------------------------------------------------
create discretized "density" on section of global grid due to my particles
density(x,y,z) = charge "density" at grid points of my 3d brick
(nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
in global grid
------------------------------------------------------------------------- */
void PPPM::make_rho()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
// clear 3d density array
- memset(&(density_brick[nzlo_out][nylo_out][nxlo_out]),0,ngrid*sizeof(FFT_SCALAR));
+ memset(&(density_brick[nzlo_out][nylo_out][nxlo_out]),0,
+ ngrid*sizeof(FFT_SCALAR));
// loop over my charges, add their contribution to nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
z0 = delvolinv * q[i];
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
y0 = z0*rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
x0 = y0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
density_brick[mz][my][mx] += x0*rho1d[0][l];
}
}
}
}
}
/* ----------------------------------------------------------------------
FFT-based Poisson solver
------------------------------------------------------------------------- */
void PPPM::poisson(int eflag, int vflag)
{
int i,j,k,n;
double eng;
// transform charge density (r -> k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] = density_fft[i];
work1[n++] = ZEROF;
}
fft1->compute(work1,work1,1);
// if requested, compute energy and virial contribution
double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm);
double s2 = scaleinv*scaleinv;
if (eflag || vflag) {
if (vflag) {
n = 0;
for (i = 0; i < nfft; i++) {
eng = s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
for (j = 0; j < 6; j++) virial[j] += eng*vg[i][j];
energy += eng;
n += 2;
}
} else {
n = 0;
for (i = 0; i < nfft; i++) {
energy +=
s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
n += 2;
}
}
}
// scale by 1/total-grid-pts to get rho(k)
// multiply by Green's function to get V(k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] *= scaleinv * greensfn[i];
work1[n++] *= scaleinv * greensfn[i];
}
// compute gradients of V(r) in each of 3 dims by transformimg -ik*V(k)
// FFT leaves data in 3d brick decomposition
// copy it into inner portion of vdx,vdy,vdz arrays
// x direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkx[i]*work1[n+1];
work2[n+1] = -fkx[i]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdx_brick[k][j][i] = work2[n];
n += 2;
}
// y direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fky[j]*work1[n+1];
work2[n+1] = -fky[j]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdy_brick[k][j][i] = work2[n];
n += 2;
}
// z direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkz[k]*work1[n+1];
work2[n+1] = -fkz[k]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdz_brick[k][j][i] = work2[n];
n += 2;
}
}
/* ----------------------------------------------------------------------
interpolate from grid to get electric field & force on my particles
------------------------------------------------------------------------- */
void PPPM::fieldforce()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
FFT_SCALAR ekx,eky,ekz;
// loop over my charges, interpolate electric field from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
// ek = 3 components of E-field on particle
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
ekx = eky = ekz = ZEROF;
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
ekx -= x0*vdx_brick[mz][my][mx];
eky -= x0*vdy_brick[mz][my][mx];
ekz -= x0*vdz_brick[mz][my][mx];
}
}
}
// convert E-field to force
- const double qfactor = qqrd2e*scale*q[i];
+
+ const double qfactor = force->qqrd2e * scale * q[i];
f[i][0] += qfactor*ekx;
f[i][1] += qfactor*eky;
f[i][2] += qfactor*ekz;
}
}
/* ----------------------------------------------------------------------
map nprocs to NX by NY grid as PX by PY procs - return optimal px,py
------------------------------------------------------------------------- */
void PPPM::procs2grid2d(int nprocs, int nx, int ny, int *px, int *py)
{
// loop thru all possible factorizations of nprocs
// surf = surface area of largest proc sub-domain
// innermost if test minimizes surface area and surface/volume ratio
int bestsurf = 2 * (nx + ny);
int bestboxx = 0;
int bestboxy = 0;
int boxx,boxy,surf,ipx,ipy;
ipx = 1;
while (ipx <= nprocs) {
if (nprocs % ipx == 0) {
ipy = nprocs/ipx;
boxx = nx/ipx;
if (nx % ipx) boxx++;
boxy = ny/ipy;
if (ny % ipy) boxy++;
surf = boxx + boxy;
if (surf < bestsurf ||
(surf == bestsurf && boxx*boxy > bestboxx*bestboxy)) {
bestsurf = surf;
bestboxx = boxx;
bestboxy = boxy;
*px = ipx;
*py = ipy;
}
}
ipx++;
}
}
/* ----------------------------------------------------------------------
charge assignment into rho1d
dx,dy,dz = distance of particle from "lower left" grid point
------------------------------------------------------------------------- */
+
void PPPM::compute_rho1d(const FFT_SCALAR &dx, const FFT_SCALAR &dy,
const FFT_SCALAR &dz)
{
int k,l;
FFT_SCALAR r1,r2,r3;
for (k = (1-order)/2; k <= order/2; k++) {
r1 = r2 = r3 = ZEROF;
for (l = order-1; l >= 0; l--) {
r1 = rho_coeff[l][k] + r1*dx;
r2 = rho_coeff[l][k] + r2*dy;
r3 = rho_coeff[l][k] + r3*dz;
}
rho1d[0][k] = r1;
rho1d[1][k] = r2;
rho1d[2][k] = r3;
}
}
/* ----------------------------------------------------------------------
generate coeffients for the weight function of order n
(n-1)
Wn(x) = Sum wn(k,x) , Sum is over every other integer
k=-(n-1)
For k=-(n-1),-(n-1)+2, ....., (n-1)-2,n-1
k is odd integers if n is even and even integers if n is odd
---
| n-1
| Sum a(l,j)*(x-k/2)**l if abs(x-k/2) < 1/2
wn(k,x) = < l=0
|
| 0 otherwise
---
a coeffients are packed into the array rho_coeff to eliminate zeros
rho_coeff(l,((k+mod(n+1,2))/2) = a(l,k)
------------------------------------------------------------------------- */
void PPPM::compute_rho_coeff()
{
int j,k,l,m;
FFT_SCALAR s;
FFT_SCALAR **a;
memory->create2d_offset(a,order,-order,order,"pppm:a");
for (k = -order; k <= order; k++)
for (l = 0; l < order; l++)
a[l][k] = 0.0;
a[0][0] = 1.0;
for (j = 1; j < order; j++) {
for (k = -j; k <= j; k += 2) {
s = 0.0;
for (l = 0; l < j; l++) {
a[l+1][k] = (a[l][k+1]-a[l][k-1]) / (l+1);
#ifdef FFT_SINGLE
s += powf(0.5,(float) l+1) *
(a[l][k-1] + powf(-1.0,(float) l) * a[l][k+1]) / (l+1);
#else
s += pow(0.5,(double) l+1) *
(a[l][k-1] + pow(-1.0,(double) l) * a[l][k+1]) / (l+1);
#endif
}
a[0][k] = s;
}
}
m = (1-order)/2;
for (k = -(order-1); k < order; k += 2) {
for (l = 0; l < order; l++)
rho_coeff[l][m] = a[l][k];
m++;
}
memory->destroy2d_offset(a,-order);
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2D Ewald if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void PPPM::slabcorr(int eflag)
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
double dipole = 0.0;
for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2];
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
- double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double qscale = force->qqrd2e * scale;
- if (eflag) energy += qqrd2e*scale * e_slabcorr;
+ if (eflag) energy += qscale * e_slabcorr;
// add on force corrections
double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
- for (int i = 0; i < nlocal; i++) f[i][2] += qqrd2e*scale * q[i]*ffact;
+ for (int i = 0; i < nlocal; i++) f[i][2] += qscale * q[i]*ffact;
}
/* ----------------------------------------------------------------------
perform and time the 4 FFTs required for N timesteps
------------------------------------------------------------------------- */
void PPPM::timing(int n, double &time3d, double &time1d)
{
double time1,time2;
for (int i = 0; i < 2*nfft_both; i++) work1[i] = ZEROF;
MPI_Barrier(world);
time1 = MPI_Wtime();
for (int i = 0; i < n; i++) {
fft1->compute(work1,work1,1);
fft2->compute(work1,work1,-1);
fft2->compute(work1,work1,-1);
fft2->compute(work1,work1,-1);
}
MPI_Barrier(world);
time2 = MPI_Wtime();
time3d = time2 - time1;
MPI_Barrier(world);
time1 = MPI_Wtime();
for (int i = 0; i < n; i++) {
fft1->timing1d(work1,nfft_both,1);
fft2->timing1d(work1,nfft_both,-1);
fft2->timing1d(work1,nfft_both,-1);
fft2->timing1d(work1,nfft_both,-1);
}
MPI_Barrier(world);
time2 = MPI_Wtime();
time1d = time2 - time1;
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double PPPM::memory_usage()
{
double bytes = nmax*3 * sizeof(double);
int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
(nzhi_out-nzlo_out+1);
bytes += 4 * nbrick * sizeof(FFT_SCALAR);
bytes += 6 * nfft_both * sizeof(double);
bytes += nfft_both * sizeof(double);
bytes += nfft_both*5 * sizeof(FFT_SCALAR);
bytes += 2 * nbuf * sizeof(FFT_SCALAR);
return bytes;
}
diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h
index e2a58e880..b3dbf1779 100644
--- a/src/KSPACE/pppm.h
+++ b/src/KSPACE/pppm.h
@@ -1,116 +1,115 @@
-/* -*- c++ -*- ----------------------------------------------------------
+/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
KSpaceStyle(pppm,PPPM)
#else
#ifndef LMP_PPPM_H
#define LMP_PPPM_H
#include "lmptype.h"
#include "mpi.h"
#ifdef FFT_SINGLE
typedef float FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_FLOAT
#else
typedef double FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_DOUBLE
#endif
#include "kspace.h"
namespace LAMMPS_NS {
class PPPM : public KSpace {
public:
PPPM(class LAMMPS *, int, char **);
virtual ~PPPM();
virtual void init();
virtual void setup();
virtual void compute(int, int);
virtual void timing(int, double &, double &);
virtual double memory_usage();
protected:
int me,nprocs;
double precision;
int nfactors;
int *factors;
double qsum,qsqsum;
- double qqrd2e;
double cutoff;
double volume;
double delxinv,delyinv,delzinv,delvolinv;
double shift,shiftone;
int nxlo_in,nylo_in,nzlo_in,nxhi_in,nyhi_in,nzhi_in;
int nxlo_out,nylo_out,nzlo_out,nxhi_out,nyhi_out,nzhi_out;
int nxlo_ghost,nxhi_ghost,nylo_ghost,nyhi_ghost,nzlo_ghost,nzhi_ghost;
int nxlo_fft,nylo_fft,nzlo_fft,nxhi_fft,nyhi_fft,nzhi_fft;
int nlower,nupper;
int ngrid,nfft,nbuf,nfft_both;
FFT_SCALAR ***density_brick;
FFT_SCALAR ***vdx_brick,***vdy_brick,***vdz_brick;
double *greensfn;
double **vg;
double *fkx,*fky,*fkz;
FFT_SCALAR *density_fft;
FFT_SCALAR *work1,*work2;
FFT_SCALAR *buf1,*buf2;
double *gf_b;
FFT_SCALAR **rho1d,**rho_coeff;
class FFT3d *fft1,*fft2;
class Remap *remap;
int **part2grid; // storage for particle -> grid mapping
int nmax;
int triclinic; // domain settings, orthog or triclinic
double *boxlo;
// TIP4P settings
int typeH,typeO; // atom types of TIP4P water H and O atoms
double qdist; // distance from O site to negative charge
double alpha; // geometric factor
void set_grid();
virtual void allocate();
virtual void deallocate();
int factorable(int);
double rms(double, double, bigint, double, double **);
double diffpr(double, double, double, double, double **);
void compute_gf_denom();
double gf_denom(double, double, double);
virtual void particle_map();
virtual void make_rho();
virtual void brick2fft();
virtual void fillbrick();
virtual void poisson(int, int);
virtual void fieldforce();
void procs2grid2d(int,int,int,int *, int*);
void compute_rho1d(const FFT_SCALAR &, const FFT_SCALAR &,
const FFT_SCALAR &);
void compute_rho_coeff();
void slabcorr(int);
};
}
#endif
#endif
diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp
index daffb5ff2..663d263a2 100644
--- a/src/KSPACE/pppm_cg.cpp
+++ b/src/KSPACE/pppm_cg.cpp
@@ -1,402 +1,406 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "atom.h"
#include "domain.h"
#include "error.h"
+#include "force.h"
#include "memory.h"
#include "pppm_cg.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define OFFSET 16384
#define SMALLQ 0.00001
#if defined(FFT_SINGLE)
#define ZEROF 0.0f
#else
#define ZEROF 0.0
#endif
/* ---------------------------------------------------------------------- */
PPPMCG::PPPMCG(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg)
{
if ((narg < 1) || (narg > 2)) error->all(FLERR,"Illegal kspace_style pppm/cg command");
if (narg == 2)
smallq = atof(arg[1]);
else
smallq = SMALLQ;
num_charged = -1;
is_charged = NULL;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
PPPMCG::~PPPMCG()
{
memory->destroy(is_charged);
}
/* ----------------------------------------------------------------------
compute the PPPM long-range force, energy, virial
------------------------------------------------------------------------- */
void PPPMCG::compute(int eflag, int vflag)
{
int i;
// convert atoms from box to lamda coords
if (triclinic == 0) boxlo = domain->boxlo;
else {
boxlo = domain->boxlo_lamda;
domain->x2lamda(atom->nlocal);
}
// extend size of per-atom arrays if necessary
if (atom->nlocal > nmax) {
memory->destroy(part2grid);
memory->destroy(is_charged);
nmax = atom->nmax;
memory->create(part2grid,nmax,3,"pppm:part2grid");
memory->create(is_charged,nmax,"pppm/cg:is_charged");
}
// one time setup message.
if (num_charged < 0) {
bigint charged_all, charged_num;
double charged_frac, charged_fmax, charged_fmin;
num_charged=0;
for (i=0; i < atom->nlocal; ++i)
if (fabs(atom->q[i]) > smallq)
++num_charged;
// get fraction of charged particles per domain
if (atom->nlocal > 0)
charged_frac = static_cast<double>(num_charged) * 100.0
/ static_cast<double>(atom->nlocal);
else
charged_frac = 0.0;
MPI_Reduce(&charged_frac,&charged_fmax,1,MPI_DOUBLE,MPI_MAX,0,world);
MPI_Reduce(&charged_frac,&charged_fmin,1,MPI_DOUBLE,MPI_MIN,0,world);
// get fraction of charged particles overall
charged_num = num_charged;
MPI_Reduce(&charged_num,&charged_all,1,MPI_LMP_BIGINT,MPI_SUM,0,world);
charged_frac = static_cast<double>(charged_all) * 100.0
/ static_cast<double>(atom->natoms);
if (me == 0) {
if (screen)
fprintf(screen,
" PPPM/cg optimization cutoff: %g\n"
" Total charged atoms: %.1f%%\n"
" Min/max charged atoms/proc: %.1f%% %.1f%%\n",
smallq,charged_frac,charged_fmin,charged_fmax);
if (logfile)
fprintf(logfile,
" PPPM/cg optimization cutoff: %g\n"
" Total charged atoms: %.1f%%\n"
" Min/max charged atoms/proc: %.1f%% %.1f%%\n",
smallq,charged_frac,charged_fmin,charged_fmax);
}
}
num_charged=0;
for (i=0; i < atom->nlocal; ++i)
if (fabs(atom->q[i]) > smallq) {
is_charged[num_charged] = i;
++num_charged;
}
energy = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
// find grid points for all my particles
// map my particle charge onto my local 3d density grid
particle_map();
make_rho();
// all procs communicate density values from their ghost cells
// to fully sum contribution in their 3d bricks
// remap from 3d decomposition to FFT decomposition
brick2fft();
// compute potential gradient on my FFT grid and
// portion of e_long on this proc's FFT grid
// return gradients (electric fields) in 3d brick decomposition
poisson(eflag,vflag);
// all procs communicate E-field values to fill ghost cells
// surrounding their 3d bricks
fillbrick();
// calculate the force on my particles
fieldforce();
// sum energy across procs and add in volume-dependent term
+ const double qscale = force->qqrd2e * scale;
+
if (eflag) {
double energy_all;
MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
energy = energy_all;
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/MY_PIS +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
- energy *= qqrd2e*scale;
+ energy *= qscale;
}
// sum virial across procs
if (vflag) {
double virial_all[6];
MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world);
- for (i = 0; i < 6; i++) virial[i] = 0.5*qqrd2e*scale*volume*virial_all[i];
+ for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i];
}
// 2d slab correction
if (slabflag) slabcorr(eflag);
// convert atoms back from lamda to box coords
if (triclinic) domain->lamda2x(atom->nlocal);
}
/* ----------------------------------------------------------------------
find center grid pt for each of my particles
check that full stencil for the particle will fit in my 3d brick
store central grid pt indices in part2grid array
------------------------------------------------------------------------- */
void PPPMCG::particle_map()
{
int nx,ny,nz;
double **x = atom->x;
int flag = 0;
for (int j = 0; j < num_charged; j++) {
int i = is_charged[j];
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// current particle coord can be outside global and local box
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
nx = static_cast<int> ((x[i][0]-boxlo[0])*delxinv+shift) - OFFSET;
ny = static_cast<int> ((x[i][1]-boxlo[1])*delyinv+shift) - OFFSET;
nz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv+shift) - OFFSET;
part2grid[i][0] = nx;
part2grid[i][1] = ny;
part2grid[i][2] = nz;
// check that entire stencil around nx,ny,nz will fit in my 3d brick
if (nx+nlower < nxlo_out || nx+nupper > nxhi_out ||
ny+nlower < nylo_out || ny+nupper > nyhi_out ||
nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag = 1;
}
if (flag) error->one(FLERR,"Out of range atoms - cannot compute PPPM");
}
/* ----------------------------------------------------------------------
create discretized "density" on section of global grid due to my particles
density(x,y,z) = charge "density" at grid points of my 3d brick
(nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
in global grid
------------------------------------------------------------------------- */
void PPPMCG::make_rho()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
// clear 3d density array
FFT_SCALAR *vec = &density_brick[nzlo_out][nylo_out][nxlo_out];
for (i = 0; i < ngrid; i++) vec[i] = ZEROF;
// loop over my charges, add their contribution to nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
for (int j = 0; j < num_charged; j++) {
int i = is_charged[j];
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
z0 = delvolinv * q[i];
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
y0 = z0*rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
x0 = y0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
density_brick[mz][my][mx] += x0*rho1d[0][l];
}
}
}
}
}
/* ----------------------------------------------------------------------
interpolate from grid to get electric field & force on my particles
------------------------------------------------------------------------- */
void PPPMCG::fieldforce()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
FFT_SCALAR ekx,eky,ekz;
// loop over my charges, interpolate electric field from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
// ek = 3 components of E-field on particle
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
for (int j = 0; j < num_charged; j++) {
i = is_charged[j];
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
ekx = eky = ekz = ZEROF;
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
ekx -= x0*vdx_brick[mz][my][mx];
eky -= x0*vdy_brick[mz][my][mx];
ekz -= x0*vdz_brick[mz][my][mx];
}
}
}
// convert E-field to force
- const double qfactor = qqrd2e*scale*q[i];
+ const double qfactor = force->qqrd2e * scale * q[i];
f[i][0] += qfactor*ekx;
f[i][1] += qfactor*eky;
f[i][2] += qfactor*ekz;
}
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2D Ewald if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void PPPMCG::slabcorr(int eflag)
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
double dipole = 0.0;
for (int j = 0; j < num_charged; j++) {
int i = is_charged[j];
dipole += q[i]*x[i][2];
}
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
- double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
+ const double qscale = force->qqrd2e * scale;
- if (eflag) energy += qqrd2e*scale * e_slabcorr;
+ if (eflag) energy += qscale * e_slabcorr;
// add on force corrections
- double ffact = -4.0*MY_PI*dipole_all/volume * qqrd2e * scale;
+ const double ffact = -4.0*MY_PI*dipole_all/volume * qscale;
double **f = atom->f;
for (int j = 0; j < num_charged; j++) {
int i = is_charged[j];
f[i][2] += q[i]*ffact;
}
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double PPPMCG::memory_usage()
{
double bytes = PPPM::memory_usage();
bytes += nmax * sizeof(int);
return bytes;
}
diff --git a/src/KSPACE/pppm_tip4p.cpp b/src/KSPACE/pppm_tip4p.cpp
index a191fa742..bd6e880a3 100644
--- a/src/KSPACE/pppm_tip4p.cpp
+++ b/src/KSPACE/pppm_tip4p.cpp
@@ -1,275 +1,289 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Amalie Frischknecht and Ahmed Ismail (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "pppm_tip4p.h"
#include "atom.h"
#include "domain.h"
+#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define OFFSET 16384
#ifdef FFT_SINGLE
#define ZEROF 0.0f
#define ONEF 1.0f
#else
#define ZEROF 0.0
#define ONEF 1.0
#endif
/* ---------------------------------------------------------------------- */
PPPMTIP4P::PPPMTIP4P(LAMMPS *lmp, int narg, char **arg) :
PPPM(lmp, narg, arg) {}
+/* ---------------------------------------------------------------------- */
+
+void PPPMTIP4P::init()
+{
+ // TIP4P PPPM requires newton on, b/c it computes forces on ghost atoms
+
+ if (force->newton == 0)
+ error->all(FLERR,"Kspace style pppm/tip4p requires newton on");
+
+ PPPM::init();
+}
+
/* ----------------------------------------------------------------------
find center grid pt for each of my particles
check that full stencil for the particle will fit in my 3d brick
store central grid pt indices in part2grid array
------------------------------------------------------------------------- */
void PPPMTIP4P::particle_map()
{
int nx,ny,nz,iH1,iH2;
double *xi,xM[3];
int *type = atom->type;
double **x = atom->x;
int nlocal = atom->nlocal;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
if (type[i] == typeO) {
find_M(i,iH1,iH2,xM);
xi = xM;
} else xi = x[i];
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// current particle coord can be outside global and local box
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
nx = static_cast<int> ((xi[0]-boxlo[0])*delxinv+shift) - OFFSET;
ny = static_cast<int> ((xi[1]-boxlo[1])*delyinv+shift) - OFFSET;
nz = static_cast<int> ((xi[2]-boxlo[2])*delzinv+shift) - OFFSET;
part2grid[i][0] = nx;
part2grid[i][1] = ny;
part2grid[i][2] = nz;
// check that entire stencil around nx,ny,nz will fit in my 3d brick
if (nx+nlower < nxlo_out || nx+nupper > nxhi_out ||
ny+nlower < nylo_out || ny+nupper > nyhi_out ||
nz+nlower < nzlo_out || nz+nupper > nzhi_out) flag++;
}
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all) error->all(FLERR,"Out of range atoms - cannot compute PPPM");
}
/* ----------------------------------------------------------------------
create discretized "density" on section of global grid due to my particles
density(x,y,z) = charge "density" at grid points of my 3d brick
(nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
in global grid
------------------------------------------------------------------------- */
void PPPMTIP4P::make_rho()
{
int i,l,m,n,nx,ny,nz,mx,my,mz,iH1,iH2;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
double *xi,xM[3];
// clear 3d density array
FFT_SCALAR *vec = &density_brick[nzlo_out][nylo_out][nxlo_out];
for (i = 0; i < ngrid; i++) vec[i] = ZEROF;
// loop over my charges, add their contribution to nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
int *type = atom->type;
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (type[i] == typeO) {
find_M(i,iH1,iH2,xM);
xi = xM;
} else xi = x[i];
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (xi[0]-boxlo[0])*delxinv;
dy = ny+shiftone - (xi[1]-boxlo[1])*delyinv;
dz = nz+shiftone - (xi[2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
z0 = delvolinv * q[i];
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
y0 = z0*rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
x0 = y0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
density_brick[mz][my][mx] += x0*rho1d[0][l];
}
}
}
}
}
/* ----------------------------------------------------------------------
interpolate from grid to get electric field & force on my particles
------------------------------------------------------------------------- */
void PPPMTIP4P::fieldforce()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
FFT_SCALAR ekx,eky,ekz;
double *xi;
int iH1,iH2;
double xM[3];
double fx,fy,fz;
double ddotf, rOMx, rOMy, rOMz, f1x, f1y, f1z;
// loop over my charges, interpolate electric field from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
// ek = 3 components of E-field on particle
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) {
if (type[i] == typeO) {
find_M(i,iH1,iH2,xM);
xi = xM;
} else xi = x[i];
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (xi[0]-boxlo[0])*delxinv;
dy = ny+shiftone - (xi[1]-boxlo[1])*delyinv;
dz = nz+shiftone - (xi[2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
ekx = eky = ekz = ZEROF;
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
ekx -= x0*vdx_brick[mz][my][mx];
eky -= x0*vdy_brick[mz][my][mx];
ekz -= x0*vdz_brick[mz][my][mx];
}
}
}
// convert E-field to force
- const double qfactor = qqrd2e*scale*q[i];
+
+ const double qfactor = force->qqrd2e * scale * q[i];
if (type[i] != typeO) {
f[i][0] += qfactor*ekx;
f[i][1] += qfactor*eky;
f[i][2] += qfactor*ekz;
- } else {
+ } else {
fx = qfactor * ekx;
fy = qfactor * eky;
fz = qfactor * ekz;
find_M(i,iH1,iH2,xM);
rOMx = xM[0] - x[i][0];
rOMy = xM[1] - x[i][1];
rOMz = xM[2] - x[i][2];
ddotf = (rOMx * fx + rOMy * fy + rOMz * fz) / (qdist * qdist);
f1x = ddotf * rOMx;
f1y = ddotf * rOMy;
f1z = ddotf * rOMz;
f[i][0] += fx - alpha * (fx - f1x);
f[i][1] += fy - alpha * (fy - f1y);
f[i][2] += fz - alpha * (fz - f1z);
f[iH1][0] += 0.5*alpha*(fx - f1x);
f[iH1][1] += 0.5*alpha*(fy - f1y);
f[iH1][2] += 0.5*alpha*(fz - f1z);
f[iH2][0] += 0.5*alpha*(fx - f1x);
f[iH2][1] += 0.5*alpha*(fy - f1y);
f[iH2][2] += 0.5*alpha*(fz - f1z);
}
}
}
/* ----------------------------------------------------------------------
find 2 H atoms bonded to O atom i
compute position xM of fictitious charge site for O atom
also return local indices iH1,iH2 of H atoms
------------------------------------------------------------------------- */
void PPPMTIP4P::find_M(int i, int &iH1, int &iH2, double *xM)
{
iH1 = atom->map(atom->tag[i] + 1);
iH2 = atom->map(atom->tag[i] + 2);
if (iH1 == -1 || iH2 == -1) error->one(FLERR,"TIP4P hydrogen is missing");
if (atom->type[iH1] != typeH || atom->type[iH2] != typeH)
error->one(FLERR,"TIP4P hydrogen has incorrect atom type");
double **x = atom->x;
double delx1 = x[iH1][0] - x[i][0];
double dely1 = x[iH1][1] - x[i][1];
double delz1 = x[iH1][2] - x[i][2];
domain->minimum_image(delx1,dely1,delz1);
double delx2 = x[iH2][0] - x[i][0];
double dely2 = x[iH2][1] - x[i][1];
double delz2 = x[iH2][2] - x[i][2];
domain->minimum_image(delx2,dely2,delz2);
xM[0] = x[i][0] + alpha * 0.5 * (delx1 + delx2);
xM[1] = x[i][1] + alpha * 0.5 * (dely1 + dely2);
xM[2] = x[i][2] + alpha * 0.5 * (delz1 + delz2);
}
diff --git a/src/KSPACE/pppm_tip4p.h b/src/KSPACE/pppm_tip4p.h
index 764db68ed..35dd747ad 100644
--- a/src/KSPACE/pppm_tip4p.h
+++ b/src/KSPACE/pppm_tip4p.h
@@ -1,44 +1,45 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
KSpaceStyle(pppm/tip4p,PPPMTIP4P)
#else
#ifndef LMP_PPPM_TIP4P_H
#define LMP_PPPM_TIP4P_H
#include "pppm.h"
namespace LAMMPS_NS {
class PPPMTIP4P : public PPPM {
public:
PPPMTIP4P(class LAMMPS *, int, char **);
virtual ~PPPMTIP4P () {};
+ void init();
protected:
virtual void particle_map();
virtual void make_rho();
virtual void fieldforce();
private:
void find_M(int, int &, int &, double *);
};
}
#endif
#endif
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp
index c2625072c..fcbbc1e09 100644
--- a/src/MANYBODY/pair_airebo.cpp
+++ b/src/MANYBODY/pair_airebo.cpp
@@ -1,4199 +1,4199 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Ase Henry (MIT)
Bugfixes and optimizations:
Marcel Fallet & Steve Stuart (Clemson), Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "mpi.h"
#include "pair_airebo.h"
#include "atom.h"
#include "neighbor.h"
#include "neigh_request.h"
#include "force.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXLINE 1024
#define TOL 1.0e-9
#define PGDELTA 1
/* ---------------------------------------------------------------------- */
PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp)
{
single_enable = 0;
one_coeff = 1;
ghostneigh = 1;
maxlocal = 0;
REBO_numneigh = NULL;
REBO_firstneigh = NULL;
maxpage = 0;
pages = NULL;
nC = nH = NULL;
}
/* ----------------------------------------------------------------------
check if allocated, since class can be destructed when incomplete
------------------------------------------------------------------------- */
PairAIREBO::~PairAIREBO()
{
memory->destroy(REBO_numneigh);
memory->sfree(REBO_firstneigh);
for (int i = 0; i < maxpage; i++) memory->destroy(pages[i]);
memory->sfree(pages);
memory->destroy(nC);
memory->destroy(nH);
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cutghost);
memory->destroy(cutljsq);
memory->destroy(lj1);
memory->destroy(lj2);
memory->destroy(lj3);
memory->destroy(lj4);
delete [] map;
}
}
/* ---------------------------------------------------------------------- */
void PairAIREBO::compute(int eflag, int vflag)
{
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = vflag_atom = 0;
REBO_neigh();
FREBO(eflag,vflag);
if (ljflag) FLJ(eflag,vflag);
if (torflag) TORSION(eflag,vflag);
if (vflag_fdotr) virial_fdotr_compute();
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairAIREBO::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cutghost,n+1,n+1,"pair:cutghost");
// only sized by C,H = 2 types
memory->create(cutljsq,2,2,"pair:cutljsq");
memory->create(lj1,2,2,"pair:lj1");
memory->create(lj2,2,2,"pair:lj2");
memory->create(lj3,2,2,"pair:lj3");
memory->create(lj4,2,2,"pair:lj4");
map = new int[n+1];
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairAIREBO::settings(int narg, char **arg)
{
if (narg != 1 && narg != 3) error->all(FLERR,"Illegal pair_style command");
cutlj = force->numeric(arg[0]);
ljflag = torflag = 1;
if (narg == 3) {
ljflag = force->inumeric(arg[1]);
torflag = force->inumeric(arg[2]);
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairAIREBO::coeff(int narg, char **arg)
{
if (!allocated) allocate();
if (narg != 3 + atom->ntypes)
error->all(FLERR,"Incorrect args for pair coefficients");
// insure I,J args are * *
if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
error->all(FLERR,"Incorrect args for pair coefficients");
// read args that map atom types to C and H
// map[i] = which element (0,1) the Ith atom type is, -1 if NULL
for (int i = 3; i < narg; i++) {
if (strcmp(arg[i],"NULL") == 0) {
map[i-2] = -1;
continue;
} else if (strcmp(arg[i],"C") == 0) {
map[i-2] = 0;
} else if (strcmp(arg[i],"H") == 0) {
map[i-2] = 1;
} else error->all(FLERR,"Incorrect args for pair coefficients");
}
// read potential file and initialize fitting splines
read_file(arg[2]);
spline_init();
// clear setflag since coeff() called once with I,J = * *
int n = atom->ntypes;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
// set setflag i,j for type pairs where both are mapped to elements
int count = 0;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
if (map[i] >= 0 && map[j] >= 0) {
setflag[i][j] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairAIREBO::init_style()
{
if (atom->tag_enable == 0)
error->all(FLERR,"Pair style AIREBO requires atom IDs");
if (force->newton_pair == 0)
error->all(FLERR,"Pair style AIREBO requires newton pair on");
// need a full neighbor list, including neighbors of ghosts
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
neighbor->requests[irequest]->ghost = 1;
// local REBO neighbor list memory
pgsize = neighbor->pgsize;
oneatom = neighbor->oneatom;
if (maxpage == 0) add_pages();
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairAIREBO::init_one(int i, int j)
{
if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
// convert to C,H types
int ii = map[i];
int jj = map[j];
// use C-C values for these cutoffs since C atoms are biggest
// cut3rebo = 3 REBO distances
cut3rebo = 3.0 * rcmax[0][0];
// cutljrebosq = furthest distance from an owned atom a ghost atom can be
// to need its REBO neighs computed
// interaction = M-K-I-J-L-N with I = owned and J = ghost
// this insures N is in the REBO neigh list of L
// since I-J < rcLJmax and J-L < rmax
double cutljrebo = rcLJmax[0][0] + rcmax[0][0];
cutljrebosq = cutljrebo * cutljrebo;
// cutmax = furthest distance from an owned atom
// at which another atom will feel force, i.e. the ghost cutoff
// for REBO term in potential:
// interaction = M-K-I-J-L-N with I = owned and J = ghost
// I to N is max distance = 3 REBO distances
// for LJ term in potential:
// short interaction = M-K-I-J-L-N with I = owned, J = ghost, I-J < rcLJmax
// rcLJmax + 2*rcmax, since I-J < rcLJmax and J-L,L-N = REBO distances
// long interaction = I-J with I = owned and J = ghost
// cutlj*sigma, since I-J < LJ cutoff
// cutghost = REBO cutoff used in REBO_neigh() for neighbors of ghosts
double cutmax = cut3rebo;
if (ljflag) {
cutmax = MAX(cutmax,rcLJmax[0][0] + 2.0*rcmax[0][0]);
cutmax = MAX(cutmax,cutlj*sigma[0][0]);
}
cutghost[i][j] = rcmax[ii][jj];
cutljsq[ii][jj] = cutlj*sigma[ii][jj] * cutlj*sigma[ii][jj];
lj1[ii][jj] = 48.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0);
lj2[ii][jj] = 24.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0);
lj3[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0);
lj4[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0);
cutghost[j][i] = cutghost[i][j];
cutljsq[jj][ii] = cutljsq[ii][jj];
lj1[jj][ii] = lj1[ii][jj];
lj2[jj][ii] = lj2[ii][jj];
lj3[jj][ii] = lj3[ii][jj];
lj4[jj][ii] = lj4[ii][jj];
return cutmax;
}
/* ----------------------------------------------------------------------
create REBO neighbor list from main neighbor list
REBO neighbor list stores neighbors of ghost atoms
------------------------------------------------------------------------- */
void PairAIREBO::REBO_neigh()
{
int i,j,ii,jj,n,allnum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS;
int *ilist,*jlist,*numneigh,**firstneigh;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
if (atom->nmax > maxlocal) {
maxlocal = atom->nmax;
memory->destroy(REBO_numneigh);
memory->sfree(REBO_firstneigh);
memory->destroy(nC);
memory->destroy(nH);
memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh");
REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),
"AIREBO:firstneigh");
memory->create(nC,maxlocal,"AIREBO:nC");
memory->create(nH,maxlocal,"AIREBO:nH");
}
allnum = list->inum + list->gnum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// store all REBO neighs of owned and ghost atoms
// scan full neighbor list of I
int npage = 0;
int npnt = 0;
for (ii = 0; ii < allnum; ii++) {
i = ilist[ii];
if (pgsize - npnt < oneatom) {
npnt = 0;
npage++;
if (npage == maxpage) add_pages();
}
neighptr = &pages[npage][npnt];
n = 0;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = map[type[i]];
nC[i] = nH[i] = 0.0;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < rcmaxsq[itype][jtype]) {
neighptr[n++] = j;
if (jtype == 0)
nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
else
nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
}
}
REBO_firstneigh[i] = neighptr;
REBO_numneigh[i] = n;
npnt += n;
if (npnt >= pgsize)
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
}
}
/* ----------------------------------------------------------------------
REBO forces and energy
------------------------------------------------------------------------- */
void PairAIREBO::FREBO(int eflag, int vflag)
{
int i,j,k,m,ii,inum,itype,jtype,itag,jtag;
double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
double rsq,rij,wij;
double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
double dwij,del[3];
int *ilist,*REBO_neighs;
evdwl = 0.0;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int *tag = atom->tag;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
// two-body interactions from REBO neighbor list, skip half of them
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
j = REBO_neighs[k];
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
delx = x[i][0] - x[j][0];
dely = x[i][1] - x[j][1];
delz = x[i][2] - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
rij = sqrt(rsq);
wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
if (wij <= TOL) continue;
Qij = Q[itype][jtype];
Aij = A[itype][jtype];
alphaij = alpha[itype][jtype];
VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij);
pre = wij*Aij * exp(-alphaij*rij);
dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij));
dVRdi += VR/wij * dwij;
VA = dVA = 0.0;
for (m = 0; m < 3; m++) {
term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij);
VA += term;
dVA += -Beta[itype][jtype][m] * term;
}
dVA += VA/wij * dwij;
del[0] = delx;
del[1] = dely;
del[2] = delz;
bij = bondorder(i,j,del,rij,VA,f,vflag_atom);
dVAdi = bij*dVA;
fpair = -(dVRdi+dVAdi) / rij;
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
if (eflag) evdwl = VR + bij*VA;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
}
}
}
/* ----------------------------------------------------------------------
compute LJ forces and energy
find 3- and 4-step paths between atoms I,J via REBO neighbor lists
------------------------------------------------------------------------- */
void PairAIREBO::FLJ(int eflag, int vflag)
{
int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype,itag,jtag;
int atomi,atomj,atomk,atomm;
int testpath,npath,done;
double evdwl,fpair,xtmp,ytmp,ztmp;
double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
double delij[3],rijsq,delik[3],rik,deljk[3];
double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2;
double rljmin,rljmax,sigcut,sigmin,sigwid;
double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
int *ilist,*jlist,*numneigh,**firstneigh;
int *REBO_neighs_i,*REBO_neighs_k;
double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3];
double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
double fpair1,fpair2,fpair3;
double fi[3],fj[3],fk[3],fm[3];
// I-J interaction from full neighbor list
// skip 1/2 of interactions since only consider each pair once
evdwl = 0.0;
rljmin = 0.0;
rljmax = 0.0;
sigcut = 0.0;
sigmin = 0.0;
sigwid = 0.0;
double **x = atom->x;
double **f = atom->f;
int *tag = atom->tag;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
atomi = i;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
atomj = j;
delij[0] = xtmp - x[j][0];
delij[1] = ytmp - x[j][1];
delij[2] = ztmp - x[j][2];
rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2];
// if outside of LJ cutoff, skip
// if outside of 4-path cutoff, best = 0.0, no need to test paths
// if outside of 2-path cutoff but inside 4-path cutoff,
// best = 0.0, test 3-,4-paths
// if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1
if (rijsq >= cutljsq[itype][jtype]) continue;
rij = sqrt(rijsq);
if (rij >= cut3rebo) {
best = 0.0;
testpath = 0;
} else if (rij >= rcmax[itype][jtype]) {
best = 0.0;
testpath = 1;
} else {
best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
npath = 2;
if (best < 1.0) testpath = 1;
else testpath = 0;
}
done = 0;
if (testpath) {
// test all 3-body paths = I-K-J
// I-K interactions come from atom I's REBO neighbors
// if wik > current best, compute wkj
// if best = 1.0, done
REBO_neighs_i = REBO_firstneigh[i];
for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) {
k = REBO_neighs_i[kk];
if (k == j) continue;
ktype = map[type[k]];
delik[0] = x[i][0] - x[k][0];
delik[1] = x[i][1] - x[k][1];
delik[2] = x[i][2] - x[k][2];
rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2];
if (rsq < rcmaxsq[itype][ktype]) {
rik = sqrt(rsq);
wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
} else wik = 0.0;
if (wik > best) {
deljk[0] = x[j][0] - x[k][0];
deljk[1] = x[j][1] - x[k][1];
deljk[2] = x[j][2] - x[k][2];
rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
if (rsq < rcmaxsq[ktype][jtype]) {
rkj = sqrt(rsq);
wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj);
if (wik*wkj > best) {
best = wik*wkj;
npath = 3;
atomk = k;
delikS[0] = delik[0];
delikS[1] = delik[1];
delikS[2] = delik[2];
rikS = rik;
wikS = wik;
dwikS = dwik;
deljkS[0] = deljk[0];
deljkS[1] = deljk[1];
deljkS[2] = deljk[2];
rkjS = rkj;
wkjS = wkj;
dwkjS = dwkj;
if (best == 1.0) {
done = 1;
break;
}
}
}
// test all 4-body paths = I-K-M-J
// K-M interactions come from atom K's REBO neighbors
// if wik*wkm > current best, compute wmj
// if best = 1.0, done
REBO_neighs_k = REBO_firstneigh[k];
for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) {
m = REBO_neighs_k[mm];
if (m == i || m == j) continue;
mtype = map[type[m]];
delkm[0] = x[k][0] - x[m][0];
delkm[1] = x[k][1] - x[m][1];
delkm[2] = x[k][2] - x[m][2];
rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2];
if (rsq < rcmaxsq[ktype][mtype]) {
rkm = sqrt(rsq);
wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm);
} else wkm = 0.0;
if (wik*wkm > best) {
deljm[0] = x[j][0] - x[m][0];
deljm[1] = x[j][1] - x[m][1];
deljm[2] = x[j][2] - x[m][2];
rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] +
deljm[2]*deljm[2];
if (rsq < rcmaxsq[mtype][jtype]) {
rmj = sqrt(rsq);
wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj);
if (wik*wkm*wmj > best) {
best = wik*wkm*wmj;
npath = 4;
atomk = k;
delikS[0] = delik[0];
delikS[1] = delik[1];
delikS[2] = delik[2];
rikS = rik;
wikS = wik;
dwikS = dwik;
atomm = m;
delkmS[0] = delkm[0];
delkmS[1] = delkm[1];
delkmS[2] = delkm[2];
rkmS = rkm;
wkmS = wkm;
dwkmS = dwkm;
deljmS[0] = deljm[0];
deljmS[1] = deljm[1];
deljmS[2] = deljm[2];
rmjS = rmj;
wmjS = wmj;
dwmjS = dwmj;
if (best == 1.0) {
done = 1;
break;
}
}
}
}
}
}
}
}
cij = 1.0 - best;
if (cij == 0.0) continue;
// compute LJ forces and energy
sigwid = 0.84;
sigcut = 3.0;
sigmin = sigcut - sigwid;
rljmin = sigma[itype][jtype];
rljmax = sigcut * rljmin;
rljmin = sigmin * rljmin;
if (rij > rljmax){
slw = 0.0;
dslw = 0.0;}
else if (rij > rljmin){
drij = rij - rljmin;
swidth = rljmax - rljmin;
tee = drij / swidth;
tee2 = pow (tee,2);
slw = 1.0 - tee2 * (3.0 - 2.0 * tee);
dslw = 6.0 * tee * (1.0 - tee) / rij / swidth;
}
else
slw = 1.0;
dslw = 0.0;
r2inv = 1.0/rijsq;
r6inv = r2inv*r2inv*r2inv;
vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij;
// VLJ now becomes vdw * slw, derivaties, etc.
VLJ = vdw * slw;
dVLJ = dvdw * slw + vdw * dslw;
Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr);
VA = Str*cij*VLJ;
if (Str > 0.0) {
scale = rcmin[itype][jtype] / rij;
delscale[0] = scale * delij[0];
delscale[1] = scale * delij[1];
delscale[2] = scale * delij[2];
Stb = bondorderLJ(i,j,delscale,rcmin[itype][jtype],VA,
delij,rij,f,vflag_atom);
} else Stb = 0.0;
fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
f[i][0] += delij[0]*fpair;
f[i][1] += delij[1]*fpair;
f[i][2] += delij[2]*fpair;
f[j][0] -= delij[0]*fpair;
f[j][1] -= delij[1]*fpair;
f[j][2] -= delij[2]*fpair;
if (eflag) evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delij[0],delij[1],delij[2]);
if (cij < 1.0) {
dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
if (npath == 2) {
fpair = dC*dwij / rij;
f[atomi][0] += delij[0]*fpair;
f[atomi][1] += delij[1]*fpair;
f[atomi][2] += delij[2]*fpair;
f[atomj][0] -= delij[0]*fpair;
f[atomj][1] -= delij[1]*fpair;
f[atomj][2] -= delij[2]*fpair;
if (vflag_atom) v_tally2(atomi,atomj,fpair,delij);
} else if (npath == 3) {
fpair1 = dC*dwikS*wkjS / rikS;
fi[0] = delikS[0]*fpair1;
fi[1] = delikS[1]*fpair1;
fi[2] = delikS[2]*fpair1;
fpair2 = dC*wikS*dwkjS / rkjS;
fj[0] = deljkS[0]*fpair2;
fj[1] = deljkS[1]*fpair2;
fj[2] = deljkS[2]*fpair2;
f[atomi][0] += fi[0];
f[atomi][1] += fi[1];
f[atomi][2] += fi[2];
f[atomj][0] += fj[0];
f[atomj][1] += fj[1];
f[atomj][2] += fj[2];
f[atomk][0] -= fi[0] + fj[0];
f[atomk][1] -= fi[1] + fj[1];
f[atomk][2] -= fi[2] + fj[2];
if (vflag_atom)
v_tally3(atomi,atomj,atomk,fi,fj,delikS,deljkS);
} else {
fpair1 = dC*dwikS*wkmS*wmjS / rikS;
fi[0] = delikS[0]*fpair1;
fi[1] = delikS[1]*fpair1;
fi[2] = delikS[2]*fpair1;
fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
fk[0] = delkmS[0]*fpair2 - fi[0];
fk[1] = delkmS[1]*fpair2 - fi[1];
fk[2] = delkmS[2]*fpair2 - fi[2];
fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
fj[0] = deljmS[0]*fpair3;
fj[1] = deljmS[1]*fpair3;
fj[2] = deljmS[2]*fpair3;
fm[0] = -delkmS[0]*fpair2 - fj[0];
fm[1] = -delkmS[1]*fpair2 - fj[1];
fm[2] = -delkmS[2]*fpair2 - fj[2];
f[atomi][0] += fi[0];
f[atomi][1] += fi[1];
f[atomi][2] += fi[2];
f[atomj][0] += fj[0];
f[atomj][1] += fj[1];
f[atomj][2] += fj[2];
f[atomk][0] += fk[0];
f[atomk][1] += fk[1];
f[atomk][2] += fk[2];
f[atomm][0] += fm[0];
f[atomm][1] += fm[1];
f[atomm][2] += fm[2];
if (vflag_atom) {
delimS[0] = delikS[0] + delkmS[0];
delimS[1] = delikS[1] + delkmS[1];
delimS[2] = delikS[2] + delkmS[2];
v_tally4(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS);
}
}
}
}
}
}
/* ----------------------------------------------------------------------
torsional forces and energy
------------------------------------------------------------------------- */
void PairAIREBO::TORSION(int eflag, int vflag)
{
int i,j,k,l,ii,inum,itag,jtag;
double evdwl,fpair,xtmp,ytmp,ztmp;
double cos321;
double w21,dw21,cos234,w34,dw34;
double cross321[3],cross321mag,cross234[3],cross234mag;
double w23,dw23,cw2,ekijl,Ec;
double cw,cwnum,cwnom;
double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc;
double sin321,sin234,rjk2,rik2,ril2,rjl2;
double rjk,ril;
double Vtors;
double dndij[3],tmpvec[3],dndik[3],dndjl[3];
double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil;
double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil;
double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
double del32[3],rsq,r32,del23[3],del21[3],r21;
double deljk[3],del34[3],delil[3],delkl[3],r23,r34;
double fi[3],fj[3],fk[3],fl[3];
int itype,jtype,ktype,ltype,kk,ll,jj;
int *ilist,*REBO_neighs_i,*REBO_neighs_j;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int *tag = atom->tag;
inum = list->inum;
ilist = list->ilist;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
if (itype != 0) continue;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
REBO_neighs_i = REBO_firstneigh[i];
for (jj = 0; jj < REBO_numneigh[i]; jj++) {
j = REBO_neighs_i[jj];
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
if (jtype != 0) continue;
del32[0] = x[j][0]-x[i][0];
del32[1] = x[j][1]-x[i][1];
del32[2] = x[j][2]-x[i][2];
rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2];
r32 = sqrt(rsq);
del23[0] = -del32[0];
del23[1] = -del32[1];
del23[2] = -del32[2];
r23 = r32;
w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23);
for (kk = 0; kk < REBO_numneigh[i]; kk++) {
k = REBO_neighs_i[kk];
ktype = map[type[k]];
if (k == j) continue;
del21[0] = x[i][0]-x[k][0];
del21[1] = x[i][1]-x[k][1];
del21[2] = x[i][2]-x[k][2];
rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2];
r21 = sqrt(rsq);
cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) +
(del21[2]*del32[2])) / (r21*r32);
cos321 = MIN(cos321,1.0);
cos321 = MAX(cos321,-1.0);
sin321 = sqrt(1.0 - cos321*cos321);
if (sin321 < TOL) continue;
deljk[0] = del21[0]-del23[0];
deljk[1] = del21[1]-del23[1];
deljk[2] = del21[2]-del23[2];
rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
rjk=sqrt(rjk2);
rik2 = r21*r21;
w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21);
rij = r32;
rik = r21;
rij2 = r32*r32;
rik2 = r21*r21;
costmp = 0.5*(rij2+rik2-rjk2)/rij/rik;
tspjik = Sp2(costmp,thmin,thmax,dtsjik);
dtsjik = -dtsjik;
REBO_neighs_j = REBO_firstneigh[j];
for (ll = 0; ll < REBO_numneigh[j]; ll++) {
l = REBO_neighs_j[ll];
ltype = map[type[l]];
if (l == i || l == k) continue;
del34[0] = x[j][0]-x[l][0];
del34[1] = x[j][1]-x[l][1];
del34[2] = x[j][2]-x[l][2];
rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2];
r34 = sqrt(rsq);
cos234 = (del32[0]*del34[0] + del32[1]*del34[1] +
del32[2]*del34[2]) / (r32*r34);
cos234 = MIN(cos234,1.0);
cos234 = MAX(cos234,-1.0);
sin234 = sqrt(1.0 - cos234*cos234);
if (sin234 < TOL) continue;
w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34);
delil[0] = del23[0] + del34[0];
delil[1] = del23[1] + del34[1];
delil[2] = del23[2] + del34[2];
ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2];
ril=sqrt(ril2);
rjl2 = r34*r34;
rjl = r34;
rjl2 = r34*r34;
costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl;
tspijl = Sp2(costmp,thmin,thmax,dtsijl);
dtsijl = -dtsijl; //need minus sign
cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]);
cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]);
cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]);
cross321mag = sqrt(cross321[0]*cross321[0]+
cross321[1]*cross321[1]+
cross321[2]*cross321[2]);
cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]);
cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]);
cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]);
cross234mag = sqrt(cross234[0]*cross234[0]+
cross234[1]*cross234[1]+
cross234[2]*cross234[2]);
cwnum = (cross321[0]*cross234[0]) +
(cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
cwnom = r21*r34*r32*r32*sin321*sin234;
cw = cwnum/cwnom;
cw2 = (.5*(1.0-cw));
ekijl = epsilonT[ktype][ltype];
Ec = 256.0*ekijl/405.0;
Vtors = (Ec*(pow(cw2,5.0)))-(ekijl/10.0);
if (eflag) evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]);
tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]);
tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]);
tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]);
dndij[0] = dndij[0]+tmpvec[0];
dndij[1] = dndij[1]+tmpvec[1];
dndij[2] = dndij[2]+tmpvec[2];
dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]);
dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]);
dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]);
dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]);
dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]);
dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]);
dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21);
dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21);
dcidjk = (-rjk)/(r23*r21);
dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34);
dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34);
dcjdil = (-ril)/(r23*r34);
dsidij = (-cos321/sin321)*dcidij;
dsidik = (-cos321/sin321)*dcidik;
dsidjk = (-cos321/sin321)*dcidjk;
dsjdji = (-cos234/sin234)*dcjdji;
dsjdjl = (-cos234/sin234)*dcjdjl;
dsjdil = (-cos234/sin234)*dcjdil;
dxidij = (r21*sin321)+(r23*r21*dsidij);
dxidik = (r23*sin321)+(r23*r21*dsidik);
dxidjk = (r23*r21*dsidjk);
dxjdji = (r34*sin234)+(r23*r34*dsjdji);
dxjdjl = (r23*sin234)+(r23*r34*dsjdjl);
dxjdil = (r23*r34*dsjdil);
ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji);
ddndik = dxidik*cross234mag;
ddndjk = dxidjk*cross234mag;
ddndjl = cross321mag*dxjdjl;
ddndil = cross321mag*dxjdil;
dcwddn = -cwnum/(cwnom*cwnom);
dcwdn = 1.0/cwnom;
dvpdcw = (-1.0)*Ec*(-.5)*5.0*pow(cw2,4.0) *
w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
fi[0] = Ftmp[0];
fi[1] = Ftmp[1];
fi[2] = Ftmp[2];
fj[0] = -Ftmp[0];
fj[1] = -Ftmp[1];
fj[2] = -Ftmp[2];
Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
fi[0] += Ftmp[0];
fi[1] += Ftmp[1];
fi[2] += Ftmp[2];
fk[0] = -Ftmp[0];
fk[1] = -Ftmp[1];
fk[2] = -Ftmp[2];
Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
fj[0] += Ftmp[0];
fj[1] += Ftmp[1];
fj[2] += Ftmp[2];
fk[0] -= Ftmp[0];
fk[1] -= Ftmp[1];
fk[2] -= Ftmp[2];
Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
fj[0] += Ftmp[0];
fj[1] += Ftmp[1];
fj[2] += Ftmp[2];
fl[0] = -Ftmp[0];
fl[1] = -Ftmp[1];
fl[2] = -Ftmp[2];
Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
fi[0] += Ftmp[0];
fi[1] += Ftmp[1];
fi[2] += Ftmp[2];
fl[0] -= Ftmp[0];
fl[1] -= Ftmp[1];
fl[2] -= Ftmp[2];
// coordination forces
fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
fi[0] -= del21[0]*fpair;
fi[1] -= del21[1]*fpair;
fi[2] -= del21[2]*fpair;
fk[0] += del21[0]*fpair;
fk[1] += del21[1]*fpair;
fk[2] += del21[2]*fpair;
fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
fi[0] -= del23[0]*fpair;
fi[1] -= del23[1]*fpair;
fi[2] -= del23[2]*fpair;
fj[0] += del23[0]*fpair;
fj[1] += del23[1]*fpair;
fj[2] += del23[2]*fpair;
fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
fj[0] -= del34[0]*fpair;
fj[1] -= del34[1]*fpair;
fj[2] -= del34[2]*fpair;
fl[0] += del34[0]*fpair;
fl[1] += del34[1]*fpair;
fl[2] += del34[2]*fpair;
// additional cut off function forces
fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
fpair = fcpc*dcidij/rij;
fi[0] += fpair*del23[0];
fi[1] += fpair*del23[1];
fi[2] += fpair*del23[2];
fj[0] -= fpair*del23[0];
fj[1] -= fpair*del23[1];
fj[2] -= fpair*del23[2];
fpair = fcpc*dcidik/rik;
fi[0] += fpair*del21[0];
fi[1] += fpair*del21[1];
fi[2] += fpair*del21[2];
fk[0] -= fpair*del21[0];
fk[1] -= fpair*del21[1];
fk[2] -= fpair*del21[2];
fpair = fcpc*dcidjk/rjk;
fj[0] += fpair*deljk[0];
fj[1] += fpair*deljk[1];
fj[2] += fpair*deljk[2];
fk[0] -= fpair*deljk[0];
fk[1] -= fpair*deljk[1];
fk[2] -= fpair*deljk[2];
fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
fpair = fcpc*dcjdji/rij;
fi[0] += fpair*del23[0];
fi[1] += fpair*del23[1];
fi[2] += fpair*del23[2];
fj[0] -= fpair*del23[0];
fj[1] -= fpair*del23[1];
fj[2] -= fpair*del23[2];
fpair = fcpc*dcjdjl/rjl;
fj[0] += fpair*del34[0];
fj[1] += fpair*del34[1];
fj[2] += fpair*del34[2];
fl[0] -= fpair*del34[0];
fl[1] -= fpair*del34[1];
fl[2] -= fpair*del34[2];
fpair = fcpc*dcjdil/ril;
fi[0] += fpair*delil[0];
fi[1] += fpair*delil[1];
fi[2] += fpair*delil[2];
fl[0] -= fpair*delil[0];
fl[1] -= fpair*delil[1];
fl[2] -= fpair*delil[2];
// sum per-atom forces into atom force array
f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
if (evflag) {
delkl[0] = delil[0] - del21[0];
delkl[1] = delil[1] - del21[1];
delkl[2] = delil[2] - del21[2];
ev_tally4(i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl);
}
}
}
}
}
}
/* ----------------------------------------------------------------------
Bij function
------------------------------------------------------------------------- */
double PairAIREBO::bondorder(int i, int j, double rij[3],
double rijmag, double VA,
double **f, int vflag_atom)
{
int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
int itype,jtype,ktype,ltype,ntype;
double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij;
double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS;
double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
double dN2[2],dN3[3];
double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3];
double Tij;
double r32[3],r32mag,cos321,r43[3],r13[3];
double dNlj;
double om1234,rln[3];
double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
double cross321[3],cross234[3],prefactor,SpN;
double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3];
double f1[3],f2[3],f3[3],f4[4];
double dcut321,PijS,PjiS;
double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
double **x = atom->x;
int *type = atom->type;
atomi = i;
atomj = j;
itype = map[type[i]];
jtype = map[type[j]];
wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
NijC = nC[i]-(wij*kronecker(jtype,0));
NijH = nH[i]-(wij*kronecker(jtype,1));
NjiC = nC[j]-(wij*kronecker(itype,0));
NjiH = nH[j]-(wij*kronecker(itype,1));
bij = 0.0;
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
dgdc = 0.0;
dgdN = 0.0;
NconjtmpI = 0.0;
NconjtmpJ = 0.0;
Etmp = 0.0;
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
lamdajik = 4.0*kronecker(itype,1) *
((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
(rijmag*rikmag);
cosjik = MIN(cosjik,1.0);
cosjik = MAX(cosjik,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
Etmp = Etmp+(wik*g*exp(lamdajik));
tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
}
}
PijS = 0.0;
dN2[0] = 0.0;
dN2[1] = 0.0;
PijS = PijSpline(NijC,NijH,itype,jtype,dN2);
pij = pow(1.0+Etmp+PijS,-0.5);
tmp = -0.5*pow(pij,3.0);
// pij forces
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
lamdajik = 4.0*kronecker(itype,1) *
((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) /
(rijmag*rikmag);
cosjik = MIN(cosjik,1.0);
cosjik = MAX(cosjik,-1.0);
dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) -
(cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag))));
dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) -
(cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag))));
dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) -
(cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag))));
dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) +
(cosjik*(rik[0]/(rikmag*rikmag)));
dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) +
(cosjik*(rik[1]/(rikmag*rikmag)));
dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) +
(cosjik*(rik[2]/(rikmag*rikmag)));
dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) +
(cosjik*(rij[0]/(rijmag*rijmag)));
dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) +
(cosjik*(rij[1]/(rijmag*rijmag)));
dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) +
(cosjik*(rij[2]/(rijmag*rijmag)));
g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
fj[0] = -tmp2*dcosjikdrj[0];
fj[1] = -tmp2*dcosjikdrj[1];
fj[2] = -tmp2*dcosjikdrj[2];
fi[0] = -tmp2*dcosjikdri[0];
fi[1] = -tmp2*dcosjikdri[1];
fi[2] = -tmp2*dcosjikdri[2];
fk[0] = -tmp2*dcosjikdrk[0];
fk[1] = -tmp2*dcosjikdrk[1];
fk[2] = -tmp2*dcosjikdrk[2];
tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
fj[0] -= tmp2*(-rij[0]/rijmag);
fj[1] -= tmp2*(-rij[1]/rijmag);
fj[2] -= tmp2*(-rij[2]/rijmag);
fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag));
fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag));
fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag));
fk[0] -= tmp2*(rik[0]/rikmag);
fk[1] -= tmp2*(rik[1]/rikmag);
fk[2] -= tmp2*(rik[2]/rikmag);
// coordination forces
// dwik forces
tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
// PIJ forces
tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
// dgdN forces
tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
if (vflag_atom) {
rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
v_tally3(atomi,atomj,atomk,fj,fk,rji,rki);
}
}
}
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
Etmp = 0.0;
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
lamdaijl = 4.0*kronecker(jtype,1) *
((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) +
nH[atoml]-(wjl*kronecker(jtype,1));
cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
(rijmag*rjlmag);
cosijl = MIN(cosijl,1.0);
cosijl = MAX(cosijl,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
Etmp = Etmp+(wjl*g*exp(lamdaijl));
tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
}
}
PjiS = 0.0;
dN2[0] = 0.0;
dN2[1] = 0.0;
PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2);
pji = pow(1.0+Etmp+PjiS,-0.5);
tmp = -0.5*pow(pji,3.0);
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
lamdaijl = 4.0*kronecker(jtype,1) *
((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) /
(rijmag*rjlmag);
cosijl = MIN(cosijl,1.0);
cosijl = MAX(cosijl,-1.0);
dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) -
(cosijl*rij[0]/(rijmag*rijmag));
dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) -
(cosijl*rij[1]/(rijmag*rijmag));
dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) -
(cosijl*rij[2]/(rijmag*rijmag));
dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) +
(cosijl*((rij[0]/pow(rijmag,2.0))-(rjl[0]/(rjlmag*rjlmag))));
dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) +
(cosijl*((rij[1]/pow(rijmag,2.0))-(rjl[1]/(rjlmag*rjlmag))));
dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) +
(cosijl*((rij[2]/pow(rijmag,2.0))-(rjl[2]/(rjlmag*rjlmag))));
dcosijldrl[0] = (rij[0]/(rijmag*rjlmag))+(cosijl*rjl[0]/(rjlmag*rjlmag));
dcosijldrl[1] = (rij[1]/(rijmag*rjlmag))+(cosijl*rjl[1]/(rjlmag*rjlmag));
dcosijldrl[2] = (rij[2]/(rijmag*rjlmag))+(cosijl*rjl[2]/(rjlmag*rjlmag));
// evaluate splines g and derivatives dg
g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
fi[0] = -tmp2*dcosijldri[0];
fi[1] = -tmp2*dcosijldri[1];
fi[2] = -tmp2*dcosijldri[2];
fj[0] = -tmp2*dcosijldrj[0];
fj[1] = -tmp2*dcosijldrj[1];
fj[2] = -tmp2*dcosijldrj[2];
fl[0] = -tmp2*dcosijldrl[0];
fl[1] = -tmp2*dcosijldrl[1];
fl[2] = -tmp2*dcosijldrl[2];
tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
fi[0] -= tmp2*(rij[0]/rijmag);
fi[1] -= tmp2*(rij[1]/rijmag);
fi[2] -= tmp2*(rij[2]/rijmag);
fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag));
fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag));
fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag));
fl[0] -= tmp2*(rjl[0]/rjlmag);
fl[1] -= tmp2*(rjl[1]/rjlmag);
fl[2] -= tmp2*(rjl[2]/rjlmag);
// coordination forces
// dwik forces
tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
// PIJ forces
tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
// dgdN forces
tmp2 = VA*.5*(tmp*tmp3*dwjl)/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
if (vflag_atom) {
rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj);
}
}
}
// evaluate Nij conj
Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3);
// piRC forces
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
if (atomk !=atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
SpN = Sp(Nki,Nmin,Nmax,dNki);
tmp2 = VA*dN3[0]*dwik/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
if (fabs(dNki) > TOL) {
REBO_neighs_k = REBO_firstneigh[atomk];
for (n = 0; n < REBO_numneigh[atomk]; n++) {
atomn = REBO_neighs_k[n];
if (atomn != atomi) {
ntype = map[type[atomn]];
rkn[0] = x[atomk][0]-x[atomn][0];
rkn[1] = x[atomk][1]-x[atomn][1];
rkn[2] = x[atomk][2]-x[atomn][2];
rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
f[atomk][0] -= tmp2*rkn[0];
f[atomk][1] -= tmp2*rkn[1];
f[atomk][2] -= tmp2*rkn[2];
f[atomn][0] += tmp2*rkn[0];
f[atomn][1] += tmp2*rkn[1];
f[atomn][2] += tmp2*rkn[2];
if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
}
}
}
}
}
// piRC forces
REBO_neighs = REBO_firstneigh[atomj];
for (l = 0; l < REBO_numneigh[atomj]; l++) {
atoml = REBO_neighs[l];
if (atoml !=atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
SpN = Sp(Nlj,Nmin,Nmax,dNlj);
tmp2 = VA*dN3[1]*dwjl/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
if (fabs(dNlj) > TOL) {
REBO_neighs_l = REBO_firstneigh[atoml];
for (n = 0; n < REBO_numneigh[atoml]; n++) {
atomn = REBO_neighs_l[n];
if (atomn != atomj) {
ntype = map[type[atomn]];
rln[0] = x[atoml][0]-x[atomn][0];
rln[1] = x[atoml][1]-x[atomn][1];
rln[2] = x[atoml][2]-x[atomn][2];
rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
f[atoml][0] -= tmp2*rln[0];
f[atoml][1] -= tmp2*rln[1];
f[atoml][2] -= tmp2*rln[2];
f[atomn][0] += tmp2*rln[0];
f[atomn][1] += tmp2*rln[1];
f[atomn][2] += tmp2*rln[2];
if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
}
}
}
}
}
Tij = 0.0;
dN3[0] = 0.0;
dN3[1] = 0.0;
dN3[2] = 0.0;
if (itype == 0 && jtype == 0)
Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3);
Etmp = 0.0;
if (fabs(Tij) > TOL) {
atom2 = atomi;
atom3 = atomj;
r32[0] = x[atom3][0]-x[atom2][0];
r32[1] = x[atom3][1]-x[atom2][1];
r32[2] = x[atom3][2]-x[atom2][2];
r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
r23[0] = -r32[0];
r23[1] = -r32[1];
r23[2] = -r32[2];
r23mag = r32mag;
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
atom1 = atomk;
ktype = map[type[atomk]];
if (atomk != atomj) {
r21[0] = x[atom2][0]-x[atom1][0];
r21[1] = x[atom2][1]-x[atom1][1];
r21[2] = x[atom2][2]-x[atom1][2];
r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) /
(r21mag*r32mag);
cos321 = MIN(cos321,1.0);
cos321 = MAX(cos321,-1.0);
Sp2(cos321,thmin,thmax,dcut321);
sin321 = sqrt(1.0 - cos321*cos321);
sink2i = 1.0/(sin321*sin321);
rik2i = 1.0/(r21mag*r21mag);
if (sin321 != 0.0) {
rr = (r23mag*r23mag)-(r21mag*r21mag);
rjk[0] = r21[0]-r23[0];
rjk[1] = r21[1]-r23[1];
rjk[2] = r21[2]-r23[2];
rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
rijrik = 2.0*r23mag*r21mag;
rik2 = r21mag*r21mag;
dctik = (-rr+rjk2)/(rijrik*rik2);
dctij = (rr+rjk2)/(rijrik*r23mag*r23mag);
dctjk = -2.0/rijrik;
w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
rijmag = r32mag;
rikmag = r21mag;
rij2 = r32mag*r32mag;
rik2 = r21mag*r21mag;
costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
tspjik = Sp2(costmp,thmin,thmax,dtsjik);
dtsjik = -dtsjik;
REBO_neighs_j = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs_j[l];
atom4 = atoml;
ltype = map[type[atoml]];
if (!(atoml == atomi || atoml == atomk)) {
r34[0] = x[atom3][0]-x[atom4][0];
r34[1] = x[atom3][1]-x[atom4][1];
r34[2] = x[atom3][2]-x[atom4][2];
r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2]));
cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) /
(r32mag*r34mag);
cos234 = MIN(cos234,1.0);
cos234 = MAX(cos234,-1.0);
sin234 = sqrt(1.0 - cos234*cos234);
sinl2i = 1.0/(sin234*sin234);
rjl2i = 1.0/(r34mag*r34mag);
if (sin234 != 0.0) {
w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34);
rr = (r23mag*r23mag)-(r34mag*r34mag);
ril[0] = r23[0]+r34[0];
ril[1] = r23[1]+r34[1];
ril[2] = r23[2]+r34[2];
ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
rijrjl = 2.0*r23mag*r34mag;
rjl2 = r34mag*r34mag;
dctjl = (-rr+ril2)/(rijrjl*rjl2);
dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
dctil = -2.0/rijrjl;
rjlmag = r34mag;
rjl2 = r34mag*r34mag;
costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
tspijl = Sp2(costmp,thmin,thmax,dtsijl);
dtsijl = -dtsijl;
prefactor = VA*Tij;
cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
cwnum = (cross321[0]*cross234[0]) +
(cross321[1]*cross234[1]) + (cross321[2]*cross234[2]);
cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
om1234 = cwnum/cwnom;
cw = om1234;
Etmp += ((1.0-pow(om1234,2.0))*w21*w34) *
(1.0-tspjik)*(1.0-tspijl);
dt1dik = (rik2i)-(dctik*sink2i*cos321);
dt1djk = (-dctjk*sink2i*cos321);
dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
dt1dil = (-dctil*sinl2i*cos234);
dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) -
(dctji*sinl2i*cos234);
dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) -
(r21[1]*cross234[2])+(r34[1]*cross321[2]);
dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) -
(r21[2]*cross234[0])+(r34[2]*cross321[0]);
dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) -
(r21[0]*cross234[1])+(r34[0]*cross321[1]);
aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
(1.0-tspjik)*(1.0-tspijl);
aaa1 = -prefactor*(1.0-pow(om1234,2.0)) *
(1.0-tspjik)*(1.0-tspijl);
aaa2 = aaa1*w21*w34;
at2 = aa*cwnum;
fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
(aaa2*dtsijl*dctji*(1.0-tspjik));
fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
F31[0] = (fcjkpc*rjk[0]);
F31[1] = (fcjkpc*rjk[1]);
F31[2] = (fcjkpc*rjk[2]);
F24[0] = (fcilpc*ril[0]);
F24[1] = (fcilpc*ril[1]);
F24[2] = (fcilpc*ril[2]);
f1[0] = -F12[0]-F31[0];
f1[1] = -F12[1]-F31[1];
f1[2] = -F12[2]-F31[2];
f2[0] = F23[0]+F12[0]+F24[0];
f2[1] = F23[1]+F12[1]+F24[1];
f2[2] = F23[2]+F12[2]+F24[2];
f3[0] = -F23[0]+F34[0]+F31[0];
f3[1] = -F23[1]+F34[1]+F31[1];
f3[2] = -F23[2]+F34[2]+F31[2];
f4[0] = -F34[0]-F24[0];
f4[1] = -F34[1]-F24[1];
f4[2] = -F34[2]-F24[2];
// coordination forces
tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
(1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
f2[0] -= tmp2*r21[0];
f2[1] -= tmp2*r21[1];
f2[2] -= tmp2*r21[2];
f1[0] += tmp2*r21[0];
f1[1] += tmp2*r21[1];
f1[2] += tmp2*r21[2];
tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
(1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
f3[0] -= tmp2*r34[0];
f3[1] -= tmp2*r34[1];
f3[2] -= tmp2*r34[2];
f4[0] += tmp2*r34[0];
f4[1] += tmp2*r34[1];
f4[2] += tmp2*r34[2];
f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
f[atom1][2] += f1[2];
f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
f[atom2][2] += f2[2];
f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
f[atom3][2] += f3[2];
f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
f[atom4][2] += f4[2];
if (vflag_atom) {
r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43);
}
}
}
}
}
}
}
// Tij forces now that we have Etmp
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
SpN = Sp(Nki,Nmin,Nmax,dNki);
tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
if (fabs(dNki) > TOL) {
REBO_neighs_k = REBO_firstneigh[atomk];
for (n = 0; n < REBO_numneigh[atomk]; n++) {
atomn = REBO_neighs_k[n];
ntype = map[type[atomn]];
if (atomn != atomi) {
rkn[0] = x[atomk][0]-x[atomn][0];
rkn[1] = x[atomk][1]-x[atomn][1];
rkn[2] = x[atomk][2]-x[atomn][2];
rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
f[atomk][0] -= tmp2*rkn[0];
f[atomk][1] -= tmp2*rkn[1];
f[atomk][2] -= tmp2*rkn[2];
f[atomn][0] += tmp2*rkn[0];
f[atomn][1] += tmp2*rkn[1];
f[atomn][2] += tmp2*rkn[2];
if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
}
}
}
}
}
// Tij forces
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
SpN = Sp(Nlj,Nmin,Nmax,dNlj);
tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
if (fabs(dNlj) > TOL) {
REBO_neighs_l = REBO_firstneigh[atoml];
for (n = 0; n < REBO_numneigh[atoml]; n++) {
atomn = REBO_neighs_l[n];
ntype = map[type[atomn]];
if (atomn !=atomj) {
rln[0] = x[atoml][0]-x[atomn][0];
rln[1] = x[atoml][1]-x[atomn][1];
rln[2] = x[atoml][2]-x[atomn][2];
rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
f[atoml][0] -= tmp2*rln[0];
f[atoml][1] -= tmp2*rln[1];
f[atoml][2] -= tmp2*rln[2];
f[atomn][0] += tmp2*rln[0];
f[atomn][1] += tmp2*rln[1];
f[atomn][2] += tmp2*rln[2];
if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
}
}
}
}
}
}
bij = (0.5*(pij+pji))+piRC+(Tij*Etmp);
return bij;
}
/* ----------------------------------------------------------------------
Bij* function
------------------------------------------------------------------------- */
double PairAIREBO::bondorderLJ(int i, int j, double rij[3], double rijmag,
double VA, double rij0[3], double rij0mag,
double **f, int vflag_atom)
{
int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
int atomi,atomj,itype,jtype,ktype,ltype,ntype;
double rik[3], rjl[3], rkn[3],rknmag,dNki;
double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ;
double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
double dN2[2],dN3[3];
double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl;
double Tij,crosskij[3],crosskijmag;
double crossijl[3],crossijlmag,omkijl;
double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3];
double bij,tmp3pij,tmp3pji,Stb,dStb;
double r32[3],r32mag,cos321;
double om1234,rln[3];
double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
double cross321[3],cross234[3],prefactor,SpN;
double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
double dNlj;
double PijS,PjiS;
double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
double F12[3],F23[3],F34[3],F31[3],F24[3];
double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4];
double rji[3],rki[3],rlj[3],r13[3],r43[3];
double **x = atom->x;
int *type = atom->type;
atomi = i;
atomj = j;
itype = map[type[atomi]];
jtype = map[type[atomj]];
wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
NijC = nC[atomi]-(wij*kronecker(jtype,0));
NijH = nH[atomi]-(wij*kronecker(jtype,1));
NjiC = nC[atomj]-(wij*kronecker(itype,0));
NjiH = nH[atomj]-(wij*kronecker(itype,1));
bij = 0.0;
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
dgdc = 0.0;
dgdN = 0.0;
NconjtmpI = 0.0;
NconjtmpJ = 0.0;
Etmp = 0.0;
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
lamdajik = 4.0*kronecker(itype,1) *
((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
Nki = nC[atomk]-(wik*kronecker(itype,0)) +
nH[atomk]-(wik*kronecker(itype,1));
cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
(rijmag*rikmag);
cosjik = MIN(cosjik,1.0);
cosjik = MAX(cosjik,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
Etmp = Etmp+(wik*g*exp(lamdajik));
tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
}
}
PijS = 0.0;
dN2PIJ[0] = 0.0;
dN2PIJ[1] = 0.0;
PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ);
pij = pow(1.0+Etmp+PijS,-0.5);
tmppij = -.5*pow(pij,3.0);
tmp3pij = tmp3;
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
Etmp = 0.0;
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
lamdaijl = 4.0*kronecker(jtype,1) *
((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
(rijmag*rjlmag);
cosijl = MIN(cosijl,1.0);
cosijl = MAX(cosijl,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
Etmp = Etmp+(wjl*g*exp(lamdaijl));
tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
}
}
PjiS = 0.0;
dN2PJI[0] = 0.0;
dN2PJI[1] = 0.0;
PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI);
pji = pow(1.0+Etmp+PjiS,-0.5);
tmppji = -.5*pow(pji,3.0);
tmp3pji = tmp3;
// evaluate Nij conj
Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC);
Tij = 0.0;
dN3Tij[0] = 0.0;
dN3Tij[1] = 0.0;
dN3Tij[2] = 0.0;
if (itype == 0 && jtype == 0)
Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij);
Etmp = 0.0;
if (fabs(Tij) > TOL) {
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
ktype = map[type[atomk]];
if (atomk != atomj) {
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
(rijmag*rikmag);
cos321 = MIN(cos321,1.0);
cos321 = MAX(cos321,-1.0);
rjk[0] = rik[0]-rij[0];
rjk[1] = rik[1]-rij[1];
rjk[2] = rik[2]-rij[2];
rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
rij2 = rijmag*rijmag;
rik2 = rikmag*rikmag;
costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
tspjik = Sp2(costmp,thmin,thmax,dtsjik);
if (sqrt(1.0 - cos321*cos321) != 0.0) {
wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik);
REBO_neighs_j = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs_j[l];
ltype = map[type[atoml]];
if (!(atoml == atomi || atoml == atomk)) {
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]);
cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
(rijmag*rjlmag);
cos234 = MIN(cos234,1.0);
cos234 = MAX(cos234,-1.0);
ril[0] = rij[0]+rjl[0];
ril[1] = rij[1]+rjl[1];
ril[2] = rij[2]+rjl[2];
ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
rijrjl = 2.0*rijmag*rjlmag;
rjl2 = rjlmag*rjlmag;
costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
tspijl = Sp2(costmp,thmin,thmax,dtsijl);
if (sqrt(1.0 - cos234*cos234) != 0.0) {
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS);
crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]);
crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]);
crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]);
crosskijmag = sqrt(crosskij[0]*crosskij[0] +
crosskij[1]*crosskij[1] +
crosskij[2]*crosskij[2]);
crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]);
crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]);
crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]);
crossijlmag = sqrt(crossijl[0]*crossijl[0] +
crossijl[1]*crossijl[1] +
crossijl[2]*crossijl[2]);
omkijl = -1.0*(((crosskij[0]*crossijl[0]) +
(crosskij[1]*crossijl[1]) +
(crosskij[2]*crossijl[2])) /
(crosskijmag*crossijlmag));
Etmp += ((1.0-pow(omkijl,2.0))*wik*wjl) *
(1.0-tspjik)*(1.0-tspijl);
}
}
}
}
}
}
}
bij = (.5*(pij+pji))+piRC+(Tij*Etmp);
Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb);
VA = VA*dStb;
if (dStb != 0.0) {
tmp = tmppij;
dN2[0] = dN2PIJ[0];
dN2[1] = dN2PIJ[1];
tmp3 = tmp3pij;
// pij forces
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
if (atomk != atomj) {
lamdajik = 0.0;
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]);
lamdajik = 4.0*kronecker(itype,1) *
((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
(rijmag*rikmag);
cosjik = MIN(cosjik,1.0);
cosjik = MAX(cosjik,-1.0);
dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) -
(cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag))));
dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) -
(cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag))));
dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) -
(cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag))));
dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) +
(cosjik*(rik[0]/(rikmag*rikmag)));
dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) +
(cosjik*(rik[1]/(rikmag*rikmag)));
dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) +
(cosjik*(rik[2]/(rikmag*rikmag)));
dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) +
(cosjik*(rij[0]/(rijmag*rijmag)));
dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) +
(cosjik*(rij[1]/(rijmag*rijmag)));
dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) +
(cosjik*(rij[2]/(rijmag*rijmag)));
g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
fj[0] = -tmp2*dcosjikdrj[0];
fj[1] = -tmp2*dcosjikdrj[1];
fj[2] = -tmp2*dcosjikdrj[2];
fi[0] = -tmp2*dcosjikdri[0];
fi[1] = -tmp2*dcosjikdri[1];
fi[2] = -tmp2*dcosjikdri[2];
fk[0] = -tmp2*dcosjikdrk[0];
fk[1] = -tmp2*dcosjikdrk[1];
fk[2] = -tmp2*dcosjikdrk[2];
tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
fj[0] -= tmp2*(-rij[0]/rijmag);
fj[1] -= tmp2*(-rij[1]/rijmag);
fj[2] -= tmp2*(-rij[2]/rijmag);
fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag));
fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag));
fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag));
fk[0] -= tmp2*(rik[0]/rikmag);
fk[1] -= tmp2*(rik[1]/rikmag);
fk[2] -= tmp2*(rik[2]/rikmag);
// coordination forces
// dwik forces
tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
// PIJ forces
tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
// dgdN forces
tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
fi[0] -= tmp2*rik[0];
fi[1] -= tmp2*rik[1];
fi[2] -= tmp2*rik[2];
fk[0] += tmp2*rik[0];
fk[1] += tmp2*rik[1];
fk[2] += tmp2*rik[2];
f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
if (vflag_atom) {
rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
v_tally3(atomi,atomj,atomk,fj,fk,rji,rki);
}
}
}
tmp = tmppji;
tmp3 = tmp3pji;
dN2[0] = dN2PJI[0];
dN2[1] = dN2PJI[1];
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml !=atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
lamdaijl = 4.0*kronecker(jtype,1) *
((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) /
(rijmag*rjlmag);
cosijl = MIN(cosijl,1.0);
cosijl = MAX(cosijl,-1.0);
dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) -
(cosijl*rij[0]/(rijmag*rijmag));
dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) -
(cosijl*rij[1]/(rijmag*rijmag));
dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) -
(cosijl*rij[2]/(rijmag*rijmag));
dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) +
(cosijl*((rij[0]/pow(rijmag,2.0))-(rjl[0]/(rjlmag*rjlmag))));
dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) +
(cosijl*((rij[1]/pow(rijmag,2.0))-(rjl[1]/(rjlmag*rjlmag))));
dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) +
(cosijl*((rij[2]/pow(rijmag,2.0))-(rjl[2]/(rjlmag*rjlmag))));
dcosijldrl[0] = (rij[0]/(rijmag*rjlmag)) +
(cosijl*rjl[0]/(rjlmag*rjlmag));
dcosijldrl[1] = (rij[1]/(rijmag*rjlmag)) +
(cosijl*rjl[1]/(rjlmag*rjlmag));
dcosijldrl[2] = (rij[2]/(rijmag*rjlmag)) +
(cosijl*rjl[2]/(rjlmag*rjlmag));
// evaluate splines g and derivatives dg
g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
fi[0] = -tmp2*dcosijldri[0];
fi[1] = -tmp2*dcosijldri[1];
fi[2] = -tmp2*dcosijldri[2];
fj[0] = -tmp2*dcosijldrj[0];
fj[1] = -tmp2*dcosijldrj[1];
fj[2] = -tmp2*dcosijldrj[2];
fl[0] = -tmp2*dcosijldrl[0];
fl[1] = -tmp2*dcosijldrl[1];
fl[2] = -tmp2*dcosijldrl[2];
tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
fi[0] -= tmp2*(rij[0]/rijmag);
fi[1] -= tmp2*(rij[1]/rijmag);
fi[2] -= tmp2*(rij[2]/rijmag);
fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag));
fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag));
fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag));
fl[0] -= tmp2*(rjl[0]/rjlmag);
fl[1] -= tmp2*(rjl[1]/rjlmag);
fl[2] -= tmp2*(rjl[2]/rjlmag);
// coordination forces
// dwik forces
tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
// PIJ forces
tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
// dgdN forces
tmp2=VA*.5*(tmp*tmp3*dwjl)/rjlmag;
fj[0] -= tmp2*rjl[0];
fj[1] -= tmp2*rjl[1];
fj[2] -= tmp2*rjl[2];
fl[0] += tmp2*rjl[0];
fl[1] += tmp2*rjl[1];
fl[2] += tmp2*rjl[2];
f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
if (vflag_atom) {
rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj);
}
}
}
// piRC forces
dN3[0] = dN3piRC[0];
dN3[1] = dN3piRC[1];
dN3[2] = dN3piRC[2];
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
SpN = Sp(Nki,Nmin,Nmax,dNki);
tmp2 = VA*dN3[0]*dwik/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
if (fabs(dNki) > TOL) {
REBO_neighs_k = REBO_firstneigh[atomk];
for (n = 0; n < REBO_numneigh[atomk]; n++) {
atomn = REBO_neighs_k[n];
if (atomn != atomi) {
ntype = map[type[atomn]];
rkn[0] = x[atomk][0]-x[atomn][0];
rkn[1] = x[atomk][1]-x[atomn][1];
rkn[2] = x[atomk][2]-x[atomn][2];
rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
f[atomk][0] -= tmp2*rkn[0];
f[atomk][1] -= tmp2*rkn[1];
f[atomk][2] -= tmp2*rkn[2];
f[atomn][0] += tmp2*rkn[0];
f[atomn][1] += tmp2*rkn[1];
f[atomn][2] += tmp2*rkn[2];
if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
}
}
}
}
}
// piRC forces to J side
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
SpN = Sp(Nlj,Nmin,Nmax,dNlj);
tmp2 = VA*dN3[1]*dwjl/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
if (fabs(dNlj) > TOL) {
REBO_neighs_l = REBO_firstneigh[atoml];
for (n = 0; n < REBO_numneigh[atoml]; n++) {
atomn = REBO_neighs_l[n];
if (atomn != atomj) {
ntype = map[type[atomn]];
rln[0] = x[atoml][0]-x[atomn][0];
rln[1] = x[atoml][1]-x[atomn][1];
rln[2] = x[atoml][2]-x[atomn][2];
rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
f[atoml][0] -= tmp2*rln[0];
f[atoml][1] -= tmp2*rln[1];
f[atoml][2] -= tmp2*rln[2];
f[atomn][0] += tmp2*rln[0];
f[atomn][1] += tmp2*rln[1];
f[atomn][2] += tmp2*rln[2];
if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
}
}
}
}
}
if (fabs(Tij) > TOL) {
dN3[0] = dN3Tij[0];
dN3[1] = dN3Tij[1];
dN3[2] = dN3Tij[2];
atom2 = atomi;
atom3 = atomj;
r32[0] = x[atom3][0]-x[atom2][0];
r32[1] = x[atom3][1]-x[atom2][1];
r32[2] = x[atom3][2]-x[atom2][2];
r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
r23[0] = -r32[0];
r23[1] = -r32[1];
r23[2] = -r32[2];
r23mag = r32mag;
REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs_i[k];
atom1 = atomk;
ktype = map[type[atomk]];
if (atomk != atomj) {
r21[0] = x[atom2][0]-x[atom1][0];
r21[1] = x[atom2][1]-x[atom1][1];
r21[2] = x[atom2][2]-x[atom1][2];
r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) /
(r21mag*rijmag);
cos321 = MIN(cos321,1.0);
cos321 = MAX(cos321,-1.0);
sin321 = sqrt(1.0 - cos321*cos321);
sink2i = 1.0/(sin321*sin321);
rik2i = 1.0/(r21mag*r21mag);
if (sin321 != 0.0) {
rr = (rijmag*rijmag)-(r21mag*r21mag);
rjk[0] = r21[0]-rij[0];
rjk[1] = r21[1]-rij[1];
rjk[2] = r21[2]-rij[2];
rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
rijrik = 2.0*rijmag*r21mag;
rik2 = r21mag*r21mag;
dctik = (-rr+rjk2)/(rijrik*rik2);
dctij = (rr+rjk2)/(rijrik*rijmag*rijmag);
dctjk = -2.0/rijrik;
w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
rikmag = r21mag;
rij2 = r32mag*r32mag;
rik2 = r21mag*r21mag;
costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
tspjik = Sp2(costmp,thmin,thmax,dtsjik);
dtsjik = -dtsjik;
REBO_neighs_j = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs_j[l];
atom4 = atoml;
ltype = map[type[atoml]];
if (!(atoml == atomi || atoml == atomk)) {
r34[0] = x[atom3][0]-x[atom4][0];
r34[1] = x[atom3][1]-x[atom4][1];
r34[2] = x[atom3][2]-x[atom4][2];
r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]);
cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) +
(rij[2]*r34[2]))/(rijmag*r34mag);
cos234 = MIN(cos234,1.0);
cos234 = MAX(cos234,-1.0);
sin234 = sqrt(1.0 - cos234*cos234);
sinl2i = 1.0/(sin234*sin234);
rjl2i = 1.0/(r34mag*r34mag);
if (sin234 != 0.0) {
w34 = Sp(r34mag,rcmin[jtype][ltype],
rcmaxp[jtype][ltype],dw34);
rr = (r23mag*r23mag)-(r34mag*r34mag);
ril[0] = r23[0]+r34[0];
ril[1] = r23[1]+r34[1];
ril[2] = r23[2]+r34[2];
ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
rijrjl = 2.0*r23mag*r34mag;
rjl2 = r34mag*r34mag;
dctjl = (-rr+ril2)/(rijrjl*rjl2);
dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
dctil = -2.0/rijrjl;
rjlmag = r34mag;
rjl2 = r34mag*r34mag;
costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
tspijl = Sp2(costmp,thmin,thmax,dtsijl);
dtsijl = -dtsijl; //need minus sign
prefactor = VA*Tij;
cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
cwnum = (cross321[0]*cross234[0]) +
(cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
om1234 = cwnum/cwnom;
cw = om1234;
Etmp += ((1.0-pow(om1234,2.0))*w21*w34) *
(1.0-tspjik)*(1.0-tspijl);
dt1dik = (rik2i)-(dctik*sink2i*cos321);
dt1djk = (-dctjk*sink2i*cos321);
dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
dt1dil = (-dctil*sinl2i*cos234);
dt1dij = (2.0/(r23mag*r23mag)) -
(dctij*sink2i*cos321)-(dctji*sinl2i*cos234);
dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
dt2dij[0] = (r21[2]*cross234[1]) -
(r34[2]*cross321[1])-(r21[1]*cross234[2]) +
(r34[1]*cross321[2]);
dt2dij[1] = (r21[0]*cross234[2]) -
(r34[0]*cross321[2])-(r21[2]*cross234[0]) +
(r34[2]*cross321[0]);
dt2dij[2] = (r21[1]*cross234[0]) -
(r34[1]*cross321[0])-(r21[0]*cross234[1]) +
(r34[0]*cross321[1]);
aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
(1.0-tspjik)*(1.0-tspijl);
aaa1 = -prefactor*(1.0-pow(om1234,2.0)) *
(1.0-tspjik)*(1.0-tspijl);
aaa2 = aaa1*w21*w34;
at2 = aa*cwnum;
fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
(aaa2*dtsijl*dctji*(1.0-tspjik));
fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
F31[0] = (fcjkpc*rjk[0]);
F31[1] = (fcjkpc*rjk[1]);
F31[2] = (fcjkpc*rjk[2]);
F24[0] = (fcilpc*ril[0]);
F24[1] = (fcilpc*ril[1]);
F24[2] = (fcilpc*ril[2]);
f1[0] = -F12[0]-F31[0];
f1[1] = -F12[1]-F31[1];
f1[2] = -F12[2]-F31[2];
f2[0] = F23[0]+F12[0]+F24[0];
f2[1] = F23[1]+F12[1]+F24[1];
f2[2] = F23[2]+F12[2]+F24[2];
f3[0] = -F23[0]+F34[0]+F31[0];
f3[1] = -F23[1]+F34[1]+F31[1];
f3[2] = -F23[2]+F34[2]+F31[2];
f4[0] = -F34[0]-F24[0];
f4[1] = -F34[1]-F24[1];
f4[2] = -F34[2]-F24[2];
// coordination forces
tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
(1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
f2[0] -= tmp2*r21[0];
f2[1] -= tmp2*r21[1];
f2[2] -= tmp2*r21[2];
f1[0] += tmp2*r21[0];
f1[1] += tmp2*r21[1];
f1[2] += tmp2*r21[2];
tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
(1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
f3[0] -= tmp2*r34[0];
f3[1] -= tmp2*r34[1];
f3[2] -= tmp2*r34[2];
f4[0] += tmp2*r34[0];
f4[1] += tmp2*r34[1];
f4[2] += tmp2*r34[2];
f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
f[atom1][2] += f1[2];
f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
f[atom2][2] += f2[2];
f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
f[atom3][2] += f3[2];
f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
f[atom4][2] += f4[2];
if (vflag_atom) {
r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43);
}
}
}
}
}
}
}
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
SpN = Sp(Nki,Nmin,Nmax,dNki);
tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
f[atomi][0] -= tmp2*rik[0];
f[atomi][1] -= tmp2*rik[1];
f[atomi][2] -= tmp2*rik[2];
f[atomk][0] += tmp2*rik[0];
f[atomk][1] += tmp2*rik[1];
f[atomk][2] += tmp2*rik[2];
if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
if (fabs(dNki) >TOL) {
REBO_neighs_k = REBO_firstneigh[atomk];
for (n = 0; n < REBO_numneigh[atomk]; n++) {
atomn = REBO_neighs_k[n];
ntype = map[type[atomn]];
if (atomn !=atomi) {
rkn[0] = x[atomk][0]-x[atomn][0];
rkn[1] = x[atomk][1]-x[atomn][1];
rkn[2] = x[atomk][2]-x[atomn][2];
rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
f[atomk][0] -= tmp2*rkn[0];
f[atomk][1] -= tmp2*rkn[1];
f[atomk][2] -= tmp2*rkn[2];
f[atomn][0] += tmp2*rkn[0];
f[atomn][1] += tmp2*rkn[1];
f[atomn][2] += tmp2*rkn[2];
if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
}
}
}
}
}
// Tij forces
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
SpN = Sp(Nlj,Nmin,Nmax,dNlj);
tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
f[atomj][0] -= tmp2*rjl[0];
f[atomj][1] -= tmp2*rjl[1];
f[atomj][2] -= tmp2*rjl[2];
f[atoml][0] += tmp2*rjl[0];
f[atoml][1] += tmp2*rjl[1];
f[atoml][2] += tmp2*rjl[2];
if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
if (fabs(dNlj) > TOL) {
REBO_neighs_l = REBO_firstneigh[atoml];
for (n = 0; n < REBO_numneigh[atoml]; n++) {
atomn = REBO_neighs_l[n];
ntype = map[type[atomn]];
if (atomn != atomj) {
rln[0] = x[atoml][0]-x[atomn][0];
rln[1] = x[atoml][1]-x[atomn][1];
rln[2] = x[atoml][2]-x[atomn][2];
rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
f[atoml][0] -= tmp2*rln[0];
f[atoml][1] -= tmp2*rln[1];
f[atoml][2] -= tmp2*rln[2];
f[atomn][0] += tmp2*rln[0];
f[atomn][1] += tmp2*rln[1];
f[atomn][2] += tmp2*rln[2];
if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
}
}
}
}
}
}
}
return Stb;
}
/* ----------------------------------------------------------------------
G spline
------------------------------------------------------------------------- */
double PairAIREBO::gSpline(double costh, double Nij, int typei,
double *dgdc, double *dgdN)
{
double coeffs[6],dS,g1,g2,dg1,dg2,cut,g;
int i,j;
i = 0;
j = 0;
g = 0.0;
cut = 0.0;
dS = 0.0;
dg1 = 0.0;
dg2 = 0.0;
*dgdc = 0.0;
*dgdN = 0.0;
// central atom is Carbon
if (typei == 0) {
if (costh < gCdom[0]) costh = gCdom[0];
if (costh > gCdom[4]) costh = gCdom[4];
if (Nij >= NCmax) {
for (i = 0; i < 4; i++) {
if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j];
}
}
g2 = Sp5th(costh,coeffs,&dg2);
g = g2;
*dgdc = dg2;
*dgdN = 0.0;
}
if (Nij <= NCmin) {
for (i = 0; i < 4; i++) {
if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j];
}
}
g1 = Sp5th(costh,coeffs,&dg1);
g = g1;
*dgdc = dg1;
*dgdN = 0.0;
}
if (Nij > NCmin && Nij < NCmax) {
for (i = 0; i < 4; i++) {
if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j];
}
}
g1 = Sp5th(costh,coeffs,&dg1);
for (i = 0; i < 4; i++) {
if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j];
}
}
g2 = Sp5th(costh,coeffs,&dg2);
cut = Sp(Nij,NCmin,NCmax,dS);
g = g2+cut*(g1-g2);
*dgdc = dg2+(cut*(dg1-dg2));
*dgdN = dS*(g1-g2);
}
}
// central atom is Hydrogen
if (typei == 1) {
if (costh < gHdom[0]) costh = gHdom[0];
if (costh > gHdom[3]) costh = gHdom[3];
for (i = 0; i < 3; i++) {
if (costh >= gHdom[i] && costh <= gHdom[i+1]) {
for (j = 0; j < 6; j++) coeffs[j] = gH[i][j];
}
}
g = Sp5th(costh,coeffs,&dg1);
*dgdN = 0.0;
*dgdc = dg1;
}
return g;
}
/* ----------------------------------------------------------------------
Pij spline
------------------------------------------------------------------------- */
double PairAIREBO::PijSpline(double NijC, double NijH, int typei, int typej,
double dN2[2])
{
int x,y,i,done;
double Pij,coeffs[16];
for (i = 0; i < 16; i++) coeffs[i]=0.0;
x = 0;
y = 0;
dN2[0] = 0.0;
dN2[1] = 0.0;
done = 0;
// if inputs are out of bounds set them back to a point in bounds
if (typei == 0 && typej == 0) {
if (NijC < pCCdom[0][0]) NijC=pCCdom[0][0];
if (NijC > pCCdom[0][1]) NijC=pCCdom[0][1];
if (NijH < pCCdom[1][0]) NijH=pCCdom[1][0];
if (NijH > pCCdom[1][1]) NijH=pCCdom[1][1];
if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) {
Pij = PCCf[(int) NijC][(int) NijH];
dN2[0] = PCCdfdx[(int) NijC][(int) NijH];
dN2[1] = PCCdfdy[(int) NijC][(int) NijH];
done = 1;
}
if (done == 0) {
x = (int) (floor(NijC));
y = (int) (floor(NijH));
for (i = 0; i<16; i++) coeffs[i] = pCC[x][y][i];
Pij = Spbicubic(NijC,NijH,coeffs,dN2);
}
}
// if inputs are out of bounds set them back to a point in bounds
if (typei == 0 && typej == 1){
if (NijC < pCHdom[0][0]) NijC=pCHdom[0][0];
if (NijC > pCHdom[0][1]) NijC=pCHdom[0][1];
if (NijH < pCHdom[1][0]) NijH=pCHdom[1][0];
if (NijH > pCHdom[1][1]) NijH=pCHdom[1][1];
if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) {
Pij = PCHf[(int) NijC][(int) NijH];
dN2[0] = PCHdfdx[(int) NijC][(int) NijH];
dN2[1] = PCHdfdy[(int) NijC][(int) NijH];
done = 1;
}
if (done == 0) {
x = (int) (floor(NijC));
y = (int) (floor(NijH));
for (i = 0; i<16; i++) coeffs[i] = pCH[x][y][i];
Pij = Spbicubic(NijC,NijH,coeffs,dN2);
}
}
if (typei == 1 && typej == 0) {
Pij = 0.0;
dN2[0] = 0.0;
dN2[1] = 0.0;
}
if (typei == 1 && typej == 1) {
Pij = 0.0;
dN2[0] = 0.0;
dN2[1] = 0.0;
}
return Pij;
}
/* ----------------------------------------------------------------------
PiRC spline
------------------------------------------------------------------------- */
double PairAIREBO::piRCSpline(double Nij, double Nji, double Nijconj,
int typei, int typej, double dN3[3])
{
int x,y,z,i,done;
double piRC,coeffs[64];
x=0;
y=0;
z=0;
i=0;
done=0;
for (i=0; i<64; i++) coeffs[i]=0.0;
if (typei==0 && typej==0) {
//if the inputs are out of bounds set them back to a point in bounds
if (Nij<piCCdom[0][0]) Nij=piCCdom[0][0];
if (Nij>piCCdom[0][1]) Nij=piCCdom[0][1];
if (Nji<piCCdom[1][0]) Nji=piCCdom[1][0];
if (Nji>piCCdom[1][1]) Nji=piCCdom[1][1];
if (Nijconj<piCCdom[2][0]) Nijconj=piCCdom[2][0];
if (Nijconj>piCCdom[2][1]) Nijconj=piCCdom[2][1];
if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
fabs(Nijconj-floor(Nijconj))<TOL) {
piRC=piCCf[(int) Nij][(int) Nji][(int) Nijconj];
dN3[0]=piCCdfdx[(int) Nij][(int) Nji][(int) Nijconj];
dN3[1]=piCCdfdy[(int) Nij][(int) Nji][(int) Nijconj];
dN3[2]=piCCdfdz[(int) Nij][(int) Nji][(int) Nijconj];
done=1;
}
if (done==0) {
for (i=0; i<piCCdom[0][1]; i++)
if (Nij>=(double) i && Nij<=(double) i+1 || Nij==(double) i) x=i;
for (i=0; i<piCCdom[1][1]; i++)
if (Nji>=(double) i && Nji<=(double) i+1 || Nji==(double) i) y=i;
for (i=0; i<piCCdom[2][1]; i++)
if (Nijconj>=(double) i && Nijconj<=(double) i+1 ||
Nijconj==(double) i) z=i;
for (i=0; i<64; i++) coeffs[i]=piCC[x][y][z][i];
piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
}
}
// CH interaction
if (typei==0 && typej==1 || typei==1 && typej==0) {
// if the inputs are out of bounds set them back to a point in bounds
if (Nij<piCHdom[0][0] || Nij>piCHdom[0][1] ||
Nji<piCHdom[1][0] || Nji>piCHdom[1][1] ||
Nijconj<piCHdom[2][0] || Nijconj>piCHdom[2][1]) {
if (Nij<piCHdom[0][0]) Nij=piCHdom[0][0];
if (Nij>piCHdom[0][1]) Nij=piCHdom[0][1];
if (Nji<piCHdom[1][0]) Nji=piCHdom[1][0];
if (Nji>piCHdom[1][1]) Nji=piCHdom[1][1];
if (Nijconj<piCHdom[2][0]) Nijconj=piCHdom[2][0];
if (Nijconj>piCHdom[2][1]) Nijconj=piCHdom[2][1];
}
if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
fabs(Nijconj-floor(Nijconj))<TOL) {
piRC=piCHf[(int) Nij][(int) Nji][(int) Nijconj];
dN3[0]=piCHdfdx[(int) Nij][(int) Nji][(int) Nijconj];
dN3[1]=piCHdfdy[(int) Nij][(int) Nji][(int) Nijconj];
dN3[2]=piCHdfdz[(int) Nij][(int) Nji][(int) Nijconj];
done=1;
}
if (done==0) {
for (i=0; i<piCHdom[0][1]; i++)
if (Nij>=i && Nij<=i+1) x=i;
for (i=0; i<piCHdom[1][1]; i++)
if (Nji>=i && Nji<=i+1) y=i;
for (i=0; i<piCHdom[2][1]; i++)
if (Nijconj>=i && Nijconj<=i+1) z=i;
for (i=0; i<64; i++) coeffs[i]=piCH[x][y][z][i];
piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
}
}
if (typei==1 && typej==1) {
if (Nij<piHHdom[0][0] || Nij>piHHdom[0][1] ||
Nji<piHHdom[1][0] || Nji>piHHdom[1][1] ||
Nijconj<piHHdom[2][0] || Nijconj>piHHdom[2][1]) {
Nij=0.0;
Nji=0.0;
Nijconj=0.0;
}
if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
fabs(Nijconj-floor(Nijconj))<TOL) {
piRC=piHHf[(int) Nij][(int) Nji][(int) Nijconj];
dN3[0]=piHHdfdx[(int) Nij][(int) Nji][(int) Nijconj];
dN3[1]=piHHdfdy[(int) Nij][(int) Nji][(int) Nijconj];
dN3[2]=piHHdfdz[(int) Nij][(int) Nji][(int) Nijconj];
done=1;
}
if (done==0) {
for (i=0; i<piHHdom[0][1]; i++)
if (Nij>=i && Nij<=i+1) x=i;
for (i=0; i<piHHdom[1][1]; i++)
if (Nji>=i && Nji<=i+1) y=i;
for (i=0; i<piHHdom[2][1]; i++)
if (Nijconj>=i && Nijconj<=i+1) z=i;
for (i=0; i<64; i++) coeffs[i]=piHH[x][y][z][i];
piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
}
}
return piRC;
}
/* ----------------------------------------------------------------------
Tij spline
------------------------------------------------------------------------- */
double PairAIREBO::TijSpline(double Nij, double Nji,
double Nijconj, double dN3[3])
{
int x,y,z,i,done;
double Tijf,coeffs[64];
x=0;
y=0;
z=0;
i=0;
Tijf=0.0;
done=0;
for (i=0; i<64; i++) coeffs[i]=0.0;
//if the inputs are out of bounds set them back to a point in bounds
if (Nij<Tijdom[0][0]) Nij=Tijdom[0][0];
if (Nij>Tijdom[0][1]) Nij=Tijdom[0][1];
if (Nji<Tijdom[1][0]) Nji=Tijdom[1][0];
if (Nji>Tijdom[1][1]) Nji=Tijdom[1][1];
if (Nijconj<Tijdom[2][0]) Nijconj=Tijdom[2][0];
if (Nijconj>Tijdom[2][1]) Nijconj=Tijdom[2][1];
if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
fabs(Nijconj-floor(Nijconj))<TOL) {
Tijf=Tf[(int) Nij][(int) Nji][(int) Nijconj];
dN3[0]=Tdfdx[(int) Nij][(int) Nji][(int) Nijconj];
dN3[1]=Tdfdy[(int) Nij][(int) Nji][(int) Nijconj];
dN3[2]=Tdfdz[(int) Nij][(int) Nji][(int) Nijconj];
done=1;
}
if (done==0) {
for (i=0; i<Tijdom[0][1]; i++)
if (Nij>=i && Nij<=i+1) x=i;
for (i=0; i<Tijdom[1][1]; i++)
if (Nji>=i && Nji<=i+1) y=i;
for (i=0; i<Tijdom[2][1]; i++)
if (Nijconj>=i && Nijconj<=i+1) z=i;
for (i=0; i<64; i++) coeffs[i]=Tijc[x][y][z][i];
Tijf=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
}
return Tijf;
}
/* ----------------------------------------------------------------------
add pages to REBO neighbor list
------------------------------------------------------------------------- */
-void PairAIREBO::add_pages()
+void PairAIREBO::add_pages(int howmany)
{
int toppage = maxpage;
- maxpage += PGDELTA;
+ maxpage += howmany*PGDELTA;
pages = (int **)
memory->srealloc(pages,maxpage*sizeof(int *),"AIREBO:pages");
for (int i = toppage; i < maxpage; i++)
memory->create(pages[i],pgsize,"AIREBO:pages[i]");
}
/* ----------------------------------------------------------------------
read AIREBO potential file
------------------------------------------------------------------------- */
void PairAIREBO::read_file(char *filename)
{
int i,j,k,l,limit;
char s[MAXLINE];
// REBO Parameters (AIREBO)
double rcmin_CC,rcmin_CH,rcmin_HH,rcmax_CC,rcmax_CH,
rcmax_HH,rcmaxp_CC,rcmaxp_CH,rcmaxp_HH;
double Q_CC,Q_CH,Q_HH,alpha_CC,alpha_CH,alpha_HH,A_CC,A_CH,A_HH;
double BIJc_CC1,BIJc_CC2,BIJc_CC3,BIJc_CH1,BIJc_CH2,BIJc_CH3,
BIJc_HH1,BIJc_HH2,BIJc_HH3;
double Beta_CC1,Beta_CC2,Beta_CC3,Beta_CH1,Beta_CH2,Beta_CH3,
Beta_HH1,Beta_HH2,Beta_HH3;
double rho_CC,rho_CH,rho_HH;
// LJ Parameters (AIREBO)
double rcLJmin_CC,rcLJmin_CH,rcLJmin_HH,rcLJmax_CC,rcLJmax_CH,
rcLJmax_HH,bLJmin_CC;
double bLJmin_CH,bLJmin_HH,bLJmax_CC,bLJmax_CH,bLJmax_HH,
epsilon_CC,epsilon_CH,epsilon_HH;
double sigma_CC,sigma_CH,sigma_HH,epsilonT_CCCC,epsilonT_CCCH,epsilonT_HCCH;
MPI_Comm_rank(world,&me);
// read file on proc 0
if (me == 0) {
FILE *fp = fopen(filename,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open AIREBO potential file %s",filename);
error->one(FLERR,str);
}
// skip initial comment lines
while (1) {
fgets(s,MAXLINE,fp);
if (s[0] != '#') break;
}
// read parameters
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmin_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmin_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmin_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmax_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmax_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmax_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmaxp_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmaxp_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcmaxp_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&smin);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Nmin);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Nmax);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&NCmin);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&NCmax);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Q_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Q_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Q_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&alpha_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&alpha_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&alpha_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&A_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&A_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&A_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CC1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CC2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CC3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CH1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CH2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_CH3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_HH1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_HH2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&BIJc_HH3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CC1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CC2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CC3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CH1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CH2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_CH3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_HH1);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_HH2);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Beta_HH3);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rho_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rho_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rho_HH);
// LJ parameters
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmin_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmin_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmin_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmax_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmax_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&rcLJmax_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmin_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmin_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmin_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmax_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmax_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&bLJmax_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilon_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilon_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilon_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&sigma_CC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&sigma_CH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&sigma_HH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilonT_CCCC);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilonT_CCCH);
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&epsilonT_HCCH);
// gC spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
// number-1 = # of domains for the spline
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit; i++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&gCdom[i]);
}
fgets(s,MAXLINE,fp);
for (i = 0; i < limit-1; i++) {
for (j = 0; j < 6; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&gC1[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < limit-1; i++) {
for (j = 0; j < 6; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&gC2[i][j]);
}
}
// gH spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit; i++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&gHdom[i]);
}
fgets(s,MAXLINE,fp);
for (i = 0; i < limit-1; i++) {
for (j = 0; j < 6; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&gH[i][j]);
}
}
// pCC spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/2; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&pCCdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) pCCdom[0][1]; i++) {
for (j = 0; j < (int) pCCdom[1][1]; j++) {
for (k = 0; k < 16; k++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&pCC[i][j][k]);
}
}
}
// pCH spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/2; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&pCHdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) pCHdom[0][1]; i++) {
for (j = 0; j < (int) pCHdom[1][1]; j++) {
for (k = 0; k < 16; k++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&pCH[i][j][k]);
}
}
}
// piCC cpline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/3; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piCCdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) piCCdom[0][1]; i++) {
for (j = 0; j < (int) piCCdom[1][1]; j++) {
for (k = 0; k < (int) piCCdom[2][1]; k++) {
for (l = 0; l < 64; l = l+1) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piCC[i][j][k][l]);
}
}
}
}
// piCH spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/3; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piCHdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) piCHdom[0][1]; i++) {
for (j = 0; j < (int) piCHdom[1][1]; j++) {
for (k = 0; k < (int) piCHdom[2][1]; k++) {
for (l = 0; l < 64; l = l+1) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piCH[i][j][k][l]);
}
}
}
}
// piHH spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/3; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piHHdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) piHHdom[0][1]; i++) {
for (j = 0; j < (int) piHHdom[1][1]; j++) {
for (k = 0; k < (int) piHHdom[2][1]; k++) {
for (l = 0; l < 64; l = l+1) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&piHH[i][j][k][l]);
}
}
}
}
// Tij spline
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
fgets(s,MAXLINE,fp);
sscanf(s,"%d",&limit);
for (i = 0; i < limit/2; i++) {
for (j = 0; j < limit/3; j++) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Tijdom[i][j]);
}
}
fgets(s,MAXLINE,fp);
for (i = 0; i < (int) Tijdom[0][1]; i++) {
for (j = 0; j < (int) Tijdom[1][1]; j++) {
for (k = 0; k < (int) Tijdom[2][1]; k++) {
for (l = 0; l < 64; l = l+1) {
fgets(s,MAXLINE,fp);
sscanf(s,"%lg",&Tijc[i][j][k][l]);
}
}
}
}
fclose(fp);
}
// store read-in values in arrays
if (me == 0) {
// REBO
rcmin[0][0] = rcmin_CC;
rcmin[0][1] = rcmin_CH;
rcmin[1][0] = rcmin[0][1];
rcmin[1][1] = rcmin_HH;
rcmax[0][0] = rcmax_CC;
rcmax[0][1] = rcmax_CH;
rcmax[1][0] = rcmax[0][1];
rcmax[1][1] = rcmax_HH;
rcmaxsq[0][0] = rcmax[0][0]*rcmax[0][0];
rcmaxsq[1][0] = rcmax[1][0]*rcmax[1][0];
rcmaxsq[0][1] = rcmax[0][1]*rcmax[0][1];
rcmaxsq[1][1] = rcmax[1][1]*rcmax[1][1];
rcmaxp[0][0] = rcmaxp_CC;
rcmaxp[0][1] = rcmaxp_CH;
rcmaxp[1][0] = rcmaxp[0][1];
rcmaxp[1][1] = rcmaxp_HH;
Q[0][0] = Q_CC;
Q[0][1] = Q_CH;
Q[1][0] = Q[0][1];
Q[1][1] = Q_HH;
alpha[0][0] = alpha_CC;
alpha[0][1] = alpha_CH;
alpha[1][0] = alpha[0][1];
alpha[1][1] = alpha_HH;
A[0][0] = A_CC;
A[0][1] = A_CH;
A[1][0] = A[0][1];
A[1][1] = A_HH;
rho[0][0] = rho_CC;
rho[0][1] = rho_CH;
rho[1][0] = rho[0][1];
rho[1][1] = rho_HH;
BIJc[0][0][0] = BIJc_CC1;
BIJc[0][0][1] = BIJc_CC2;
BIJc[0][0][2] = BIJc_CC3;
BIJc[0][1][0] = BIJc_CH1;
BIJc[0][1][1] = BIJc_CH2;
BIJc[0][1][2] = BIJc_CH3;
BIJc[1][0][0] = BIJc_CH1;
BIJc[1][0][1] = BIJc_CH2;
BIJc[1][0][2] = BIJc_CH3;
BIJc[1][1][0] = BIJc_HH1;
BIJc[1][1][1] = BIJc_HH2;
BIJc[1][1][2] = BIJc_HH3;
Beta[0][0][0] = Beta_CC1;
Beta[0][0][1] = Beta_CC2;
Beta[0][0][2] = Beta_CC3;
Beta[0][1][0] = Beta_CH1;
Beta[0][1][1] = Beta_CH2;
Beta[0][1][2] = Beta_CH3;
Beta[1][0][0] = Beta_CH1;
Beta[1][0][1] = Beta_CH2;
Beta[1][0][2] = Beta_CH3;
Beta[1][1][0] = Beta_HH1;
Beta[1][1][1] = Beta_HH2;
Beta[1][1][2] = Beta_HH3;
// LJ
rcLJmin[0][0] = rcLJmin_CC;
rcLJmin[0][1] = rcLJmin_CH;
rcLJmin[1][0] = rcLJmin[0][1];
rcLJmin[1][1] = rcLJmin_HH;
rcLJmax[0][0] = rcLJmax_CC;
rcLJmax[0][1] = rcLJmax_CH;
rcLJmax[1][0] = rcLJmax[0][1];
rcLJmax[1][1] = rcLJmax_HH;
rcLJmaxsq[0][0] = rcLJmax[0][0]*rcLJmax[0][0];
rcLJmaxsq[1][0] = rcLJmax[1][0]*rcLJmax[1][0];
rcLJmaxsq[0][1] = rcLJmax[0][1]*rcLJmax[0][1];
rcLJmaxsq[1][1] = rcLJmax[1][1]*rcLJmax[1][1];
bLJmin[0][0] = bLJmin_CC;
bLJmin[0][1] = bLJmin_CH;
bLJmin[1][0] = bLJmin[0][1];
bLJmin[1][1] = bLJmin_HH;
bLJmax[0][0] = bLJmax_CC;
bLJmax[0][1] = bLJmax_CH;
bLJmax[1][0] = bLJmax[0][1];
bLJmax[1][1] = bLJmax_HH;
epsilon[0][0] = epsilon_CC;
epsilon[0][1] = epsilon_CH;
epsilon[1][0] = epsilon[0][1];
epsilon[1][1] = epsilon_HH;
sigma[0][0] = sigma_CC;
sigma[0][1] = sigma_CH;
sigma[1][0] = sigma[0][1];
sigma[1][1] = sigma_HH;
// torsional
thmin = -1.0;
thmax = -0.995;
epsilonT[0][0] = epsilonT_CCCC;
epsilonT[0][1] = epsilonT_CCCH;
epsilonT[1][0] = epsilonT[0][1];
epsilonT[1][1] = epsilonT_HCCH;
}
// broadcast read-in and setup values
MPI_Bcast(&thmin,1,MPI_DOUBLE,0,world);
MPI_Bcast(&thmax,1,MPI_DOUBLE,0,world);
MPI_Bcast(&smin,1,MPI_DOUBLE,0,world);
MPI_Bcast(&Nmin,1,MPI_DOUBLE,0,world);
MPI_Bcast(&Nmax,1,MPI_DOUBLE,0,world);
MPI_Bcast(&NCmin,1,MPI_DOUBLE,0,world);
MPI_Bcast(&NCmax,1,MPI_DOUBLE,0,world);
MPI_Bcast(&rcmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcmax[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcmaxsq[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcmaxp[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&Q[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&alpha[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&A[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rho[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&BIJc[0][0][0],12,MPI_DOUBLE,0,world);
MPI_Bcast(&Beta[0][0][0],12,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmaxsq[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&bLJmin[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&bLJmax[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&epsilon[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&sigma[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&epsilonT[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&gCdom[0],5,MPI_DOUBLE,0,world);
MPI_Bcast(&gC1[0][0],24,MPI_DOUBLE,0,world);
MPI_Bcast(&gC2[0][0],24,MPI_DOUBLE,0,world);
MPI_Bcast(&gHdom[0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&gH[0][0],18,MPI_DOUBLE,0,world);
MPI_Bcast(&pCCdom[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&pCHdom[0][0],4,MPI_DOUBLE,0,world);
MPI_Bcast(&pCC[0][0][0],256,MPI_DOUBLE,0,world);
MPI_Bcast(&pCH[0][0][0],256,MPI_DOUBLE,0,world);
MPI_Bcast(&piCCdom[0][0],6,MPI_DOUBLE,0,world);
MPI_Bcast(&piCHdom[0][0],6,MPI_DOUBLE,0,world);
MPI_Bcast(&piHHdom[0][0],6,MPI_DOUBLE,0,world);
MPI_Bcast(&piCC[0][0][0][0],9216,MPI_DOUBLE,0,world);
MPI_Bcast(&piCH[0][0][0][0],9216,MPI_DOUBLE,0,world);
MPI_Bcast(&piHH[0][0][0][0],9216,MPI_DOUBLE,0,world);
MPI_Bcast(&Tijdom[0][0],6,MPI_DOUBLE,0,world);
MPI_Bcast(&Tijc[0][0][0][0],9216,MPI_DOUBLE,0,world);
}
// ----------------------------------------------------------------------
// generic Spline functions
// ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
fifth order spline evaluation
------------------------------------------------------------------------- */
double PairAIREBO::Sp5th(double x, double coeffs[6], double *df)
{
double f, d;
const double x2 = x*x;
const double x3 = x2*x;
f = coeffs[0];
f += coeffs[1]*x;
d = coeffs[1];
f += coeffs[2]*x2;
d += 2.0*coeffs[2]*x;
f += coeffs[3]*x3;
d += 3.0*coeffs[3]*x2;
f += coeffs[4]*x2*x2;
d += 4.0*coeffs[4]*x3;
f += coeffs[5]*x2*x3;
d += 5.0*coeffs[5]*x2*x2;
*df = d;
return f;
}
/* ----------------------------------------------------------------------
bicubic spline evaluation
------------------------------------------------------------------------- */
double PairAIREBO::Spbicubic(double x, double y,
double coeffs[16], double df[2])
{
double f,xn,yn,xn1,yn1,c;
int i,j;
f = 0.0;
df[0] = 0.0;
df[1] = 0.0;
xn = 1.0;
for (i = 0; i < 4; i++) {
yn = 1.0;
for (j = 0; j < 4; j++) {
c = coeffs[i*4+j];
f += c*xn*yn;
if (i > 0) df[0] += c * ((double) i) * xn1 * yn;
if (j > 0) df[1] += c * ((double) j) * xn * yn1;
yn1 = yn;
yn *= y;
}
xn1 = xn;
xn *= x;
}
return f;
}
/* ----------------------------------------------------------------------
tricubic spline evaluation
------------------------------------------------------------------------- */
double PairAIREBO::Sptricubic(double x, double y, double z,
double coeffs[64], double df[3])
{
double f,ir,jr,kr,xn,yn,zn,xn1,yn1,zn1,c;
int i,j,k;
f = 0.0;
df[0] = 0.0;
df[1] = 0.0;
df[2] = 0.0;
xn = 1.0;
for (i = 0; i < 4; i++) {
ir = (double) i;
yn = 1.0;
for (j = 0; j < 4; j++) {
jr = (double) j;
zn = 1.0;
for (k = 0; k < 4; k++) {
kr = (double) k;
c = coeffs[16*i+4*j+k];
f += c*xn*yn*zn;
if (i > 0) df[0] += c * ir * xn1 * yn * zn;
if (j > 0) df[1] += c * jr * xn * yn1 * zn;
if (k > 0) df[2] += c * kr * xn * yn * zn1;
zn1 = zn;
zn *= z;
}
yn1 = yn;
yn *= y;
}
xn1 = xn;
xn *= x;
}
return f;
}
/* ----------------------------------------------------------------------
initialize spline knot values
------------------------------------------------------------------------- */
void PairAIREBO::spline_init()
{
int i,j,k;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
PCCf[i][j] = 0.0;
PCCdfdx[i][j] = 0.0;
PCCdfdy[i][j] = 0.0;
PCHf[i][j] = 0.0;
PCHdfdx[i][j] = 0.0;
PCHdfdy[i][j] = 0.0;
}
}
PCCf[0][2] = -0.00050;
PCCf[0][3] = 0.0161253646;
PCCf[1][1] = -0.010960;
PCCf[1][2] = 0.00632624824;
PCCf[2][0] = -0.0276030;
PCCf[2][1] = 0.00317953083;
PCHf[0][1] = 0.209336733;
PCHf[0][2] = -0.0644496154;
PCHf[0][3] = -0.303927546;
PCHf[1][0] = 0.010;
PCHf[1][1] = -0.125123401;
PCHf[1][2] = -0.298905246;
PCHf[2][0] = -0.122042146;
PCHf[2][1] = -0.300529172;
PCHf[3][0] = -0.307584705;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
for (k = 0; k < 10; k++) {
piCCf[i][j][k] = 0.0;
piCCdfdx[i][j][k] = 0.0;
piCCdfdy[i][j][k] = 0.0;
piCCdfdz[i][j][k] = 0.0;
piCHf[i][j][k] = 0.0;
piCHdfdx[i][j][k] = 0.0;
piCHdfdy[i][j][k] = 0.0;
piCHdfdz[i][j][k] = 0.0;
piHHf[i][j][k] = 0.0;
piHHdfdx[i][j][k] = 0.0;
piHHdfdy[i][j][k] = 0.0;
piHHdfdz[i][j][k] = 0.0;
Tf[i][j][k] = 0.0;
Tdfdx[i][j][k] = 0.0;
Tdfdy[i][j][k] = 0.0;
Tdfdz[i][j][k] = 0.0;
}
}
}
for (i = 3; i < 10; i++) piCCf[0][0][i] = 0.0049586079;
piCCf[1][0][1] = 0.021693495;
piCCf[0][1][1] = 0.021693495;
for (i = 2; i < 10; i++) piCCf[1][0][i] = 0.0049586079;
for (i = 2; i < 10; i++) piCCf[0][1][i] = 0.0049586079;
piCCf[1][1][1] = 0.05250;
piCCf[1][1][2] = -0.002088750;
for (i = 3; i < 10; i++) piCCf[1][1][i] = -0.00804280;
piCCf[2][0][1] = 0.024698831850;
piCCf[0][2][1] = 0.024698831850;
piCCf[2][0][2] = -0.00597133450;
piCCf[0][2][2] = -0.00597133450;
for (i = 3; i < 10; i++) piCCf[2][0][i] = 0.0049586079;
for (i = 3; i < 10; i++) piCCf[0][2][i] = 0.0049586079;
piCCf[2][1][1] = 0.00482478490;
piCCf[1][2][1] = 0.00482478490;
piCCf[2][1][2] = 0.0150;
piCCf[1][2][2] = 0.0150;
piCCf[2][1][3] = -0.010;
piCCf[1][2][3] = -0.010;
piCCf[2][1][4] = -0.01168893870;
piCCf[1][2][4] = -0.01168893870;
piCCf[2][1][5] = -0.013377877400;
piCCf[1][2][5] = -0.013377877400;
piCCf[2][1][6] = -0.015066816000;
piCCf[1][2][6] = -0.015066816000;
for (i = 7; i < 10; i++) piCCf[2][1][i] = -0.015066816000;
for (i = 7; i < 10; i++) piCCf[1][2][i] = -0.015066816000;
piCCf[2][2][1] = 0.0472247850;
piCCf[2][2][2] = 0.0110;
piCCf[2][2][3] = 0.0198529350;
piCCf[2][2][4] = 0.01654411250;
piCCf[2][2][5] = 0.013235290;
piCCf[2][2][6] = 0.00992646749999 ;
piCCf[2][2][7] = 0.006617644999;
piCCf[2][2][8] = 0.00330882250;
piCCf[3][0][1] = -0.05989946750;
piCCf[0][3][1] = -0.05989946750;
piCCf[3][0][2] = -0.05989946750;
piCCf[0][3][2] = -0.05989946750;
for (i = 3; i < 10; i++) piCCf[3][0][i] = 0.0049586079;
for (i = 3; i < 10; i++) piCCf[0][3][i] = 0.0049586079;
piCCf[3][1][2] = -0.0624183760;
piCCf[1][3][2] = -0.0624183760;
for (i = 3; i < 10; i++) piCCf[3][1][i] = -0.0624183760;
for (i = 3; i < 10; i++) piCCf[1][3][i] = -0.0624183760;
piCCf[3][2][1] = -0.02235469150;
piCCf[2][3][1] = -0.02235469150;
for (i = 2; i < 10; i++) piCCf[3][2][i] = -0.02235469150;
for (i = 2; i < 10; i++) piCCf[2][3][i] = -0.02235469150;
piCCdfdx[2][1][1] = -0.026250;
piCCdfdx[2][1][5] = -0.0271880;
piCCdfdx[2][1][6] = -0.0271880;
for (i = 7; i < 10; i++) piCCdfdx[2][1][i] = -0.0271880;
piCCdfdx[1][3][2] = 0.0187723882;
for (i = 2; i < 10; i++) piCCdfdx[2][3][i] = 0.031209;
piCCdfdy[1][2][1] = -0.026250;
piCCdfdy[1][2][5] = -0.0271880;
piCCdfdy[1][2][6] = -0.0271880;
for (i = 7; i < 10; i++) piCCdfdy[1][2][i] = -0.0271880;
piCCdfdy[3][1][2] = 0.0187723882;
for (i = 2; i < 10; i++) piCCdfdy[3][2][i] = 0.031209;
piCCdfdz[1][1][2] = -0.0302715;
piCCdfdz[2][1][4] = -0.0100220;
piCCdfdz[1][2][4] = -0.0100220;
piCCdfdz[2][1][5] = -0.0100220;
piCCdfdz[1][2][5] = -0.0100220;
for (i = 4; i < 9; i++) piCCdfdz[2][2][i] = -0.0033090;
// make top end of piCC flat instead of zero
i = 4;
for (j = 0; j < 4; j++){
for (k = 1; k < 11; k++){
piCCf[i][j][k] = piCCf[i-1][j][k];
}
}
for (i = 0; i < 4; i++){ // also enforces some symmetry
for (j = i+1; j < 5; j++){
for (k = 1; k < 11; k++){
piCCf[i][j][k] = piCCf[j][i][k];
}
}
}
for (k = 1; k < 11; k++) piCCf[4][4][k] = piCCf[3][4][k];
k = 10;
for (i = 0; i < 5; i++){
for (j = 0; j < 5; j++){
piCCf[i][j][k] = piCCf[i][j][k-1];
}
}
piCHf[1][1][1] = -0.050;
piCHf[1][1][2] = -0.050;
piCHf[1][1][3] = -0.30;
for (i = 4; i < 10; i++) piCHf[1][1][i] = -0.050;
for (i = 5; i < 10; i++) piCHf[2][0][i] = -0.004523893758064;
for (i = 5; i < 10; i++) piCHf[0][2][i] = -0.004523893758064;
piCHf[2][1][2] = -0.250;
piCHf[1][2][2] = -0.250;
piCHf[2][1][3] = -0.250;
piCHf[1][2][3] = -0.250;
piCHf[3][1][1] = -0.10;
piCHf[1][3][1] = -0.10;
piCHf[3][1][2] = -0.125;
piCHf[1][3][2] = -0.125;
piCHf[3][1][3] = -0.125;
piCHf[1][3][3] = -0.125;
for (i = 4; i < 10; i++) piCHf[3][1][i] = -0.10;
for (i = 4; i < 10; i++) piCHf[1][3][i] = -0.10;
// make top end of piCH flat instead of zero
// also enforces some symmetry
i = 4;
for (j = 0; j < 4; j++){
for (k = 1; k < 11; k++){
piCHf[i][j][k] = piCHf[i-1][j][k];
}
}
for (i = 0; i < 4; i++){
for (j = i+1; j < 5; j++){
for (k = 1; k < 11; k++){
piCHf[i][j][k] = piCHf[j][i][k];
}
}
}
for (k = 1; k < 11; k++) piCHf[4][4][k] = piCHf[3][4][k];
k = 10;
for (i = 0; i < 5; i++){
for (j = 0; j < 5; j++){
piCHf[i][j][k] = piCHf[i][j][k-1];
}
}
piHHf[1][1][1] = 0.124915958;
Tf[2][2][1] = -0.035140;
for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480;
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double PairAIREBO::memory_usage()
{
double bytes = 0.0;
bytes += maxlocal * sizeof(int);
bytes += maxlocal * sizeof(int *);
bytes += maxpage * neighbor->pgsize * sizeof(int);
bytes += 3 * maxlocal * sizeof(double);
return bytes;
}
diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h
index 0c4795ab0..2f78fc451 100644
--- a/src/MANYBODY/pair_airebo.h
+++ b/src/MANYBODY/pair_airebo.h
@@ -1,175 +1,176 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(airebo,PairAIREBO)
#else
#ifndef LMP_PAIR_AIREBO_H
#define LMP_PAIR_AIREBO_H
#include "pair.h"
#include "math.h"
#include "math_const.h"
namespace LAMMPS_NS {
class PairAIREBO : public Pair {
public:
PairAIREBO(class LAMMPS *);
virtual ~PairAIREBO();
virtual void compute(int, int);
virtual void settings(int, char **);
void coeff(int, char **);
void init_style();
double init_one(int, int);
double memory_usage();
protected:
int **pages; // neighbor list pages
int *map; // 0 (C), 1 (H), or -1 (NULL) for each type
int me;
int ljflag,torflag; // 0/1 if LJ,torsion terms included
int maxlocal; // size of numneigh, firstneigh arrays
int maxpage; // # of pages currently allocated
int pgsize; // size of neighbor page
int oneatom; // max # of neighbors for one atom
double cutlj; // user-specified LJ cutoff
double cutljrebosq; // cut for when to compute
// REBO neighs of ghost atoms
double **cutljsq; // LJ cutoffs for C,H types
double **lj1,**lj2,**lj3,**lj4; // pre-computed LJ coeffs for C,H types
double cut3rebo; // maximum distance for 3rd REBO neigh
int *REBO_numneigh; // # of pair neighbors for each atom
int **REBO_firstneigh; // ptr to 1st neighbor of each atom
double *closestdistsq; // closest owned atom dist to each ghost
double *nC,*nH; // sum of weighting fns with REBO neighs
double smin,Nmin,Nmax,NCmin,NCmax,thmin,thmax;
double rcmin[2][2],rcmax[2][2],rcmaxsq[2][2],rcmaxp[2][2];
double Q[2][2],alpha[2][2],A[2][2],rho[2][2],BIJc[2][2][3],Beta[2][2][3];
double rcLJmin[2][2],rcLJmax[2][2],rcLJmaxsq[2][2],bLJmin[2][2],bLJmax[2][2];
double epsilon[2][2],sigma[2][2],epsilonT[2][2];
// spline coefficients
double gCdom[5],gC1[4][6],gC2[4][6],gHdom[4],gH[3][6];
double pCCdom[2][2],pCHdom[2][2],pCC[4][4][16],pCH[4][4][16];
double piCCdom[3][2],piCHdom[3][2],piHHdom[3][2];
double piCC[4][4][9][64],piCH[4][4][9][64],piHH[4][4][9][64];
double Tijdom[3][2],Tijc[4][4][9][64];
// spline knot values
double PCCf[5][5],PCCdfdx[5][5],PCCdfdy[5][5],PCHf[5][5];
double PCHdfdx[5][5],PCHdfdy[5][5];
double piCCf[5][5][11],piCCdfdx[5][5][11];
double piCCdfdy[5][5][11],piCCdfdz[5][5][11];
double piCHf[5][5][11],piCHdfdx[5][5][11];
double piCHdfdy[5][5][11],piCHdfdz[5][5][11];
double piHHf[5][5][11],piHHdfdx[5][5][11];
double piHHdfdy[5][5][11],piHHdfdz[5][5][11];
double Tf[5][5][10],Tdfdx[5][5][10],Tdfdy[5][5][10],Tdfdz[5][5][10];
void REBO_neigh();
void FREBO(int, int);
void FLJ(int, int);
void TORSION(int, int);
double bondorder(int, int, double *, double, double, double **, int);
double bondorderLJ(int, int, double *, double, double,
double *, double, double **, int);
double gSpline(double, double, int, double *, double *);
double PijSpline(double, double, int, int, double *);
double piRCSpline(double, double, double, int, int, double *);
double TijSpline(double, double, double, double *);
- void add_pages();
+ void add_pages(int howmany=1);
void read_file(char *);
double Sp5th(double, double *, double *);
double Spbicubic(double, double, double *, double *);
double Sptricubic(double, double, double, double *, double *);
void spline_init();
void allocate();
// ----------------------------------------------------------------------
// S'(t) and S(t) cutoff functions
// added to header for inlining
// ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
cutoff function Sprime
return cutoff and dX = derivative
no side effects
------------------------------------------------------------------------- */
inline double Sp(double Xij, double Xmin, double Xmax, double &dX) const {
double cutoff;
double t = (Xij-Xmin) / (Xmax-Xmin);
if (t <= 0.0) {
cutoff = 1.0;
dX = 0.0;
} else if (t >= 1.0) {
cutoff = 0.0;
dX = 0.0;
} else {
cutoff = 0.5 * (1.0+cos(t*MathConst::MY_PI));
dX = (-0.5*MathConst::MY_PI*sin(t*MathConst::MY_PI)) / (Xmax-Xmin);
}
return cutoff;
};
/* ----------------------------------------------------------------------
LJ cutoff function Sp2
return cutoff and dX = derivative
no side effects
------------------------------------------------------------------------- */
inline double Sp2(double Xij, double Xmin, double Xmax, double &dX) const {
double cutoff;
double t = (Xij-Xmin) / (Xmax-Xmin);
if (t <= 0.0) {
cutoff = 1.0;
dX = 0.0;
} else if (t >= 1.0) {
cutoff = 0.0;
dX = 0.0;
} else {
cutoff = (1.0-(t*t*(3.0-2.0*t)));
dX = 6.0*(t*t-t) / (Xmax-Xmin);
}
return cutoff;
};
/* kronecker delta function returning a double */
+
inline double kronecker(const int a, const int b) const {
return (a == b) ? 1.0 : 0.0;
};
};
}
#endif
#endif
diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp
index 51bc45ad9..68555bd4f 100644
--- a/src/MANYBODY/pair_comb.cpp
+++ b/src/MANYBODY/pair_comb.cpp
@@ -1,2161 +1,2138 @@
/* ----------------------------------------------------------------------
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: Tzu-Ray Shan (U Florida, present: tnshan@sandia.gov)
LAMMPS implementation of the Charge-optimized many-body (COMB) potential
based on the HELL MD program (Prof Simon Phillpot, UF, sphil@mse.ufl.edu)
and Aidan Thompson's Tersoff code in LAMMPS
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_comb.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "group.h"
#include "update.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXLINE 1024
#define DELTA 4
#define PGDELTA 1
/* ---------------------------------------------------------------------- */
PairComb::PairComb(LAMMPS *lmp) : Pair(lmp)
{
single_enable = 0;
restartinfo = 0;
one_coeff = 1;
nmax = 0;
NCo = NULL;
bbij = NULL;
nelements = 0;
elements = NULL;
nparams = 0;
maxparam = 0;
params = NULL;
elem2param = NULL;
intype = NULL;
fafb = NULL;
dfafb = NULL;
ddfafb = NULL;
phin = NULL;
dphin = NULL;
erpaw = NULL;
sht_num = NULL;
sht_first = NULL;
maxpage = 0;
pages = NULL;
// set comm size needed by this Pair
comm_forward = 1;
comm_reverse = 1;
}
/* ----------------------------------------------------------------------
check if allocated, since class can be destructed when incomplete
------------------------------------------------------------------------- */
PairComb::~PairComb()
{
memory->destroy(NCo);
if (elements)
for (int i = 0; i < nelements; i++) delete [] elements[i];
delete [] elements;
memory->sfree(params);
memory->destroy(elem2param);
memory->destroy(intype);
memory->destroy(fafb);
memory->destroy(dfafb);
memory->destroy(ddfafb);
memory->destroy(phin);
memory->destroy(dphin);
memory->destroy(erpaw);
memory->destroy(bbij);
memory->destroy(sht_num);
memory->destroy(sht_first);
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
delete [] map;
delete [] esm;
}
}
/* ---------------------------------------------------------------------- */
void PairComb::compute(int eflag, int vflag)
{
int i,j,k,ii,jj,kk,inum,jnum,iparam_i;
int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,rsq1,rsq2;
double delr1[3],delr2[3],fi[3],fj[3],fk[3];
double zeta_ij,prefactor;
int *ilist,*jlist,*numneigh,**firstneigh;
int mr1,mr2,mr3;
int rsc,inty;
double elp_ij,filp[3],fjlp[3],fklp[3];
double iq,jq;
double yaself;
double potal,fac11,fac11e;
double vionij,fvionij,sr1,sr2,sr3,Eov,Fov;
int sht_jnum, *sht_jlist;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = vflag_atom = 0;
// Build short range neighbor list
// int every=neighbor->every;
// int ntimestep=update->ntimestep;
// if(ntimestep <= 1 || (ntimestep % every == 0))
Short_neigh();
// grow coordination array if necessary
if (atom->nmax > nmax) {
memory->destroy(NCo);
memory->destroy(bbij);
nmax = atom->nmax;
memory->create(NCo,nmax,"pair:NCo");
memory->create(bbij,nmax,nmax,"pair:bbij");
}
double **x = atom->x;
double **f = atom->f;
double *q = atom->q;
int *tag = atom->tag;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
yaself = vionij = fvionij = Eov = Fov = 0.0;
// self energy correction term: potal
potal_calc(potal,fac11,fac11e);
// loop over full neighbor list of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
iq = q[i];
NCo[i] = 0;
iparam_i = elem2param[itype][itype][itype];
// self energy, only on i atom
yaself = self(&params[iparam_i],iq,potal);
if (evflag) ev_tally(i,i,nlocal,0,yaself,0.0,0.0,0.0,0.0,0.0);
// two-body interactions (long and short repulsive)
jlist = firstneigh[i];
jnum = numneigh[i];
sht_jlist = sht_first[i];
sht_jnum = sht_num[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < x[i][2]) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
// Qj calculates 2-body Coulombic
jtype = map[type[j]];
jq = q[j];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
iparam_ij = elem2param[itype][jtype][jtype];
// long range q-dependent
if (rsq > params[iparam_ij].lcutsq) continue;
inty = intype[itype][jtype];
// polynomial three-point interpolation
tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype);
// 1/r energy and forces
direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq,
potal,fac11,fac11e,vionij,fvionij);
// field correction to self energy
field(&params[iparam_ij],rsq,iq,jq,vionij,fvionij);
// polarization field
// sums up long range forces
f[i][0] += delx*fvionij;
f[i][1] += dely*fvionij;
f[i][2] += delz*fvionij;
f[j][0] -= delx*fvionij;
f[j][1] -= dely*fvionij;
f[j][2] -= delz*fvionij;
if (evflag)
ev_tally(i,j,nlocal,newton_pair,0.0,vionij,fvionij,delx,dely,delz);
// short range q-independent
if (rsq > params[iparam_ij].cutsq) continue;
repulsive(&params[iparam_ij],rsq,fpair,eflag,evdwl,iq,jq);
// repulsion is pure two-body, sums up pair repulsive forces
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
if (evflag)
ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,fpair,delx,dely,delz);
}
// accumulate coordination number information
if (cor_flag) {
for (jj = 0; jj < sht_jnum; jj++) {
j = sht_jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
iparam_ij = elem2param[itype][jtype][jtype];
if(params[iparam_ij].hfocor > 0.0 ) {
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = vec3_dot(delr1,delr1);
if (rsq1 > params[iparam_ij].cutsq) continue;
NCo[i] += 1;
}
}
}
// three-body interactions
// half i-j loop
for (jj = 0; jj < sht_jnum; jj++) {
j = sht_jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
iparam_ij = elem2param[itype][jtype][jtype];
// this Qj for q-dependent BSi
jq = q[j];
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = vec3_dot(delr1,delr1);
if (rsq1 > params[iparam_ij].cutsq) continue;
// accumulate bondorder zeta for each i-j interaction via loop over k
zeta_ij = 0.0;
cuo_flag1 = 0; cuo_flag2 = 0;
for (kk = 0; kk < sht_jnum; kk++) {
k = sht_jlist[kk];
if (j == k) continue;
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
delr2[0] = x[k][0] - xtmp;
delr2[1] = x[k][1] - ytmp;
delr2[2] = x[k][2] - ztmp;
rsq2 = vec3_dot(delr2,delr2);
if (rsq2 > params[iparam_ijk].cutsq) continue;
zeta_ij += zeta(&params[iparam_ijk],rsq1,rsq2,delr1,delr2);
if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1;
if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1;
}
if (cuo_flag1 && cuo_flag2) cuo_flag = 1;
else cuo_flag = 0;
force_zeta(&params[iparam_ij],eflag,i,j,rsq1,zeta_ij,
iq,jq,fpair,prefactor,evdwl);
// over-coordination correction for HfO2
if (cor_flag && NCo[i] != 0)
Over_cor(&params[iparam_ij],rsq1,NCo[i],Eov, Fov);
evdwl += Eov;
fpair += Fov;
f[i][0] += delr1[0]*fpair;
f[i][1] += delr1[1]*fpair;
f[i][2] += delr1[2]*fpair;
f[j][0] -= delr1[0]*fpair;
f[j][1] -= delr1[1]*fpair;
f[j][2] -= delr1[2]*fpair;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,-fpair,-delr1[0],-delr1[1],-delr1[2]);
// attractive term via loop over k (3-body forces)
for (kk = 0; kk < sht_jnum; kk++) {
k = sht_jlist[kk];
if (j == k) continue;
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
delr2[0] = x[k][0] - xtmp;
delr2[1] = x[k][1] - ytmp;
delr2[2] = x[k][2] - ztmp;
rsq2 = vec3_dot(delr2,delr2);
if (rsq2 > params[iparam_ijk].cutsq) continue;
for (rsc = 0; rsc < 3; rsc++)
fi[rsc] = fj[rsc] = fk[rsc] = 0.0;
attractive(&params[iparam_ijk],prefactor,
rsq1,rsq2,delr1,delr2,fi,fj,fk);
// 3-body LP and BB correction and forces
elp_ij = elp(&params[iparam_ijk],rsq1,rsq2,delr1,delr2);
flp(&params[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp);
for (rsc = 0; rsc < 3; rsc++) {
fi[rsc] += filp[rsc];
fj[rsc] += fjlp[rsc];
fk[rsc] += fklp[rsc];
}
for (rsc = 0; rsc < 3; rsc++) {
f[i][rsc] += fi[rsc];
f[j][rsc] += fj[rsc];
f[k][rsc] += fk[rsc];
}
if (evflag)
ev_tally(i,j,nlocal,newton_pair,elp_ij,0.0,0.0,0.0,0.0,0.0);
if (vflag_atom) v_tally3(i,j,k,fj,fk,delr1,delr2);
}
}
if (cuo_flag) params[iparam_i].cutsq *= 0.65;
}
cuo_flag = 0;
if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
void PairComb::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
memory->create(cutsq,n+1,n+1,"pair:cutsq");
map = new int[n+1];
esm = new double[n];
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairComb::settings(int narg, char **arg)
{
if (narg > 0) error->all(FLERR,"Illegal pair_style command");
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairComb::coeff(int narg, char **arg)
{
int i,j,n;
if (!allocated) allocate();
if (narg != 3 + atom->ntypes)
error->all(FLERR,"Incorrect args for pair coefficients");
// insure I,J args are * *
if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
error->all(FLERR,"Incorrect args for pair coefficients");
// read args that map atom types to elements in potential file
// map[i] = which element the Ith atom type is, -1 if NULL
// nelements = # of unique elements
// elements = list of element names
if (elements) {
for (i = 0; i < nelements; i++) delete [] elements[i];
delete [] elements;
}
elements = new char*[atom->ntypes];
for (i = 0; i < atom->ntypes; i++) elements[i] = NULL;
nelements = 0;
for (i = 3; i < narg; i++) {
if (strcmp(arg[i],"NULL") == 0) {
map[i-2] = -1;
continue;
}
for (j = 0; j < nelements; j++)
if (strcmp(arg[i],elements[j]) == 0) break;
map[i-2] = j;
if (j == nelements) {
n = strlen(arg[i]) + 1;
elements[j] = new char[n];
strcpy(elements[j],arg[i]);
nelements++;
}
}
// read potential file and initialize potential parameters
read_file(arg[2]);
setup();
n = atom->ntypes;
// generate streitz-mintmire direct 1/r energy look-up table
if (comm->me == 0 && screen) fprintf(screen,"Pair COMB:\n");
if (comm->me == 0 && screen)
fprintf(screen," generating Coulomb integral lookup table ...\n");
sm_table();
if (cor_flag && comm->me == 0 && screen)
fprintf(screen," will apply over-coordination correction ...\n");
if (!cor_flag&& comm->me == 0 && screen)
fprintf(screen," will not apply over-coordination correction ...\n");
// clear setflag since coeff() called once with I,J = * *
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
// set setflag i,j for type pairs where both are mapped to elements
int count = 0;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
if (map[i] >= 0 && map[j] >= 0) {
setflag[i][j] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairComb::init_style()
{
if (atom->tag_enable == 0)
error->all(FLERR,"Pair style COMB requires atom IDs");
if (force->newton_pair == 0)
error->all(FLERR,"Pair style COMB requires newton pair on");
if (!atom->q_flag)
error->all(FLERR,"Pair style COMB requires atom attribute q");
// ptr to QEQ fix
//for (i = 0; i < modify->nfix; i++)
// if (strcmp(modify->fix[i]->style,"qeq") == 0) break;
//if (i < modify->nfix) fixqeq = (FixQEQ *) modify->fix[i];
//else fixqeq = NULL;
// need a full neighbor list
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
neighbor->requests[irequest]->ghost = 1;
pgsize = neighbor->pgsize;
oneatom = neighbor->oneatom;
if (maxpage == 0) add_pages();
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairComb::init_one(int i, int j)
{
if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
return cutmax;
}
/* ---------------------------------------------------------------------- */
void PairComb::read_file(char *file)
{
int params_per_line = 49;
char **words = new char*[params_per_line+1];
if (params) delete [] params;
params = NULL;
nparams = 0;
// open file on proc 0
FILE *fp;
if (comm->me == 0) {
fp = fopen(file,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open COMB potential file %s",file);
error->one(FLERR,str);
}
}
// read each line out of file, skipping blank lines or leading '#'
// store line of params if all 3 element tags are in element list
int n,nwords,ielement,jelement,kelement;
char line[MAXLINE],*ptr;
int eof = 0;
while (1) {
if (comm->me == 0) {
ptr = fgets(line,MAXLINE,fp);
if (ptr == NULL) {
eof = 1;
fclose(fp);
} else n = strlen(line) + 1;
}
MPI_Bcast(&eof,1,MPI_INT,0,world);
if (eof) break;
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(line,n,MPI_CHAR,0,world);
// strip comment, skip line if blank
if (ptr = strchr(line,'#')) *ptr = '\0';
nwords = atom->count_words(line);
if (nwords == 0) continue;
// concatenate additional lines until have params_per_line words
while (nwords < params_per_line) {
n = strlen(line);
if (comm->me == 0) {
ptr = fgets(&line[n],MAXLINE-n,fp);
if (ptr == NULL) {
eof = 1;
fclose(fp);
} else n = strlen(line) + 1;
}
MPI_Bcast(&eof,1,MPI_INT,0,world);
if (eof) break;
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(line,n,MPI_CHAR,0,world);
if (ptr = strchr(line,'#')) *ptr = '\0';
nwords = atom->count_words(line);
}
if (nwords != params_per_line)
error->all(FLERR,"Incorrect format in COMB potential file");
// words = ptrs to all words in line
nwords = 0;
words[nwords++] = strtok(line," \t\n\r\f");
while (words[nwords++] = strtok(NULL," \t\n\r\f")) continue;
// ielement,jelement,kelement = 1st args
// if all 3 args are in element list, then parse this line
// else skip to next line
for (ielement = 0; ielement < nelements; ielement++)
if (strcmp(words[0],elements[ielement]) == 0) break;
if (ielement == nelements) continue;
for (jelement = 0; jelement < nelements; jelement++)
if (strcmp(words[1],elements[jelement]) == 0) break;
if (jelement == nelements) continue;
for (kelement = 0; kelement < nelements; kelement++)
if (strcmp(words[2],elements[kelement]) == 0) break;
if (kelement == nelements) continue;
// load up parameter settings and error check their values
if (nparams == maxparam) {
maxparam += DELTA;
params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),
"pair:params");
}
params[nparams].ielement = ielement;
params[nparams].jelement = jelement;
params[nparams].kelement = kelement;
params[nparams].powerm = atof(words[3]);
params[nparams].c = atof(words[4]);
params[nparams].d = atof(words[5]);
params[nparams].h = atof(words[6]);
params[nparams].powern = atof(words[7]);
params[nparams].beta = atof(words[8]);
params[nparams].lam21 = atof(words[9]);
params[nparams].lam22 = atof(words[10]);
params[nparams].bigb1 = atof(words[11]);
params[nparams].bigb2 = atof(words[12]);
params[nparams].bigr = atof(words[13]);
params[nparams].bigd = atof(words[14]);
params[nparams].lam11 = atof(words[15]);
params[nparams].lam12 = atof(words[16]);
params[nparams].biga1 = atof(words[17]);
params[nparams].biga2 = atof(words[18]);
params[nparams].plp1 = atof(words[19]);
params[nparams].plp3 = atof(words[20]);
params[nparams].plp6 = atof(words[21]);
params[nparams].a123 = atof(words[22]);
params[nparams].aconf= atof(words[23]);
params[nparams].addrep = atof(words[24]);
params[nparams].romigb = atof(words[25]);
params[nparams].romigc = atof(words[26]);
params[nparams].romigd = atof(words[27]);
params[nparams].romiga = atof(words[28]);
params[nparams].QL1 = atof(words[29]);
params[nparams].QU1 = atof(words[30]);
params[nparams].DL1 = atof(words[31]);
params[nparams].DU1 = atof(words[32]);
params[nparams].QL2 = atof(words[33]);
params[nparams].QU2 = atof(words[34]);
params[nparams].DL2 = atof(words[35]);
params[nparams].DU2 = atof(words[36]);
params[nparams].chi = atof(words[37]);
params[nparams].dj = atof(words[38]);
params[nparams].dk = atof(words[39]);
params[nparams].dl = atof(words[40]);
params[nparams].dm = atof(words[41]);
params[nparams].esm1 = atof(words[42]);
params[nparams].cmn1 = atof(words[43]);
params[nparams].cml1 = atof(words[44]);
params[nparams].cmn2 = atof(words[45]);
params[nparams].cml2 = atof(words[46]);
params[nparams].coulcut = atof(words[47]);
params[nparams].hfocor = atof(words[48]);
params[nparams].powermint = int(params[nparams].powerm);
// parameter sanity checks
if (params[nparams].lam11 < 0.0 || params[nparams].lam12 < 0.0 ||
params[nparams].c < 0.0 || params[nparams].d < 0.0 ||
params[nparams].powern < 0.0 || params[nparams].beta < 0.0 ||
params[nparams].lam21 < 0.0 || params[nparams].lam22 < 0.0 ||
params[nparams].bigb1< 0.0 || params[nparams].bigb2< 0.0 ||
params[nparams].biga1< 0.0 || params[nparams].biga2< 0.0 ||
params[nparams].bigr < 0.0 || params[nparams].bigd < 0.0 ||
params[nparams].bigd > params[nparams].bigr ||
params[nparams].powerm - params[nparams].powermint != 0.0 ||
(params[nparams].powermint != 3 && params[nparams].powermint != 1) ||
params[nparams].plp1 < 0.0 || params[nparams].plp3 < 0.0 ||
params[nparams].plp6 < 0.0 ||
params[nparams].a123 > 360.0 || params[nparams].aconf < 0.0 ||
params[nparams].addrep < 0.0 || params[nparams].romigb < 0.0 ||
params[nparams].romigc < 0.0 || params[nparams].romigd < 0.0 ||
params[nparams].romiga < 0.0 ||
params[nparams].QL1 > 0.0 || params[nparams].QU1 < 0.0 ||
params[nparams].DL1 < 0.0 || params[nparams].DU1 > 0.0 ||
params[nparams].QL2 > 0.0 || params[nparams].QU2 < 0.0 ||
params[nparams].DL2 < 0.0 || params[nparams].DU2 > 0.0 ||
params[nparams].chi < 0.0 ||
// params[nparams].dj < 0.0 || params[nparams].dk < 0.0 ||
// params[nparams].dl < 0.0 || params[nparams].dm < 0.0 ||
params[nparams].esm1 < 0.0)
error->all(FLERR,"Illegal COMB parameter");
if (params[nparams].lam11 < params[nparams].lam21 ||
params[nparams].lam12 < params[nparams].lam22 ||
params[nparams].biga1< params[nparams].bigb1 ||
params[nparams].biga2< params[nparams].bigb2)
error->all(FLERR,"Illegal COMB parameter");
nparams++;
}
delete [] words;
}
/* ---------------------------------------------------------------------- */
void PairComb::setup()
{
int i,j,k,m,n;
// set elem2param for all element triplet combinations
// must be a single exact match to lines read from file
// do not allow for ACB in place of ABC
memory->destroy(elem2param);
memory->create(elem2param,nelements,nelements,nelements,"pair:elem2param");
for (i = 0; i < nelements; i++)
for (j = 0; j < nelements; j++)
for (k = 0; k < nelements; k++) {
n = -1;
for (m = 0; m < nparams; m++) {
if (i == params[m].ielement && j == params[m].jelement &&
k == params[m].kelement) {
if (n >= 0) error->all(FLERR,"Potential file has duplicate entry");
n = m;
}
}
if (n < 0) error->all(FLERR,"Potential file is missing an entry");
elem2param[i][j][k] = n;
}
// compute parameter values derived from inputs
for (m = 0; m < nparams; m++) {
params[m].cut = params[m].bigr + params[m].bigd;
params[m].cutsq = params[m].cut*params[m].cut;
params[m].c1 = pow(2.0*params[m].powern*1.0e-16,-1.0/params[m].powern);
params[m].c2 = pow(2.0*params[m].powern*1.0e-8,-1.0/params[m].powern);
params[m].c3 = 1.0/params[m].c2;
params[m].c4 = 1.0/params[m].c1;
params[m].rlm1 = 0.5*(params[m].lam11+params[m].lam12)*params[m].romigc;
params[m].rlm2 = 0.5*(params[m].lam21+params[m].lam22)*params[m].romigd;
params[m].Qo1 = (params[m].QU1+params[m].QL1)/2.0; // (A22)
params[m].dQ1 = (params[m].QU1-params[m].QL1)/2.0; // (A21)
params[m].aB1 = 1.0 /
(1.0-pow(fabs(params[m].Qo1/params[m].dQ1),10)); // (A20)
params[m].bB1 = pow(fabs(params[m].aB1),0.1)/params[m].dQ1; // (A19)
params[m].nD1 = log(params[m].DU1/(params[m].DU1-params[m].DL1))/
log(params[m].QU1/(params[m].QU1-params[m].QL1));
params[m].bD1 = (pow((params[m].DL1-params[m].DU1),(1.0/params[m].nD1)))/
(params[m].QU1-params[m].QL1);
params[m].Qo2 = (params[m].QU2+params[m].QL2)/2.0; // (A22)
params[m].dQ2 = (params[m].QU2-params[m].QL2)/2.0; // (A21)
params[m].aB2 = 1.0 /
(1.0-pow(fabs(params[m].Qo2/params[m].dQ2),10)); // (A20)
params[m].bB2 = pow(fabs(params[m].aB2),0.1)/params[m].dQ2; // (A19)
params[m].nD2 = log(params[m].DU2/(params[m].DU2-params[m].DL2))/
log(params[m].QU2/(params[m].QU2-params[m].QL2));
params[m].bD2 = (pow((params[m].DL2-params[m].DU2),(1.0/params[m].nD2)))/
(params[m].QU2-params[m].QL2);
params[m].lcut = params[m].coulcut;
params[m].lcutsq = params[m].lcut*params[m].lcut;
}
// set cutmax to max of all params
cutmax = cutmin = 0.0;
cor_flag = 0;
for (m = 0; m < nparams; m++) {
if (params[m].cut > cutmax) cutmax = params[m].cut;
if (params[m].lcut > cutmax) cutmax = params[m].lcut;
if (params[m].cutsq > cutmin) cutmin = params[m].cutsq+1.0;
if (params[m].hfocor > 0.0001) cor_flag = 1;
}
}
/* ---------------------------------------------------------------------- */
void PairComb::repulsive(Param *param, double rsq, double &fforce,
int eflag, double &eng, double iq, double jq)
{
double r,tmp_fc,tmp_fc_d,tmp_exp,Di,Dj;
double bigA,Asi,Asj,vrcs,fvrcs,fforce_tmp;
double rslp,rslp2,rslp4,arr1,arr2,fc2j,fc3j,fcp2j,fcp3j;
double romi = param->addrep;
double rrcs = param->bigr + param->bigd;
r = sqrt(rsq);
if (r > rrcs) return ;
tmp_fc = comb_fc(r,param);
tmp_fc_d = comb_fc_d(r,param);
tmp_exp = exp(-param->rlm1 * r);
arr1 = 2.22850; arr2 = 1.89350;
fc2j = comb_fc2(r);
fc3j = comb_fc3(r);
fcp2j = comb_fc2_d(r);
fcp3j = comb_fc3_d(r);
Di = param->DU1 + pow(fabs(param->bD1*(param->QU1-iq)),param->nD1);
Dj = param->DU2 + pow(fabs(param->bD2*(param->QU2-jq)),param->nD2);
Asi = param->biga1 * exp(param->lam11*Di);
Asj = param->biga2 * exp(param->lam12*Dj);
if ( Asi > 0.0 && Asj > 0.0 )
bigA = sqrt(Asi*Asj)*param->romiga;
else
bigA = 0.0;
fforce = -bigA * tmp_exp * (tmp_fc_d - tmp_fc*param->rlm1) / r;
// additional repulsion for TiO2 and HfO2 (switch by cor_flag)
vrcs = 0.0; fvrcs = 0.0;
if (romi > 0.0) {
if (!cor_flag) {
vrcs = romi * pow((1.0-r/rrcs),2.0);
fvrcs= romi * 2.0 * (r/rrcs-1.0)/rrcs; }
else if (cor_flag) {
rslp = ((arr1-r)/(arr1-arr2));
rslp2 = rslp * rslp; rslp4 = rslp2 * rslp2;
vrcs = fc2j * fc3j * romi * ((50.0*rslp4-30.0*rslp2+4.50))/8.0;
fvrcs = fcp2j*fcp3j*romi*rslp*(-25.0*rslp2+7.50)/(arr1-arr2);
}
fforce_tmp = fforce*vrcs - (tmp_fc * bigA * tmp_exp * fvrcs);
fforce += fforce_tmp;
}
// eng = repulsive energy
if (eflag) eng = (tmp_fc * bigA * tmp_exp)*(1.0+vrcs);
}
/* ---------------------------------------------------------------------- */
double PairComb::zeta(Param *param, double rsqij, double rsqik,
double *delrij, double *delrik)
{
double rij,rik,costheta,arg,ex_delr;
rij = sqrt(rsqij);
if (rij > param->bigr+param->bigd) return 0.0;
rik = sqrt(rsqik);
costheta = vec3_dot(delrij,delrik) / (rij*rik);
if (param->powermint == 3) arg = pow(param->rlm2 * (rij-rik),3.0);
else arg = param->rlm2 * (rij-rik);
if (arg > 69.0776) ex_delr = 1.e30;
else if (arg < -69.0776) ex_delr = 0.0;
else ex_delr = exp(arg);
return comb_fc(rik,param) * comb_gijk(costheta,param) * ex_delr;
}
/* ----------------------------------------------------------------------
Legendre polynomial bond angle correction to energy
------------------------------------------------------------------------- */
double PairComb::elp(Param *param, double rsqij, double rsqik,
double *delrij, double *delrik)
{
if (param->aconf > 1.0e-6 || param->plp1 > 1.0e-6 ||
param->plp3 > 1.0e-6 || param->plp6 > 1.0e-6) {
double rij,rik,costheta,lp1,lp3,lp6;
double rmu,rmu2,comtt,fck;
double pplp1 = param->plp1, pplp3 = param->plp3, pplp6 = param->plp6;
double c123 = cos(param->a123*MY_PI/180.0);
// cos(theta) of the i-j-k
// cutoff function of rik
rij = sqrt(rsqij);
rik = sqrt(rsqik);
costheta = vec3_dot(delrij,delrik) / (rij*rik);
fck = comb_fc(rik,param);
rmu = costheta;
// Legendre Polynomial functions
if (param->plp1 > 1.0e-6 || param->plp3 > 1.0e-6 || param->plp6 > 1.0e-6) {
rmu2 = rmu*rmu;
lp1 = rmu; lp3 = 0.5*(5.0*rmu2*rmu-3.0*rmu);
lp6 = (231.0*rmu2*rmu2*rmu2-315.0*rmu2*rmu2+105.0*rmu2-5.0)/16.0;
comtt = pplp1*lp1 + pplp3*lp3 + pplp6*lp6;
} else comtt = 0.0;
// bond-bending terms
if (param->aconf>1e-4) {
if (param->hfocor >= 0.0)
comtt += param->aconf *(rmu-c123)*(rmu-c123);
else if (param->hfocor < 0.0)
comtt += param->aconf *(4.0-(rmu-c123)*(rmu-c123));
}
return 1.0 * fck * comtt;
}
return 0.0;
}
/* ----------------------------------------------------------------------
Legendre polynomial bond angle correction to forces
------------------------------------------------------------------------- */
void PairComb::flp(Param *param, double rsqij, double rsqik,
double *delrij, double *delrik, double *drilp,
double *drjlp, double *drklp)
{
double ffj1,ffj2,ffk1,ffk2;
ffj1 = 0.0; ffj2 = 0.0; ffk1 = 0.0; ffk2 = 0.0;
if (param->aconf > 1.0e-4 || param->plp1 > 1.0e-6 ||
param->plp3 > 1.0e-6 || param->plp6 > 1.0e-6) {
double rij,rik,costheta,lp1,lp1_d,lp3,lp3_d,lp6,lp6_d;
double rmu,rmu2,comtt,comtt_d,com4k,com5,fcj,fck,fck_d;
double pplp1 = param->plp1;
double pplp3 = param->plp3;
double pplp6 = param->plp6;
double c123 = cos(param->a123*MY_PI/180.0);
// fck_d = derivative of cutoff function
rij = sqrt(rsqij); rik = sqrt(rsqik);
costheta = vec3_dot(delrij,delrik) / (rij*rik);
fcj = comb_fc(rij,param);
fck = comb_fc(rik,param);
fck_d = comb_fc_d(rik,param);
rmu = costheta;
// Legendre Polynomial functions and derivatives
if (param->plp1 > 1.0e-6 || param->plp3 > 1.0e-6 || param->plp6 > 1.0e-6) {
rmu2 = rmu*rmu;
lp1 = rmu; lp3 = (2.5*rmu2*rmu-1.5*rmu);
lp6 = (231.0*rmu2*rmu2*rmu2-315.0*rmu2*rmu2+105.0*rmu2-5.0)/16.0;
lp1_d = 1.0;lp3_d = (7.5*rmu2-1.5);
lp6_d = (1386.0*rmu2*rmu2*rmu-1260.0*rmu2*rmu+210.0)/16.0;
comtt = pplp1*lp1 + pplp3*lp3 + pplp6*lp6;
comtt_d = pplp1*lp1_d + pplp3*lp3_d + pplp6*lp6_d;
} else {
comtt = 0.0;
comtt_d = 0.0;
}
// bond-bending terms derivatives
if (param->aconf > 1.0e-4) {
if (param->hfocor >= 0.0) {
comtt += param->aconf *(rmu-c123)*(rmu-c123);
comtt_d += 2.0*param->aconf*(rmu-c123);
} else if (param->hfocor < 0.0) {
comtt += param->aconf *(4.0-(rmu-c123)*(rmu-c123));
comtt_d += -2.0*param->aconf*(rmu-c123);
}
}
com4k = fcj * fck_d * comtt;
com5 = fcj * fck * comtt_d;
ffj1 =-1.0*(com5/(rij*rik));
ffj2 = 1.0*(com5*rmu/rsqij);
ffk1 = ffj1;
ffk2 = 1.0*(-com4k/rik+com5*rmu/rsqik);
} else {
ffj1 = 0.0; ffj2 = 0.0;
ffk1 = 0.0; ffk2 = 0.0;
}
// j-atom
vec3_scale(ffj1,delrik,drjlp); // (k,x[],y[]), y[]=k*x[]
vec3_scaleadd(ffj2,delrij,drjlp,drjlp); // (k,x[],y[],z[]), z[]=k*x[]+y[]
// k-atom
vec3_scale(ffk1,delrij,drklp);
vec3_scaleadd(ffk2,delrik,drklp,drklp);
// i-atom
vec3_add(drjlp,drklp,drilp); // (x[],y[],z[]), z[]=x[]+y[]
vec3_scale(-1.0,drilp,drilp);
}
/* ---------------------------------------------------------------------- */
void PairComb::force_zeta(Param *param, int eflag, int i, int j, double rsq,
double zeta_ij, double iq, double jq, double &fforce,
double &prefactor, double &eng)
{
double r,fa,fa_d,bij;
r = sqrt(rsq);
if (r > param->bigr+param->bigd) return;
fa = comb_fa(r,param,iq,jq);
fa_d = comb_fa_d(r,param,iq,jq);
bij = comb_bij(zeta_ij,param);
bbij[i][j] = bij;
// force
fforce = 0.5*bij*fa_d / r;
prefactor = -0.5*fa * comb_bij_d(zeta_ij,param);
// eng = attractive energy
if (eflag) eng = 0.5*bij*fa;
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc(double r, Param *param)
{
double comb_R = param->bigr;
double comb_D = param->bigd;
if (r < comb_R-comb_D) return 1.0;
if (r > comb_R+comb_D) return 0.0;
return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/comb_D));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc_d(double r, Param *param)
{
double comb_R = param->bigr;
double comb_D = param->bigd;
if (r < comb_R-comb_D) return 0.0;
if (r > comb_R+comb_D) return 0.0;
return -(MY_PI2/comb_D) * sin(MY_PI*(r - comb_R)/comb_D);
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc2(double r)
{
double comb_R = 1.89350;
double comb_D = comb_R + 0.050;
if (r < comb_R) return 0.0;
if (r > comb_D) return 1.0;
return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R)));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc2_d(double r)
{
double comb_R = 1.89350;
double comb_D = comb_R + 0.050;
if (r < comb_R) return 0.0;
if (r > comb_D) return 0.0;
return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc3(double r)
{
double comb_R = 2.51350;
double comb_D = comb_R + 0.050;
if (r < comb_R) return 1.0;
if (r > comb_D) return 0.0;
return 0.5*(1.0 + cos(MY_PI*(r - comb_R)/(comb_D-comb_R)));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fc3_d(double r)
{
double comb_R = 2.51350;
double comb_D = comb_R + 0.050;
if (r < comb_R) return 0.0;
if (r > comb_D) return 0.0;
return -(MY_PI2/(comb_D-comb_R)) * sin(MY_PI*(r - comb_R)/(comb_D-comb_R));
}
/* ---------------------------------------------------------------------- */
double PairComb::self(Param *param, double qi, double selfpot)
{
double self_tmp, cmin, cmax, qmin, qmax;
double s1=param->chi, s2=param->dj, s3=param->dk, s4=param->dl, s5=param->dm;
self_tmp = 0.0;
qmin = param->QL1*0.90;
qmax = param->QU1*0.90;
cmin = cmax = 1000.0;
self_tmp = qi*(s1+qi*(s2+selfpot+qi*(s3+qi*(s4+qi*qi*s5))));
if (qi < qmin) self_tmp += cmin * pow((qi-qmin),4);
if (qi > qmax) self_tmp += cmax * pow((qi-qmax),4);
return self_tmp;
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fa(double r, Param *param, double iq, double jq)
{
double bigB,Bsi,Bsj;
double qi,qj,Di,Dj;
if (r > param->bigr + param->bigd) return 0.0;
qi = iq; qj = jq;
Di = Dj = Bsi = Bsj = bigB = 0.0;
Di = param->DU1 + pow(fabs(param->bD1*(param->QU1-qi)),param->nD1);
Dj = param->DU2 + pow(fabs(param->bD2*(param->QU2-qj)),param->nD2);
Bsi = param->bigb1 * exp(param->lam21*Di)*
(param->aB1-fabs(pow(param->bB1*(qi-param->Qo1),10)));
Bsj = param->bigb2 * exp(param->lam22*Dj)*
(param->aB2-fabs(pow(param->bB2*(qj-param->Qo2),10)));
if (Bsi > 0.0 && Bsj > 0.0) bigB = sqrt(Bsi*Bsj)*param->romigb;
else bigB = 0.0;
return -bigB * exp(-param->rlm2 * r) * comb_fc(r,param);
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_fa_d(double r, Param *param, double iq, double jq)
{
double bigB,Bsi,Bsj;
double qi,qj,Di,Dj;
if (r > param->bigr + param->bigd) return 0.0;
qi = iq; qj = jq;
Di = Dj = Bsi = Bsj = bigB = 0.0;
Di = param->DU1 + pow(fabs(param->bD1*(param->QU1-qi)),param->nD1);
Dj = param->DU2 + pow(fabs(param->bD2*(param->QU2-qj)),param->nD2);
Bsi = param->bigb1 * exp(param->lam21*Di)*
(param->aB1-fabs(pow(param->bB1*(qi-param->Qo1),10)));
Bsj = param->bigb2 * exp(param->lam22*Dj)*
(param->aB2-fabs(pow(param->bB2*(qj-param->Qo2),10)));
if (Bsi > 0.0 && Bsj > 0.0) bigB = sqrt(Bsi*Bsj)*param->romigb;
else bigB = 0.0;
return bigB * exp(-param->rlm2 * r) *
(param->rlm2 * comb_fc(r,param) - comb_fc_d(r,param));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_bij(double zeta, Param *param)
{
double tmp = param->beta * zeta;
if (tmp > param->c1) return 1.0/sqrt(tmp);
if (tmp > param->c2)
return (1.0 - pow(tmp,-param->powern) / (2.0*param->powern))/sqrt(tmp);
if (tmp < param->c4) return 1.0;
if (tmp < param->c3)
return 1.0 - pow(tmp,param->powern)/(2.0*param->powern);
return pow(1.0 + pow(tmp,param->powern), -1.0/(2.0*param->powern));
}
/* ---------------------------------------------------------------------- */
double PairComb::comb_bij_d(double zeta, Param *param)
{
double tmp = param->beta * zeta;
if (tmp > param->c1) return param->beta * -0.5*pow(tmp,-1.5);
if (tmp > param->c2)
return param->beta * (-0.5*pow(tmp,-1.5) *
(1.0 - 0.5*(1.0 + 1.0/(2.0*param->powern)) *
pow(tmp,-param->powern)));
if (tmp < param->c4) return 0.0;
if (tmp < param->c3)
return -0.5*param->beta * pow(tmp,param->powern-1.0);
double tmp_n = pow(tmp,param->powern);
return -0.5 * pow(1.0+tmp_n, -1.0-(1.0/(2.0*param->powern)))*tmp_n / zeta;
}
/* ---------------------------------------------------------------------- */
-double PairComb::comb_gijk(double costheta, Param *param)
-{
- double comb_c = param->c;
- double comb_d = param->d;
-
- return (1.0 + pow(comb_c/comb_d,2.0) -
- pow(comb_c,2.0) / (pow(comb_d,2.0) + pow(param->h - costheta,2.0)));
-}
-
-/* ---------------------------------------------------------------------- */
-
-double PairComb::comb_gijk_d(double costheta, Param *param)
-{
- double numerator = -2.0 * pow(param->c,2) * (param->h - costheta);
- double denominator = pow(pow(param->d,2.0) +
- pow(param->h - costheta,2.0),2.0);
- return numerator/denominator;
-}
-
-/*------------------------------------------------------------------------- */
-
void PairComb::attractive(Param *param, double prefactor,
double rsqij, double rsqik,
double *delrij, double *delrik,
double *fi, double *fj, double *fk)
{
double rij_hat[3],rik_hat[3];
double rij,rijinv,rik,rikinv;
rij = sqrt(rsqij);
rijinv = 1.0/rij;
vec3_scale(rijinv,delrij,rij_hat);
rik = sqrt(rsqik);
rikinv = 1.0/rik;
vec3_scale(rikinv,delrik,rik_hat);
comb_zetaterm_d(prefactor,rij_hat,rij,rik_hat,rik,fi,fj,fk,param);
}
/* ---------------------------------------------------------------------- */
void PairComb::comb_zetaterm_d(double prefactor, double *rij_hat, double rij,
double *rik_hat, double rik, double *dri,
double *drj, double *drk, Param *param)
{
double gijk,gijk_d,ex_delr,ex_delr_d,fc,dfc,cos_theta,tmp;
double dcosdri[3],dcosdrj[3],dcosdrk[3];
fc = comb_fc(rik,param);
dfc = comb_fc_d(rik,param);
if (param->powermint == 3) tmp = pow(param->rlm2 * (rij-rik),3.0);
else tmp = param->rlm2 * (rij-rik);
if (tmp > 69.0776) ex_delr = 1.e30;
else if (tmp < -69.0776) ex_delr = 0.0;
else ex_delr = exp(tmp); // ex_delr is Ygexp
if (param->powermint == 3)
ex_delr_d = 3.0*pow(param->rlm2,3.0) * pow(rij-rik,2.0)*ex_delr; // com3
else ex_delr_d = param->rlm2 * ex_delr; // com3
cos_theta = vec3_dot(rij_hat,rik_hat);
gijk = comb_gijk(cos_theta,param);
gijk_d = comb_gijk_d(cos_theta,param);
costheta_d(rij_hat,rij,rik_hat,rik,dcosdri,dcosdrj,dcosdrk);
// compute the derivative wrt Ri
// dri = -dfc*gijk*ex_delr*rik_hat;
// dri += fc*gijk_d*ex_delr*dcosdri;
// dri += fc*gijk*ex_delr_d*(rik_hat - rij_hat);
// (k,x[],y[]), y[]=k*x[]
// (k,x[],y[],z[]), z[]=k*x[]+y[]
vec3_scale(-dfc*gijk*ex_delr,rik_hat,dri);
vec3_scaleadd(fc*gijk_d*ex_delr,dcosdri,dri,dri);
vec3_scaleadd(fc*gijk*ex_delr_d,rik_hat,dri,dri);
vec3_scaleadd(-fc*gijk*ex_delr_d,rij_hat,dri,dri);
vec3_scale(prefactor,dri,dri);
// compute the derivative wrt Rj
// drj = fc*gijk_d*ex_delr*dcosdrj;
// drj += fc*gijk*ex_delr_d*rij_hat;
vec3_scale(fc*gijk_d*ex_delr,dcosdrj,drj);
vec3_scaleadd(fc*gijk*ex_delr_d,rij_hat,drj,drj);
vec3_scale(prefactor,drj,drj);
// compute the derivative wrt Rk
// drk = dfc*gijk*ex_delr*rik_hat;
// drk += fc*gijk_d*ex_delr*dcosdrk;
// drk += -fc*gijk*ex_delr_d*rik_hat;
vec3_scale(dfc*gijk*ex_delr,rik_hat,drk);
vec3_scaleadd(fc*gijk_d*ex_delr,dcosdrk,drk,drk);
vec3_scaleadd(-fc*gijk*ex_delr_d,rik_hat,drk,drk);
vec3_scale(prefactor,drk,drk);
}
/* ---------------------------------------------------------------------- */
void PairComb::costheta_d(double *rij_hat, double rij,
double *rik_hat, double rik,
double *dri, double *drj, double *drk)
{
// first element is devative wrt Ri, second wrt Rj, third wrt Rk
double cos_theta = vec3_dot(rij_hat,rik_hat);
vec3_scaleadd(-cos_theta,rij_hat,rik_hat,drj);
vec3_scale(1.0/rij,drj,drj);
vec3_scaleadd(-cos_theta,rik_hat,rij_hat,drk);
vec3_scale(1.0/rik,drk,drk);
vec3_add(drj,drk,dri);
vec3_scale(-1.0,dri,dri);
}
/* ---------------------------------------------------------------------- */
void PairComb::sm_table()
{
int i,j,k,m,nntypes,ncoul;
int inty, itype, jtype;
int iparam_i, iparam_ij, iparam_ji;
double r,dra,drin,rc,z,zr,zrc,ea,eb,ea3,eb3,alf;
double exp2er,exp2ersh,fafash,dfafash,F1,dF1,ddF1,E1,E2,E3,E4;
double exp2ear,exp2ebr,exp2earsh,exp2ebrsh,fafbsh,dfafbsh;
int n = atom->ntypes;
int nmax = atom->nmax;
dra = 0.001; // lookup table step size
drin = 0.1; // starting distance of 1/r
rc = cutmax;
alf = 0.20;
nntypes = int((n+1)*n/2); // interaction types
ncoul = int((rc-drin)/dra)+1;
/*
memory->destroy(intype);
memory->destroy(fafb);
memory->destroy(dfafb);
memory->destroy(ddfafb);
memory->destroy(phin);
memory->destroy(dphin);
memory->destroy(erpaw);
*/
// allocate arrays
memory->create(intype,n,n,"pair:intype");
memory->create(fafb,ncoul,nntypes,"pair:fafb");
memory->create(dfafb,ncoul,nntypes,"pair:dfafb");
memory->create(ddfafb,ncoul,nntypes,"pair:ddfafb");
memory->create(phin,ncoul,nntypes,"pair:phin");
memory->create(dphin,ncoul,nntypes,"pair:dphin");
memory->create(erpaw,25000,2,"pair:erpaw");
memory->create(NCo,nmax,"pair:NCo");
memory->create(bbij,nmax,nmax,"pair:bbij");
memory->create(sht_num,nmax,"pair:sht_num");
sht_first = (int **) memory->smalloc(nmax*sizeof(int *),
"pair:sht_first");
// set interaction number: 0-0=0, 1-1=1, 0-1=1-0=2
m = 0; k = n;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (j == i) {
intype[i][j] = m;
m += 1;
} else if (j != i && j > i) {
intype[i][j] = k;
k += 1;
} else if (j != i && j < i) {
intype[i][j] = intype[j][i];
}
}
}
// default arrays to zero
for (i = 0; i < ncoul; i ++) {
for (j = 0; j < nntypes; j ++) {
fafb[i][j] = 0.0;
dfafb[i][j] = 0.0;
ddfafb[i][j] = 0.0;
phin[i][j] = 0.0;
dphin[i][j] = 0.0;
}
}
// direct 1/r energy with Slater 1S orbital overlap
for (i = 0; i < n; i++) {
r = drin;
itype = params[i].ielement;
iparam_i = elem2param[itype][itype][itype];
z = params[iparam_i].esm1;
for (j = 0; j < ncoul; j++) {
exp2er = exp(-2.0 * z * r);
phin[j][i] = 1.0 - exp2er * (1.0 + 2.0 * z * r * (1.0 + z * r));
dphin[j][i] = (4.0 * exp2er * z * z * z * r * r);
r += dra;
}
}
for (i = 0; i < n; i ++) {
for (j = 0; j < n; j ++) {
r = drin;
if (j == i) {
itype = params[i].ielement;
inty = intype[itype][itype];
iparam_i = elem2param[itype][itype][itype];
z = params[iparam_i].esm1;
zrc = z * rc;
exp2ersh = exp(-2.0 * zrc);
fafash = -exp2ersh * (1.0 / rc +
z * (11.0/8.0 + 3.0/4.0*zrc + zrc*zrc/6.0));
dfafash = exp2ersh * (1.0/(rc*rc) + 2.0*z/rc +
z*z*(2.0 + 7.0/6.0*zrc + zrc*zrc/3.0));
for (k = 0; k < ncoul; k ++) {
zr = z * r;
exp2er = exp(-2.0*zr);
F1 = -exp2er * (1.0 / r +
z * (11.0/8.0 + 3.0/4.0*zr + zr*zr/6.0));
dF1 = exp2er * (1.0/(r*r) + 2.0*z/r +
z*z*(2.0 + 7.0/6.0*zr + zr*zr/3.0));
ddF1 = -exp2er * (2.0/(r*r*r) + 4.0*z/(r*r) -
z*z*z/3.0*(17.0/2.0 + 5.0*zr + 2.0*zr*zr));
fafb[k][inty] = F1-fafash-(r-rc)*dfafash;
dfafb[k][inty] = (dF1 - dfafash);
ddfafb[k][inty] = ddF1;
r += dra;
}
} else if (j != i) {
itype = params[i].ielement;
jtype = params[j].ielement;
inty = intype[itype][jtype];
iparam_ij = elem2param[itype][jtype][jtype];
ea = params[iparam_ij].esm1;
ea3 = ea*ea*ea;
iparam_ji = elem2param[jtype][itype][itype];
eb = params[iparam_ji].esm1;
eb3 = eb*eb*eb;
E1 = ea*eb3*eb/((ea+eb)*(ea+eb)*(ea-eb)*(ea-eb));
E2 = eb*ea3*ea/((ea+eb)*(ea+eb)*(eb-ea)*(eb-ea));
E3 = (3.0*ea*ea*eb3*eb-eb3*eb3) /
((ea+eb)*(ea+eb)*(ea+eb)*(ea-eb)*(ea-eb)*(ea-eb));
E4 = (3.0*eb*eb*ea3*ea-ea3*ea3) /
((ea+eb)*(ea+eb)*(ea+eb)*(eb-ea)*(eb-ea)*(eb-ea));
exp2earsh = exp(-2.0*ea*rc);
exp2ebrsh = exp(-2.0*eb*rc);
fafbsh = -exp2earsh*(E1 + E3/rc)-exp2ebrsh*(E2 + E4/rc);
dfafbsh =
exp2earsh*(2.0*ea*(E1+E3/rc)+E3/(rc*rc)) +
exp2ebrsh*(2.0*eb*(E2+E4/rc)+E4/(rc*rc));
for (k = 0; k < ncoul; k ++) {
exp2ear = exp(-2.0*ea*r);
exp2ebr = exp(-2.0*eb*r);
fafb[k][inty] =
- exp2ear*(E1+E3/r) - exp2ebr*(E2+E4/r)
- fafbsh - (r-rc) * dfafbsh;
dfafb[k][inty] = (exp2ear*(2.0*ea*(E1+E3/r) + E3/(r*r))
+ exp2ebr*(2.0*eb*(E2+E4/r) + E4/(r*r))- dfafbsh);
ddfafb[k][inty] = (- exp2ear*(E3/(r*r)*(1.0/r+2.0*ea/r+2.0/(r*r))
+ 2.0*ea*(E1+E3/r))-
exp2ebr*(E4/(r*r)
*(1.0/r+2.0*eb/r+2.0/(r*r)) +
2.0*eb*(E2+E4/r)));
r += dra;
}
}
}
}
for (i = 0; i < 25000; i ++) {
r = dra * i + drin;
erpaw[i][0] = erfc(r*alf);
erpaw[i][1] = exp(-r*r*alf*alf);
}
}
/* ---------------------------------------------------------------------- */
void PairComb::potal_calc(double &calc1, double &calc2, double &calc3)
{
double alf,rcoul,esucon;
int m;
rcoul = 0.0;
for (m = 0; m < nparams; m++)
if (params[m].lcut > rcoul) rcoul = params[m].lcut;
alf = 0.20;
esucon = force->qqr2e;
calc2 = (erfc(rcoul*alf)/rcoul/rcoul+2.0*alf/MY_PIS*
exp(-alf*alf*rcoul*rcoul)/rcoul)*esucon/rcoul;
calc3 = (erfc(rcoul*alf)/rcoul)*esucon;
calc1 = -(alf/MY_PIS*esucon+calc3*0.5);
}
/* ---------------------------------------------------------------------- */
void PairComb::tri_point(double rsq, int &mr1, int &mr2,
int &mr3, double &sr1, double &sr2,
double &sr3, int &itype)
{
double r, rin, dr, dd, rr1, rridr, rridr2;
rin = 0.10; dr = 0.0010;
r = sqrt(rsq);
if (r < rin + 2.0*dr) r = rin + 2.0*dr;
if (r > cutmax - 2.0*dr) r = cutmax - 2.0*dr;
rridr = (r-rin)/dr;
mr1 = int(rridr)-1;
dd = rridr - float(mr1);
if (dd > 0.5) mr1 += 1;
mr2 = mr1 + 1;
mr3 = mr2 + 1;
rr1 = float(mr1)*dr;
rridr = (r - rin - rr1)/dr;
rridr2 = rridr * rridr;
sr1 = (rridr2 - rridr) * 0.50;
sr2 = 1.0 - rridr2;
sr3 = (rridr2 + rridr) * 0.50;
}
/* ---------------------------------------------------------------------- */
void PairComb::direct(int inty, int mr1, int mr2, int mr3, double rsq,
double sr1, double sr2, double sr3,
double iq, double jq,
double potal, double fac11, double fac11e,
double &pot_tmp, double &pot_d)
{
double r,erfcc,fafbn1,potij,sme2,esucon;
double r3,erfcd,dfafbn1,smf2,dvdrr,alf,alfdpi;
r = sqrt(rsq);
r3 = r * rsq;
alf = 0.20;
alfdpi = 2.0*alf/MY_PIS;
esucon = force->qqr2e;
pot_tmp = 0.0;
pot_d = 0.0;
// 1/r energy
erfcc = sr1*erpaw[mr1][0] + sr2*erpaw[mr2][0] + sr3*erpaw[mr3][0];
fafbn1= sr1*fafb[mr1][inty] + sr2*fafb[mr2][inty] + sr3*fafb[mr3][inty];
potij = (erfcc/r * esucon - fac11e);
sme2 = potij + fafbn1 * esucon;
pot_tmp = 1.0 * iq * jq *sme2;
// 1/r force (wrt r)
erfcd = sr1*erpaw[mr1][1] + sr2*erpaw[mr2][1] + sr3*erpaw[mr3][1];
dfafbn1= sr1*dfafb[mr1][inty] + sr2*dfafb[mr2][inty] + sr3*dfafb[mr3][inty];
dvdrr = (erfcc/r3+alfdpi*erfcd/rsq)*esucon-fac11;
smf2 = dvdrr - dfafbn1 * esucon/r;
pot_d = 1.0 * iq * jq * smf2;
}
/* ---------------------------------------------------------------------- */
void PairComb::field(Param *param, double rsq, double iq,double jq,
double &vionij,double &fvionij)
{
double r,r5,r6,rc,rc5,rc6,rf5,drf6,smpn,smpl,rfx1,rfx2;
double cmi1,cmi2,cmj1,cmj2;
r = sqrt(rsq);
r5 = r*r*r*r*r;
r6 = r5 * r;
rc = param->lcut;
rc5 = rc*rc*rc*rc*rc;
rc6 = rc5 * rc;
cmi1 = param->cmn1;
cmi2 = param->cmn2;
cmj1 = param->cml1;
cmj2 = param->cml2;
rf5 = 1.0/r5 - 1.0/rc5 + 5.0*(r-rc)/rc6;
drf6 = 5.0/rc6 - 5.0/r6;
// field correction energy
smpn = rf5*jq*(cmi1+jq*cmi2);
smpl = rf5*iq*(cmj1+iq*cmj2);
vionij += 1.0 * (smpn + smpl);
// field correction force
rfx1 = jq*drf6*(cmi1+jq*cmi2)/r;
rfx2 = iq*drf6*(cmj1+iq*cmj2)/r;
fvionij -= 1.0 * (rfx1 + rfx2);
}
/* ---------------------------------------------------------------------- */
double PairComb::yasu_char(double *qf_fix, int &igroup)
{
- int i,j,k,ii,jj,kk,jnum,itag,jtag;
- int itype,jtype,ktype,iparam_i,iparam_ij,iparam_ijk;
+ int i,j,ii,jj,jnum,itag,jtag;
+ int itype,jtype,iparam_i,iparam_ij;
double xtmp,ytmp,ztmp;
- double rsq1,rsq2,delr1[3],delr2[3],zeta_ij;
+ double rsq1,delr1[3];
int *ilist,*jlist,*numneigh,**firstneigh;
double iq,jq,fqi,fqj,fqij,fqjj;
double potal,fac11,fac11e,sr1,sr2,sr3;
int mr1,mr2,mr3,inty;
int sht_jnum, *sht_jlist;
double **x = atom->x;
double *q = atom->q;
int *type = atom->type;
int *tag = atom->tag;
int inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
int *mask = atom->mask;
int groupbit = group->bitmask[igroup];
qf = qf_fix;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (mask[i] & groupbit)
qf[i] = 0.0;
}
// communicating charge force to all nodes, first forward then reverse
comm->forward_comm_pair(this);
// self energy correction term: potal
potal_calc(potal,fac11,fac11e);
// loop over full neighbor list of my atoms
fqi = fqj = fqij = fqjj = 0.0;
for (ii = 0; ii < inum; ii ++) {
i = ilist[ii];
itag = tag[i];
if (mask[i] & groupbit) {
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
iq = q[i];
iparam_i = elem2param[itype][itype][itype];
// charge force from self energy
fqi = qfo_self(&params[iparam_i],iq,potal);
// two-body interactions
jlist = firstneigh[i];
jnum = numneigh[i];
sht_jlist = sht_first[i];
sht_jnum = sht_num[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < x[i][2]) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
jq = q[j];
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = vec3_dot(delr1,delr1);
iparam_ij = elem2param[itype][jtype][jtype];
// long range q-dependent
if (rsq1 > params[iparam_ij].lcutsq) continue;
inty = intype[itype][jtype];
// polynomial three-point interpolation
tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype);
// 1/r charge forces
qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij);
fqi += jq * fqij; qf[j] += iq * fqij;
// field correction to self energy and charge force
qfo_field(&params[iparam_ij],rsq1,iq,jq,fqij,fqjj);
fqi += fqij;
qf[j] += fqjj;
}
// three-body interactions
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
jq = q[j];
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = vec3_dot(delr1,delr1);
iparam_ij = elem2param[itype][jtype][jtype];
if (rsq1 > params[iparam_ij].cutsq) continue;
// charge force in Aij and Bij
qfo_short(&params[iparam_ij],i,j,rsq1,iq,jq,fqij,fqjj);
fqi += fqij; qf[j] += fqjj;
}
qf[i] += fqi;
}
}
comm->reverse_comm_pair(this);
// sum charge force on each node and return it
double eneg = 0.0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (mask[i] & groupbit)
eneg += qf[i];
}
double enegtot;
MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world);
return enegtot;
}
/* ---------------------------------------------------------------------- */
double PairComb::qfo_self(Param *param, double qi, double selfpot)
{
double self_d,cmin,cmax,qmin,qmax;
double s1 = param->chi;
double s2 = param->dj;
double s3 = param->dk;
double s4 = param->dl;
double s5 = param->dm;
self_d = 0.0;
qmin = param->QL1*0.90;
qmax = param->QU1*0.90;
if (qmax > 4.50 ) qmax = -0.70;
cmin = cmax = 1000.0;
self_d = s1+qi*(2.0*(s2+selfpot)+qi*(3.0*s3+qi*(4.0*s4+qi*qi*6.0*s5)));
if (qi < qmin) {
// char str[128];
// sprintf(str,"Pair COMB charge %.10f with force %.10f hit min barrier",
// qi,self_d);
// error->warning(FLERR,str,0);
self_d += 4.0 * cmin * pow((qi-qmin),3);
}
if (qi > qmax) {
// char str[128];
// sprintf(str,"Pair COMB charge %.10f with force %.10f hit max barrier",
// qi,self_d);
// error->warning(FLERR,str,0);
self_d += 4.0 * cmax * pow((qi-qmax),3);
}
return self_d;
}
/* ---------------------------------------------------------------------- */
void PairComb::qfo_direct(int inty, int mr1, int mr2, int mr3,
double rsq, double sr1, double sr2,
double sr3, double fac11e, double &fqij)
{
double r, erfcc, fafbn1, vm, esucon;
r = sqrt(rsq);
esucon=force->qqr2e;
// 1/r force (wrt q)
erfcc = sr1*erpaw[mr1][0] + sr2*erpaw[mr2][0] + sr3*erpaw[mr3][0];
fafbn1= sr1*fafb[mr1][inty] + sr2*fafb[mr2][inty] + sr3*fafb[mr3][inty];
vm = (erfcc/r * esucon - fac11e);
fqij = 1.0 * (vm+esucon*fafbn1);
}
/* ---------------------------------------------------------------------- */
void PairComb::qfo_field(Param *param, double rsq,double iq,double jq,
double &fqij, double &fqjj)
{
double r,r5,r6,rc,rc5,rc6;
double cmi1,cmi2,cmj1,cmj2,rf5;
fqij = fqjj = 0.0;
r = sqrt(rsq);
r5 = r*r*r*r*r;
r6 = r5 * r;
rc = param->lcut;
rc5 = rc*rc*rc*rc*rc;
rc6 = rc5 * rc;
cmi1 = param->cmn1;
cmi2 = param->cmn2;
cmj1 = param->cml1;
cmj2 = param->cml2;
rf5 = 1.0/r5 - 1.0/rc5 + 5.0*(r-rc)/rc6;
// field correction charge force
fqij = 1.0 * rf5 * (cmj1 + 2.0 * iq * cmj2);
fqjj = 1.0 * rf5 * (cmi1 + 2.0 * jq * cmi2);
}
/* ---------------------------------------------------------------------- */
void PairComb::qfo_short(Param *param, int i, int j, double rsq,
double iq, double jq, double &fqij, double &fqjj)
{
double r,tmp_fc,tmp_fc_d,tmp_exp1,tmp_exp2;
double bigA,Asi,Asj,vrcs;
double romi = param->addrep,rrcs = param->bigr + param->bigd;
double qi,qj,Di,Dj,bigB,Bsi,Bsj;
double QUchi,QOchi,QUchj,QOchj,YYDiqp,YYDjqp;
double YYAsiqp,YYAsjqp,YYBsiqp,YYBsjqp;
double caj,cbj,bij,cfqr,cfqs;
double romie = param->romiga;
double romib = param->romigb;
double ca1,ca2,ca3,ca4;
double rslp,rslp2,rslp4,arr1,arr2,fc2j,fc3j,fcp2j,fcp3j;
qi = iq; qj = jq; r = sqrt(rsq);
Di = Dj = Asi = Asj = bigA = Bsi = Bsj = bigB = 0.0;
QUchi = QOchi = QUchj = QOchj = YYDiqp = YYDjqp =0.0;
YYAsiqp = YYAsjqp = YYBsiqp = YYBsjqp = 0.0;
caj = cbj = vrcs = cfqr = cfqs = 0.0;
tmp_fc = comb_fc(r,param);
tmp_fc_d = comb_fc_d(r,param);
tmp_exp1 = exp(-param->rlm1 * r);
tmp_exp2 = exp(-param->rlm2 * r);
bij = bbij[i][j]; //comb_bij(zeta_ij,param);
arr1 = 2.22850; arr2 = 1.89350;
fc2j = comb_fc2(r);
fc3j = comb_fc3(r);
fcp2j = comb_fc2_d(r);
fcp3j = comb_fc3_d(r);
vrcs = 0.0;
if (romi > 0.0) {
if (!cor_flag) vrcs = romi * pow((1.0-r/rrcs),2.0);
else if (cor_flag) {
rslp = ((arr1-r)/(arr1-arr2));
rslp2 = rslp * rslp; rslp4 = rslp2 * rslp2;
vrcs = fc2j * fc3j * romi * ((50.0*rslp4-30.0*rslp2+4.50))/8.0;
}
}
Di = param->DU1 + pow(fabs(param->bD1*(param->QU1-qi)),param->nD1);
Dj = param->DU2 + pow(fabs(param->bD2*(param->QU2-qj)),param->nD2);
Asi = param->biga1 * exp(param->lam11*Di);
Asj = param->biga2 * exp(param->lam12*Dj);
Bsi = param->bigb1 * exp(param->lam21*Di)*
(param->aB1-fabs(pow(param->bB1*(qi-param->Qo1),10)));
Bsj = param->bigb2 * exp(param->lam22*Dj)*
(param->aB2-fabs(pow(param->bB2*(qj-param->Qo2),10)));
QUchi = (param->QU1-qi)*param->bD1;
QUchj = (param->QU2-qj)*param->bD2;
QOchi = (qi-param->Qo1)*param->bB1;
QOchj = (qj-param->Qo2)*param->bB2;
if (QUchi == 0.0) YYDiqp = 0.0;
else YYDiqp = -param->nD1 * QUchi * param->bD1 *
pow(fabs(QUchi),(param->nD1-2.0));
if (QUchj == 0.0) YYDjqp = 0.0;
else YYDjqp = -param->nD2 * QUchj * param->bD2 *
pow(fabs(QUchj),(param->nD2-2.0));
YYAsiqp = Asi * param->lam11 * YYDiqp;
YYAsjqp = Asj * param->lam12 * YYDjqp;
if (QOchi == 0.0)
YYBsiqp=Bsi*param->lam21*YYDiqp;
else
YYBsiqp=Bsi*param->lam21*YYDiqp-param->bigb1*exp(param->lam21*Di)*
10.0*QOchi*param->bB1*pow(fabs(QOchi),(10.0-2.0));
if (QOchj == 0.0)
YYBsjqp=Bsj*param->lam22*YYDjqp;
else
YYBsjqp=Bsj*param->lam22*YYDjqp-param->bigb2*exp(param->lam22*Dj)*
10.0*QOchj*param->bB2*pow(fabs(QOchj),(10.0-2.0));
if (Asi > 0.0 && Asj > 0.0) caj = 1.0/(2.0*sqrt(Asi*Asj)) * romie;
else caj = 0.0;
if (Bsi > 0.0 && Bsj > 0.0) cbj = 1.0/(2.0*sqrt(Bsi*Bsj)) * romib ;
else cbj = 0.0;
cfqr = 0.50 * tmp_fc * (1.0 + vrcs); // 0.5 b/c full atom loop
cfqs = -0.50 * tmp_fc * bij;
ca1 = Asj * caj * YYAsiqp;
ca2 = Bsj * cbj * YYBsiqp;
ca3 = Asi * caj * YYAsjqp;
ca4 = Bsi * cbj * YYBsjqp;
fqij = cfqr * tmp_exp1 * ca1;
fqij += cfqs * tmp_exp2 * ca2;
fqjj = cfqr * tmp_exp1 * ca3;
fqjj += cfqs * tmp_exp2 * ca4;
}
/* ---------------------------------------------------------------------- */
void PairComb::Over_cor(Param *param, double rsq1, int NCoi,
double &Eov, double &Fov)
{
double ECo,BCo,tmp_fc,tmp_fc_d;
double r = sqrt(rsq1);
int NCon = NCoi - 7;
tmp_fc = comb_fc(r,param);
tmp_fc_d = comb_fc(r,param);
Eov = 0.0; Fov = 0.0;
ECo = param->hfocor;
BCo = 0.1;
if (NCon >= 0.20) {
Eov = tmp_fc * ECo * NCon/(1.0+exp(BCo*NCon));
Fov = -(tmp_fc_d*Eov + tmp_fc*ECo/(1.0+exp(BCo*NCon)) -
(tmp_fc*ECo*NCon*BCo*exp(BCo*NCon)) /
((1.0+exp(BCo*NCon))*(1.0+exp(BCo*NCon))));
Fov /= r;
}
}
/* ---------------------------------------------------------------------- */
int PairComb::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i ++) {
j = list[i];
buf[m++] = qf[j];
}
return 1;
}
/* ---------------------------------------------------------------------- */
void PairComb::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n ;
for (i = first; i < last; i++) qf[i] = buf[m++];
}
/* ---------------------------------------------------------------------- */
int PairComb::pack_reverse_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) buf[m++] = qf[i];
return 1;
}
/* ---------------------------------------------------------------------- */
void PairComb::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
qf[j] += buf[m++];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double PairComb::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
bytes += nmax * sizeof(int);
bytes += nmax * nmax * sizeof(int);
return bytes;
}
/* ---------------------------------------------------------------------- */
void PairComb::Short_neigh()
{
int nj,itype,jtype,iparam_ij;
int inum,jnum,i,j,ii,jj;
int *neighptrj,*ilist,*jlist,*numneigh;
int **firstneigh;
double xtmp,ytmp,ztmp,rr,rsq,delrj[3];
double **x = atom->x;
int *type = atom->type;
int nlocal = atom->nlocal;
int ntype = atom->ntypes;
if (atom->nmax > nmax) {
nmax = int(1.0 * atom->nmax);
memory->sfree(sht_num);
memory->sfree(sht_first);
memory->create(sht_num,nmax,"pair:sht_num");
sht_first = (int **) memory->smalloc(nmax*sizeof(int *),
"pair:sht_first");
}
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
int npntj = 0;
int npage = 0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
if (pgsize - npntj < oneatom) {
npntj = 0;
npage++;
if (npage == maxpage) add_pages();
}
nj = 0;
neighptrj = &pages[npage][npntj];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
iparam_ij = elem2param[itype][jtype][jtype];
delrj[0] = xtmp - x[j][0];
delrj[1] = ytmp - x[j][1];
delrj[2] = ztmp - x[j][2];
rsq = vec3_dot(delrj,delrj);
if (rsq > cutmin) continue;
neighptrj[nj++] = j;
}
sht_first[i] = neighptrj;
sht_num[i] = nj;
npntj += nj;
}
}
/* ---------------------------------------------------------------------- */
-void PairComb::add_pages()
+void PairComb::add_pages(int howmany)
{
int toppage = maxpage;
- maxpage += PGDELTA;
+ maxpage += howmany*PGDELTA;
pages = (int **)
memory->srealloc(pages,maxpage*sizeof(int *),"pair:pages");
for (int i = toppage; i < maxpage; i++)
memory->create(pages[i],pgsize,"pair:pages[i]");
}
-
-/* ---------------------------------------------------------------------- */
diff --git a/src/MANYBODY/pair_comb.h b/src/MANYBODY/pair_comb.h
index 0a8b11ad0..19bc849b4 100644
--- a/src/MANYBODY/pair_comb.h
+++ b/src/MANYBODY/pair_comb.h
@@ -1,157 +1,181 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(comb,PairComb)
#else
#ifndef LMP_PAIR_COMB_H
#define LMP_PAIR_COMB_H
#include "pair.h"
namespace LAMMPS_NS {
class PairComb : public Pair {
public:
PairComb(class LAMMPS *);
virtual ~PairComb();
- void compute(int, int);
+ virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
void init_style();
double init_one(int, int);
double memory_usage();
- double yasu_char(double *, int &);
+ virtual double yasu_char(double *, int &);
- private:
+ protected:
struct Param {
double lam11,lam12,lam21,lam22;
double c,d,h;
double gamma,powerm;
double powern,beta;
double biga1,biga2,bigb1,bigb2;
double bigd,bigr;
double cut,cutsq;
double c1,c2,c3,c4;
double plp1,plp3,plp6,a123,aconf;
double rlm1,rlm2;
double romiga,romigb,romigc,romigd,addrep;
double QU1,QL1,DU1,DL1,Qo1,dQ1,aB1,bB1,nD1,bD1;
double QU2,QL2,DU2,DL2,Qo2,dQ2,aB2,bB2,nD2,bD2;
double chi,dj,dk,dl,dm,esm1,esm2,cmn1,cmn2,cml1,cml2;
double coulcut, lcut, lcutsq, hfocor;
int ielement,jelement,kelement;
int powermint;
};
double cutmax; // max cutoff for all elements
int nelements; // # of unique elements
char **elements; // names of unique elements
int ***elem2param; // mapping from element triplets to parameters
int *map; // mapping from atom types to elements
int nparams; // # of stored parameter sets
int maxparam; // max # of parameter sets
double precision;
Param *params; // parameter set for an I-J-K interaction
int nmax;
double *qf;
double *esm, **fafb, **dfafb, **ddfafb, **phin, **dphin, **erpaw;
double *charge;
int **intype, *typeno;
int *NCo, cor_flag, cuo_flag, cuo_flag1, cuo_flag2;
double **bbij;
void allocate();
virtual void read_file(char *);
void setup();
virtual void repulsive(Param *, double, double &, int,
double &, double, double);
double zeta(Param *, double, double, double *, double *);
void force_zeta(Param *, int, int, int, double, double, double, double,
double &, double &, double &);
void attractive(Param *, double, double, double, double *, double *,
double *, double *, double *);
double elp(Param *, double, double, double *, double *);
void flp(Param *, double, double, double *, double *, double *,
double *, double *);
double comb_fc(double, Param *);
double comb_fc_d(double, Param *);
double comb_fc2(double);
double comb_fc2_d(double);
double comb_fc3(double);
double comb_fc3_d(double);
virtual double comb_fa(double, Param *, double,double);
virtual double comb_fa_d(double, Param *, double,double);
double comb_bij(double, Param *);
double comb_bij_d(double, Param *);
- double comb_gijk(double, Param *);
- double comb_gijk_d(double, Param *);
+
+ inline double comb_gijk(const double costheta, const Param * const param) const {
+ const double comb_c = param->c * param->c;
+ const double comb_d = param->d * param->d;
+ const double hcth = param->h - costheta;
+
+ return param->gamma*(1.0 + comb_c/comb_d - comb_c / (comb_d + hcth*hcth));
+ }
+
+ inline double comb_gijk_d(const double costheta, const Param * const param) const {
+ const double comb_c = param->c * param->c;
+ const double comb_d = param->d * param->d;
+ const double hcth = param->h - costheta;
+ const double numerator = -2.0 * comb_c * hcth;
+ const double denominator = 1.0/(comb_d + hcth*hcth);
+ return param->gamma*numerator*denominator*denominator;
+ }
+
void comb_zetaterm_d(double, double *, double, double *, double,
double *, double *, double *, Param *);
void costheta_d(double *, double, double *, double,
double *, double *, double *);
double self(Param *, double, double);
void sm_table();
void potal_calc(double &, double &, double &);
void tri_point(double, int &, int &, int &, double &, double &,
double &, int &);
void direct(int,int,int,int,double,double,double,double,double,double,
double,double,double,double &,double &);
void field(Param *,double,double,double,double &,double &);
double qfo_self(Param *, double, double);
void qfo_short(Param *, int, int, double, double, double,
double &, double &);
void qfo_direct (int, int, int, int, double, double, double, double,
double, double &);
void qfo_field(Param *, double,double ,double ,double &, double &);
void qsolve(double *);
void Over_cor(Param *, double, int, double &, double &);
int pack_reverse_comm(int, int, double *);
void unpack_reverse_comm(int, int *, double *);
int pack_comm(int , int *, double *, int, int *);
void unpack_comm(int , int , double *);
// Short range neighbor list
- void add_pages();
+ void add_pages(int howmany=1);
void Short_neigh();
int maxpage, pgsize, oneatom, **pages;
int *sht_num, **sht_first; // short-range neighbor list
double cutmin;
// vector functions, inline for efficiency
- inline double vec3_dot(double *x, double *y) {
+ inline double vec3_dot(const double x[3], const double y[3]) const {
return x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
}
- inline void vec3_add(double *x, double *y, double *z) {
+
+ inline void vec3_add(const double x[3], const double y[3],
+ double * const z) const {
z[0] = x[0]+y[0]; z[1] = x[1]+y[1]; z[2] = x[2]+y[2];
}
- inline void vec3_scale(double k, double *x, double *y) {
+
+ inline void vec3_scale(const double k, const double x[3],
+ double y[3]) const {
y[0] = k*x[0]; y[1] = k*x[1]; y[2] = k*x[2];
}
- inline void vec3_scaleadd(double k, double *x, double *y, double *z) {
- z[0] = k*x[0]+y[0]; z[1] = k*x[1]+y[1]; z[2] = k*x[2]+y[2];
+
+ inline void vec3_scaleadd(const double k, const double x[3],
+ const double y[3], double * const z) const {
+ z[0] = k*x[0]+y[0];
+ z[1] = k*x[1]+y[1];
+ z[2] = k*x[2]+y[2];
}
};
}
#endif
#endif
diff --git a/src/MOLECULE/angle_hybrid.cpp b/src/MOLECULE/angle_hybrid.cpp
index 869b2bf41..6cd641e73 100644
--- a/src/MOLECULE/angle_hybrid.cpp
+++ b/src/MOLECULE/angle_hybrid.cpp
@@ -1,357 +1,367 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "ctype.h"
#include "angle_hybrid.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define EXTRA 1000
/* ---------------------------------------------------------------------- */
AngleHybrid::AngleHybrid(LAMMPS *lmp) : Angle(lmp)
{
nstyles = 0;
}
/* ---------------------------------------------------------------------- */
AngleHybrid::~AngleHybrid()
{
if (nstyles) {
for (int i = 0; i < nstyles; i++) delete styles[i];
delete [] styles;
for (int i = 0; i < nstyles; i++) delete [] keywords[i];
delete [] keywords;
}
if (allocated) {
memory->destroy(setflag);
memory->destroy(map);
delete [] nanglelist;
delete [] maxangle;
for (int i = 0; i < nstyles; i++)
memory->destroy(anglelist[i]);
delete [] anglelist;
}
}
/* ---------------------------------------------------------------------- */
void AngleHybrid::compute(int eflag, int vflag)
{
int i,j,m,n;
// save ptrs to original anglelist
int nanglelist_orig = neighbor->nanglelist;
int **anglelist_orig = neighbor->anglelist;
// if this is re-neighbor step, create sub-style anglelists
// nanglelist[] = length of each sub-style list
// realloc sub-style anglelist if necessary
// load sub-style anglelist with 4 values from original anglelist
if (neighbor->ago == 0) {
for (m = 0; m < nstyles; m++) nanglelist[m] = 0;
for (i = 0; i < nanglelist_orig; i++) {
m = map[anglelist_orig[i][3]];
if (m >= 0) nanglelist[m]++;
}
for (m = 0; m < nstyles; m++) {
if (nanglelist[m] > maxangle[m]) {
memory->destroy(anglelist[m]);
maxangle[m] = nanglelist[m] + EXTRA;
memory->create(anglelist[m],maxangle[m],4,"angle_hybrid:anglelist");
}
nanglelist[m] = 0;
}
for (i = 0; i < nanglelist_orig; i++) {
m = map[anglelist_orig[i][3]];
if (m < 0) continue;
n = nanglelist[m];
anglelist[m][n][0] = anglelist_orig[i][0];
anglelist[m][n][1] = anglelist_orig[i][1];
anglelist[m][n][2] = anglelist_orig[i][2];
anglelist[m][n][3] = anglelist_orig[i][3];
nanglelist[m]++;
}
}
// call each sub-style's compute function
// set neighbor->anglelist to sub-style anglelist before call
// accumulate sub-style global/peratom energy/virial in hybrid
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
for (m = 0; m < nstyles; m++) {
neighbor->nanglelist = nanglelist[m];
neighbor->anglelist = anglelist[m];
styles[m]->compute(eflag,vflag);
if (eflag_global) energy += styles[m]->energy;
if (vflag_global)
for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
}
}
// restore ptrs to original anglelist
neighbor->nanglelist = nanglelist_orig;
neighbor->anglelist = anglelist_orig;
}
/* ---------------------------------------------------------------------- */
void AngleHybrid::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(map,n+1,"angle:map");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
nanglelist = new int[nstyles];
maxangle = new int[nstyles];
anglelist = new int**[nstyles];
for (int m = 0; m < nstyles; m++) maxangle[m] = 0;
for (int m = 0; m < nstyles; m++) anglelist[m] = NULL;
}
/* ----------------------------------------------------------------------
create one angle style for each arg in list
------------------------------------------------------------------------- */
void AngleHybrid::settings(int narg, char **arg)
{
int i,m,istyle;
if (narg < 1) error->all(FLERR,"Illegal angle_style command");
// delete old lists, since cannot just change settings
if (nstyles) {
for (int i = 0; i < nstyles; i++) delete styles[i];
delete [] styles;
for (int i = 0; i < nstyles; i++) delete [] keywords[i];
delete [] keywords;
}
if (allocated) {
memory->destroy(setflag);
memory->destroy(map);
delete [] nanglelist;
delete [] maxangle;
for (int i = 0; i < nstyles; i++)
memory->destroy(anglelist[i]);
delete [] anglelist;
}
allocated = 0;
// count sub-styles by skipping numeric args
// one exception is 1st arg of style "table", which is non-numeric word
// need a better way to skip these exceptions
nstyles = 0;
i = 0;
while (i < narg) {
if (strcmp(arg[i],"table") == 0) i++;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
nstyles++;
}
// allocate list of sub-styles
styles = new Angle*[nstyles];
keywords = new char*[nstyles];
// allocate each sub-style and call its settings() with subset of args
// define subset of args for a sub-style by skipping numeric args
// one exception is 1st arg of style "table", which is non-numeric
// need a better way to skip these exceptions
int dummy;
nstyles = 0;
i = 0;
while (i < narg) {
for (m = 0; m < nstyles; m++)
if (strcmp(arg[i],keywords[m]) == 0)
error->all(FLERR,"Angle style hybrid cannot use same pair style twice");
if (strcmp(arg[i],"hybrid") == 0)
error->all(FLERR,"Angle style hybrid cannot have hybrid as an argument");
if (strcmp(arg[i],"none") == 0)
error->all(FLERR,"Angle style hybrid cannot have none as an argument");
styles[nstyles] = force->new_angle(arg[i],lmp->suffix,dummy);
keywords[nstyles] = new char[strlen(arg[i])+1];
strcpy(keywords[nstyles],arg[i]);
istyle = i;
if (strcmp(arg[i],"table") == 0) i++;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]);
nstyles++;
}
}
/* ----------------------------------------------------------------------
set coeffs for one type
---------------------------------------------------------------------- */
void AngleHybrid::coeff(int narg, char **arg)
{
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
// 2nd arg = angle sub-style name
// allow for "none" or "skip" as valid sub-style name
int m;
for (m = 0; m < nstyles; m++)
if (strcmp(arg[1],keywords[m]) == 0) break;
int none = 0;
int skip = 0;
if (m == nstyles) {
if (strcmp(arg[1],"none") == 0) none = 1;
else if (strcmp(arg[1],"skip") == 0) none = skip = 1;
else error->all(FLERR,"Angle coeff for hybrid has invalid style");
}
// move 1st arg to 2nd arg
// just copy ptrs, since arg[] points into original input line
arg[1] = arg[0];
// invoke sub-style coeff() starting with 1st arg
if (!none) styles[m]->coeff(narg-1,&arg[1]);
// set setflag and which type maps to which sub-style
// if sub-style is skip: auxiliary class2 setting in data file so ignore
// if sub-style is none: set hybrid setflag, wipe out map
for (int i = ilo; i <= ihi; i++) {
if (skip) continue;
else if (none) {
setflag[i] = 1;
map[i] = -1;
} else {
setflag[i] = styles[m]->setflag[i];
map[i] = m;
}
}
}
+/* ----------------------------------------------------------------------
+ run angle style specific initialization
+------------------------------------------------------------------------- */
+
+void AngleHybrid::init_style()
+{
+ for (int m = 0; m < nstyles; m++)
+ if (styles[m]) styles[m]->init_style();
+}
+
/* ----------------------------------------------------------------------
return an equilbrium angle length
------------------------------------------------------------------------- */
double AngleHybrid::equilibrium_angle(int i)
{
if (map[i] < 0)
error->one(FLERR,"Invoked angle equil angle on angle style none");
return styles[map[i]]->equilibrium_angle(i);
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void AngleHybrid::write_restart(FILE *fp)
{
fwrite(&nstyles,sizeof(int),1,fp);
int n;
for (int m = 0; m < nstyles; m++) {
n = strlen(keywords[m]) + 1;
fwrite(&n,sizeof(int),1,fp);
fwrite(keywords[m],sizeof(char),n,fp);
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void AngleHybrid::read_restart(FILE *fp)
{
int me = comm->me;
if (me == 0) fread(&nstyles,sizeof(int),1,fp);
MPI_Bcast(&nstyles,1,MPI_INT,0,world);
styles = new Angle*[nstyles];
keywords = new char*[nstyles];
allocate();
int n,dummy;
for (int m = 0; m < nstyles; m++) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
keywords[m] = new char[n];
if (me == 0) fread(keywords[m],sizeof(char),n,fp);
MPI_Bcast(keywords[m],n,MPI_CHAR,0,world);
styles[m] = force->new_angle(keywords[m],lmp->suffix,dummy);
}
}
/* ---------------------------------------------------------------------- */
double AngleHybrid::single(int type, int i1, int i2, int i3)
{
if (map[type] < 0) error->one(FLERR,"Invoked angle single on angle style none");
return styles[map[type]]->single(type,i1,i2,i3);
}
/* ----------------------------------------------------------------------
memory usage
------------------------------------------------------------------------- */
double AngleHybrid::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += maxangle[m]*4 * sizeof(int);
for (int m = 0; m < nstyles; m++)
if (styles[m]) bytes += styles[m]->memory_usage();
return bytes;
}
diff --git a/src/MOLECULE/angle_hybrid.h b/src/MOLECULE/angle_hybrid.h
index 9671e3a6c..8f12bcb3d 100644
--- a/src/MOLECULE/angle_hybrid.h
+++ b/src/MOLECULE/angle_hybrid.h
@@ -1,57 +1,59 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ANGLE_CLASS
AngleStyle(hybrid,AngleHybrid)
#else
#ifndef LMP_ANGLE_HYBRID_H
#define LMP_ANGLE_HYBRID_H
#include "stdio.h"
#include "angle.h"
namespace LAMMPS_NS {
class AngleHybrid : public Angle {
public:
+ int nstyles; // # of different angle styles
+ Angle **styles; // class list for each Angle style
+ char **keywords; // keyword for each Angle style
+
AngleHybrid(class LAMMPS *);
~AngleHybrid();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
+ void init_style();
double equilibrium_angle(int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, int, int, int);
double memory_usage();
private:
- int nstyles; // # of different angle styles
- Angle **styles; // class list for each Angle style
- char **keywords; // keyword for each Angle style
int *map; // which style each angle type points to
int *nanglelist; // # of angles in sub-style anglelists
int *maxangle; // max # of angles sub-style lists can store
int ***anglelist; // anglelist for each sub-style
void allocate();
};
}
#endif
#endif
diff --git a/src/MOLECULE/dihedral_hybrid.h b/src/MOLECULE/dihedral_hybrid.h
index 551a49d77..9c4b73499 100644
--- a/src/MOLECULE/dihedral_hybrid.h
+++ b/src/MOLECULE/dihedral_hybrid.h
@@ -1,56 +1,57 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(hybrid,DihedralHybrid)
#else
#ifndef LMP_DIHEDRAL_HYBRID_H
#define LMP_DIHEDRAL_HYBRID_H
#include "stdio.h"
#include "dihedral.h"
namespace LAMMPS_NS {
class DihedralHybrid : public Dihedral {
public:
+ int nstyles; // # of different dihedral styles
+ Dihedral **styles; // class list for each Dihedral style
+ char **keywords; // keyword for each dihedral style
+
DihedralHybrid(class LAMMPS *);
~DihedralHybrid();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
double memory_usage();
private:
- int nstyles; // # of different dihedral styles
- Dihedral **styles; // class list for each Dihedral style
- char **keywords; // keyword for each dihedral style
int *map; // which style each dihedral type points to
int *ndihedrallist; // # of dihedrals in sub-style dihedrallists
int *maxdihedral; // max # of dihedrals sub-style lists can store
int ***dihedrallist; // dihedrallist for each sub-style
void allocate();
};
}
#endif
#endif
diff --git a/src/MOLECULE/improper_hybrid.h b/src/MOLECULE/improper_hybrid.h
index ceb75d010..8e866fbf2 100644
--- a/src/MOLECULE/improper_hybrid.h
+++ b/src/MOLECULE/improper_hybrid.h
@@ -1,55 +1,56 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef IMPROPER_CLASS
ImproperStyle(hybrid,ImproperHybrid)
#else
#ifndef LMP_IMPROPER_HYBRID_H
#define LMP_IMPROPER_HYBRID_H
#include "stdio.h"
#include "improper.h"
namespace LAMMPS_NS {
class ImproperHybrid : public Improper {
public:
+ int nstyles; // # of different improper styles
+ Improper **styles; // class list for each Improper style
+ char **keywords; // keyword for each improper style
+
ImproperHybrid(class LAMMPS *);
~ImproperHybrid();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
void write_restart(FILE *);
void read_restart(FILE *);
double memory_usage();
private:
- int nstyles; // # of different improper styles
- Improper **styles; // class list for each Improper style
- char **keywords; // keyword for each improper style
int *map; // which style each improper type points to
int *nimproperlist; // # of impropers in sub-style improperlists
int *maximproper; // max # of impropers sub-style lists can store
int ***improperlist; // improperlist for each sub-style
void allocate();
};
}
#endif
#endif
diff --git a/src/PERI/fix_peri_neigh.h b/src/PERI/fix_peri_neigh.h
index 8a441f22c..c823403a4 100644
--- a/src/PERI/fix_peri_neigh.h
+++ b/src/PERI/fix_peri_neigh.h
@@ -1,73 +1,73 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
FixStyle(PERI_NEIGH,FixPeriNeigh)
#else
#ifndef LMP_FIX_PERI_NEIGH_H
#define LMP_FIX_PERI_NEIGH_H
#include "fix.h"
namespace LAMMPS_NS {
class FixPeriNeigh : public Fix {
friend class PairPeriPMB;
friend class PairPeriPMBOMP;
friend class PairPeriLPS;
friend class PairPeriLPSOMP;
friend class ComputeDamageAtom;
public:
FixPeriNeigh(class LAMMPS *,int, char **);
- ~FixPeriNeigh();
+ virtual ~FixPeriNeigh();
int setmask();
void init();
void init_list(int, class NeighList *);
void setup(int);
void min_setup(int);
double memory_usage();
void grow_arrays(int);
void copy_arrays(int, int);
int pack_exchange(int, double *);
int unpack_exchange(int, double *);
void write_restart(FILE *);
void restart(char *);
int pack_restart(int, double *);
void unpack_restart(int, int);
int size_restart(int);
int maxsize_restart();
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
- private:
+ protected:
int first; // flag for first time initialization
int maxpartner; // max # of peridynamic neighs for any atom
int *npartner; // # of neighbors for each atom
int **partner; // neighs for each atom, stored as global IDs
double **r0; // initial distance to partners
double *vinter; // sum of vfrac for bonded neighbors
double *wvolume; // weighted volume of particle
class NeighList *list;
};
}
#endif
#endif
diff --git a/src/PERI/pair_peri_lps.cpp b/src/PERI/pair_peri_lps.cpp
index ab7471094..10002f8d4 100644
--- a/src/PERI/pair_peri_lps.cpp
+++ b/src/PERI/pair_peri_lps.cpp
@@ -1,745 +1,748 @@
/* ----------------------------------------------------------------------
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: Mike Parks (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "pair_peri_lps.h"
#include "atom.h"
#include "domain.h"
#include "lattice.h"
#include "force.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_peri_neigh.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "memory.h"
#include "error.h"
#include "update.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairPeriLPS::PairPeriLPS(LAMMPS *lmp) : Pair(lmp)
{
for (int i = 0; i < 6; i++) virial[i] = 0.0;
- no_virial_fdotr_compute=1;
+ no_virial_fdotr_compute = 1;
ifix_peri = -1;
nmax = 0;
s0_new = NULL;
theta = NULL;
bulkmodulus = NULL;
shearmodulus = NULL;
s00 = alpha = NULL;
cut = NULL;
// set comm size needed by this Pair
// comm_reverse not needed
comm_forward = 1; // for passing dilatation (theta)
}
/* ---------------------------------------------------------------------- */
PairPeriLPS::~PairPeriLPS()
{
if (ifix_peri >= 0) modify->delete_fix("PERI_NEIGH");
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(bulkmodulus);
memory->destroy(shearmodulus);
memory->destroy(s00);
memory->destroy(alpha);
memory->destroy(cut);
memory->destroy(theta);
memory->destroy(s0_new);
}
}
/* ---------------------------------------------------------------------- */
void PairPeriLPS::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0;
double rsq,r,dr,rk,evdwl,fpair,fbond;
int *ilist,*jlist,*numneigh,**firstneigh;
double d_ij,delta,stretch;
evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
double **f = atom->f;
double **x = atom->x;
int *type = atom->type;
int nlocal = atom->nlocal;
double *vfrac = atom->vfrac;
double *s0 = atom->s0;
double **x0 = atom->x0;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
// lc = lattice constant
// init_style guarantees it's the same in x, y, and z
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double vfrac_scale = 1.0;
// short-range forces
int newton_pair = force->newton_pair;
int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
// need minimg() for x0 difference since not ghosted
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
jtype = type[j];
r = sqrt(rsq);
// short-range interaction distance based on initial particle position
// 0.9 and 1.35 are constants
d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
// short-range contact forces
// 15 is constant taken from the EMU Theory Manual
// Silling, 12 May 2005, p 18
if (r < d_ij) {
dr = r - d_ij;
// kshort based upon short-range force constant
// of the bond-based theory used in PMB model
double kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) /
(3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]);
rk = (kshort * vfrac[j]) * (dr / cut[itype][jtype]);
if (r > 0.0) fpair = -(rk/r);
else fpair = 0.0;
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (eflag) evdwl = 0.5*rk*dr;
- if (evflag) ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,fpair*vfrac[i],delx,dely,delz);
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,evdwl,0.0,
+ fpair*vfrac[i],delx,dely,delz);
}
}
}
// grow bond forces array if necessary
if (atom->nmax > nmax) {
memory->destroy(s0_new);
memory->destroy(theta);
nmax = atom->nmax;
memory->create(s0_new,nmax,"pair:s0_new");
memory->create(theta,nmax,"pair:theta");
}
// Compute the dilatation on each particle
compute_dilatation();
// communicate dilatation (theta) of each particle
comm->forward_comm_pair(this);
// communicate wighted volume (wvolume) upon every reneighbor
if (neighbor->ago == 0)
comm->forward_comm_fix(modify->fix[ifix_peri]);
// Volume-dependent part of the energy
if (eflag) {
for (i = 0; i < nlocal; i++) {
itype = type[i];
if (eflag_global)
eng_vdwl += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
if (eflag_atom)
eatom[i] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
}
}
// loop over my particles and their partners
// partner list contains all bond partners, so I-J appears twice
// if bond already broken, skip this partner
// first = true if this is first neighbor of particle i
bool first;
double omega_minus, omega_plus;
for (i = 0; i < nlocal; i++) {
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
itype = type[i];
jnum = npartner[i];
first = true;
for (jj = 0; jj < jnum; jj++) {
if (partner[i][jj] == 0) continue;
j = atom->map(partner[i][jj]);
// check if lost a partner without first breaking bond
if (j < 0) {
partner[i][jj] = 0;
continue;
}
// compute force density, add to PD equation of motion
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
if (periodic) domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
jtype = type[j];
delta = cut[itype][jtype];
r = sqrt(rsq);
dr = r - r0[i][jj];
// avoid roundoff errors
if (fabs(dr) < 2.2204e-016) dr = 0.0;
// scale vfrac[j] if particle j near the horizon
if ((fabs(r0[i][jj] - delta)) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((delta - half_lc)/(2*half_lc) ) );
else vfrac_scale = 1.0;
omega_plus = influence_function(-1.0*delx0,-1.0*dely0,-1.0*delz0);
omega_minus = influence_function(delx0,dely0,delz0);
rk = ( (3.0 * bulkmodulus[itype][itype]) -
(5.0 * shearmodulus[itype][itype]) ) * vfrac[j] * vfrac_scale *
( (omega_plus * theta[i] / wvolume[i]) +
( omega_minus * theta[j] / wvolume[j] ) ) * r0[i][jj];
rk += 15.0 * ( shearmodulus[itype][itype] * vfrac[j] * vfrac_scale ) *
( (omega_plus / wvolume[i]) + (omega_minus / wvolume[j]) ) * dr;
if (r > 0.0) fbond = -(rk/r);
else fbond = 0.0;
f[i][0] += delx*fbond;
f[i][1] += dely*fbond;
f[i][2] += delz*fbond;
// since I-J is double counted, set newton off & use 1/2 factor and I,I
double deviatoric_extension = dr - (theta[i]* r0[i][jj] / 3.0);
if (eflag) evdwl = 0.5 * 15 * (shearmodulus[itype][itype]/wvolume[i]) *
omega_plus*(deviatoric_extension * deviatoric_extension) *
vfrac[j] * vfrac_scale;
- if (evflag) ev_tally(i,i,nlocal,0,0.5*evdwl,0.0,0.5*fbond*vfrac[i],delx,dely,delz);
+ if (evflag) ev_tally(i,i,nlocal,0,0.5*evdwl,0.0,
+ 0.5*fbond*vfrac[i],delx,dely,delz);
// find stretch in bond I-J and break if necessary
// use s0 from previous timestep
stretch = dr / r0[i][jj];
if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0;
// update s0 for next timestep
if (first)
s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch);
else
- s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch));
+ s0_new[i] = MAX(s0_new[i],s00[itype][jtype] -
+ (alpha[itype][jtype] * stretch));
first = false;
}
}
// store new s0
for (i = 0; i < nlocal; i++) s0[i] = s0_new[i];
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairPeriLPS::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(bulkmodulus,n+1,n+1,"pair:bulkmodulus");
memory->create(shearmodulus,n+1,n+1,"pair:shearmodulus");
memory->create(s00,n+1,n+1,"pair:s00");
memory->create(alpha,n+1,n+1,"pair:alpha");
memory->create(cut,n+1,n+1,"pair:cut");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairPeriLPS::settings(int narg, char **arg)
{
if (narg) error->all(FLERR,"Illegal pair_style command");
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairPeriLPS::coeff(int narg, char **arg)
{
if (narg != 7) error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
double bulkmodulus_one = atof(arg[2]);
double shearmodulus_one = atof(arg[3]);
double cut_one = atof(arg[4]);
double s00_one = atof(arg[5]);
double alpha_one = atof(arg[6]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
bulkmodulus[i][j] = bulkmodulus_one;
shearmodulus[i][j] = shearmodulus_one;
cut[i][j] = cut_one;
s00[i][j] = s00_one;
alpha[i][j] = alpha_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairPeriLPS::init_one(int i, int j)
{
if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
bulkmodulus[j][i] = bulkmodulus[i][j];
shearmodulus[j][i] = shearmodulus[i][j];
s00[j][i] = s00[i][j];
alpha[j][i] = alpha[i][j];
cut[j][i] = cut[i][j];
return cut[i][j];
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairPeriLPS::init_style()
{
// error checks
if (!atom->peri_flag) error->all(FLERR,"Pair style peri requires atom style peri");
if (atom->map_style == 0)
error->all(FLERR,"Pair peri requires an atom map, see atom_modify");
if (domain->lattice == NULL)
error->all(FLERR,"Pair peri requires a lattice be defined");
if (domain->lattice->xlattice != domain->lattice->ylattice ||
domain->lattice->xlattice != domain->lattice->zlattice ||
domain->lattice->ylattice != domain->lattice->zlattice)
error->all(FLERR,"Pair peri lattice is not identical in x, y, and z");
// if first init, create Fix needed for storing fixed neighbors
if (ifix_peri == -1) {
char **fixarg = new char*[3];
fixarg[0] = (char *) "PERI_NEIGH";
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "PERI_NEIGH";
modify->add_fix(3,fixarg);
delete [] fixarg;
}
// find associated PERI_NEIGH fix that must exist
// could have changed locations in fix list since created
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"PERI_NEIGH") == 0) ifix_peri = i;
if (ifix_peri == -1) error->all(FLERR,"Fix peri neigh does not exist");
neighbor->request(this);
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairPeriLPS::write_restart(FILE *fp)
{
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&bulkmodulus[i][j],sizeof(double),1,fp);
fwrite(&shearmodulus[i][j],sizeof(double),1,fp);
fwrite(&s00[i][j],sizeof(double),1,fp);
fwrite(&alpha[i][j],sizeof(double),1,fp);
fwrite(&cut[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairPeriLPS::read_restart(FILE *fp)
{
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&bulkmodulus[i][j],sizeof(double),1,fp);
fread(&shearmodulus[i][j],sizeof(double),1,fp);
fread(&s00[i][j],sizeof(double),1,fp);
fread(&alpha[i][j],sizeof(double),1,fp);
fread(&cut[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&bulkmodulus[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&shearmodulus[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&s00[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&alpha[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ---------------------------------------------------------------------- */
double PairPeriLPS::single(int i, int j, int itype, int jtype,
double rsq, double factor_coul, double factor_lj,
double &fforce)
{
double delx0,dely0,delz0,rsq0;
double d_ij,r,dr,rk,vfrac_scale;
double *vfrac = atom->vfrac;
double **x0 = atom->x0;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double kshort;
delx0 = x0[i][0] - x0[j][0];
dely0 = x0[i][1] - x0[j][1];
delz0 = x0[i][2] - x0[j][2];
int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic;
if (periodic) domain->minimum_image(delx0,dely0,delz0);
rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
r = sqrt(rsq);
double energy = 0.0;
fforce = 0.0;
if (r < d_ij) {
dr = r - d_ij;
// kshort resembles short-range force constant of bond-based theory in 3d
kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) /
( 3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]);
rk = ( kshort * vfrac[j]) * (dr / sqrt(cutsq[itype][jtype]));
if (r > 0.0) fforce += -(rk/r);
energy += 0.5*rk*dr;
}
if (atom->nmax > nmax) {
memory->destroy(theta);
nmax = atom->nmax;
memory->create(theta,nmax,"pair:theta");
}
// Compute the dilatation on each particle
compute_dilatation();
// communicate dilatation (theta) of each particle
comm->forward_comm_pair(this);
// communicate wighted volume (wvolume) upon every reneighbor
if (neighbor->ago == 0)
comm->forward_comm_fix(modify->fix[ifix_peri]);
double omega_plus, omega_minus;
int jnum = npartner[i];
for (int jj = 0; jj < jnum; jj++) {
if (partner[i][jj] == 0) continue;
if (j < 0) continue;
if (j == atom->map(partner[i][jj])) {
dr = r - r0[i][jj];
if (fabs(dr) < 2.2204e-016) dr = 0.0;
// scale vfrac[j] if particle j near the horizon
if ( (fabs(r0[i][jj] - sqrt(cutsq[itype][jtype]))) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((sqrt(cutsq[itype][jtype]) - half_lc)/(2*half_lc)));
else vfrac_scale = 1.0;
omega_plus = influence_function(-1.0*delx0,-1.0*dely0,-1.0*delz0);
omega_minus = influence_function(delx0,dely0,delz0);
rk = (3.0* bulkmodulus[itype][itype] -5.0 * shearmodulus[itype][itype]) *
vfrac[j] * vfrac_scale * ( (omega_plus * theta[i] / wvolume[i]) +
(omega_minus * theta[j] / wvolume[j])) *
r0[i][jj];
rk += 15.0 * ( shearmodulus[itype][itype] * vfrac[j] * vfrac_scale ) *
( (omega_plus / wvolume[i]) + (omega_minus / wvolume[j]) ) * dr;
if (r > 0.0) fforce += -(rk/r);
energy += 0.5 * 15 * (shearmodulus[itype][itype]/wvolume[i]) *
omega_plus * ( dr - theta[i]* r0[i][jj] / 3.0 ) *
( dr - theta[i]* r0[i][jj] / 3.0 ) * vfrac[j] * vfrac_scale;
}
}
return energy;
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double PairPeriLPS::memory_usage()
{
double bytes = 2 * nmax * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
influence function definition
------------------------------------------------------------------------- */
double PairPeriLPS::influence_function(double xi_x, double xi_y, double xi_z)
{
double r = sqrt(xi_x*xi_x + xi_y*xi_y + xi_z*xi_z);
double omega;
if (fabs(r) < 2.2204e-016)
error->one(FLERR,"Divide by 0 in influence function of pair peri/lps");
omega = 1.0/r;
return omega;
}
/* ---------------------------------------------------------------------- */
void PairPeriLPS::compute_dilatation()
{
int i,j,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0;
double rsq,r,dr;
double delta;
double **x = atom->x;
int *type = atom->type;
double **x0 = atom->x0;
int nlocal = atom->nlocal;
double *vfrac = atom->vfrac;
double vfrac_scale = 1.0;
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic;
// compute the dilatation theta
for (i = 0; i < nlocal; i++) {
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
jnum = npartner[i];
theta[i] = 0.0;
itype = type[i];
for (jj = 0; jj < jnum; jj++) {
// if bond already broken, skip this partner
if (partner[i][jj] == 0) continue;
// Look up local index of this partner particle
j = atom->map(partner[i][jj]);
// Skip if particle is "lost"
if (j < 0) continue;
// Compute force density and add to PD equation of motion
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
if (periodic) domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
r = sqrt(rsq);
dr = r - r0[i][jj];
if (fabs(dr) < 2.2204e-016) dr = 0.0;
jtype = type[j];
delta = cut[itype][jtype];
// scale vfrac[j] if particle j near the horizon
if ((fabs(r0[i][jj] - delta)) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((delta - half_lc)/(2*half_lc) ) );
else vfrac_scale = 1.0;
theta[i] += influence_function(delx0, dely0, delz0) * r0[i][jj] * dr *
vfrac[j] * vfrac_scale;
}
// if wvolume[i] is zero, then particle i has no bonds
// therefore, the dilatation is set to
if (wvolume[i] != 0.0) theta[i] = (3.0/wvolume[i]) * theta[i];
else theta[i] = 0;
}
}
/* ----------------------------------------------------------------------
communication routines
---------------------------------------------------------------------- */
int PairPeriLPS::pack_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = theta[j];
}
return 1;
}
/* ---------------------------------------------------------------------- */
void PairPeriLPS::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
theta[i] = buf[m++];
}
}
diff --git a/src/REPLICA/Install.sh b/src/REPLICA/Install.sh
index 50264e134..1fd33b5fe 100644
--- a/src/REPLICA/Install.sh
+++ b/src/REPLICA/Install.sh
@@ -1,47 +1,51 @@
# Install/unInstall package files in LAMMPS
if (test $1 = 1) then
cp compute_event_displace.cpp ..
cp fix_event.cpp ..
cp fix_event_prd.cpp ..
cp fix_event_tad.cpp ..
cp fix_neb.cpp ..
+ cp verlet_split.cpp ..
cp neb.cpp ..
cp prd.cpp ..
cp tad.cpp ..
cp temper.cpp ..
cp compute_event_displace.h ..
cp fix_event.h ..
cp fix_event_prd.h ..
cp fix_event_tad.h ..
cp fix_neb.h ..
+ cp verlet_split.h ..
cp neb.h ..
cp prd.h ..
cp tad.h ..
cp temper.h ..
elif (test $1 = 0) then
rm -f ../compute_event_displace.cpp
rm -f ../fix_event.cpp
rm -f ../fix_event_prd.cpp
rm -f ../fix_event_tad.cpp
rm -f ../fix_neb.cpp
+ rm -f ../verlet_split.cpp
rm -f ../neb.cpp
rm -f ../prd.cpp
rm -f ../tad.cpp
rm -f ../temper.cpp
rm -f ../compute_event_displace.h
rm -f ../fix_event.h
rm -f ../fix_event_prd.h
rm -f ../fix_event_tad.h
rm -f ../fix_neb.h
+ rm -f ../verlet_split.h
rm -f ../neb.h
rm -f ../prd.h
rm -f ../tad.h
rm -f ../temper.h
fi
diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp
index c8747aa81..f6719fa3a 100644
--- a/src/REPLICA/neb.cpp
+++ b/src/REPLICA/neb.cpp
@@ -1,508 +1,511 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "neb.h"
#include "universe.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "min.h"
#include "modify.h"
#include "fix.h"
#include "fix_neb.h"
#include "output.h"
#include "thermo.h"
#include "finish.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define CHUNK 1000
#define MAXLINE 256
/* ---------------------------------------------------------------------- */
NEB::NEB(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
internal NEB constructor, called from TAD
------------------------------------------------------------------------- */
NEB::NEB(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
int n2steps_in, int nevery_in, double *buf_init, double *buf_final)
: Pointers(lmp)
{
double delx,dely,delz;
etol = etol_in;
ftol = ftol_in;
n1steps = n1steps_in;
n2steps = n2steps_in;
nevery = nevery_in;
// replica info
nreplica = universe->nworlds;
ireplica = universe->iworld;
me_universe = universe->me;
uworld = universe->uworld;
MPI_Comm_rank(world,&me);
// generate linear interpolate replica
double fraction = ireplica/(nreplica-1.0);
double **x = atom->x;
int nlocal = atom->nlocal;
int ii = 0;
for (int i = 0; i < nlocal; i++) {
delx = buf_final[ii] - buf_init[ii];
dely = buf_final[ii+1] - buf_init[ii+1];
delz = buf_final[ii+2] - buf_init[ii+2];
domain->minimum_image(delx,dely,delz);
x[i][0] = buf_init[ii] + fraction*delx;
x[i][1] = buf_init[ii+1] + fraction*dely;
x[i][2] = buf_init[ii+2] + fraction*delz;
ii += 3;
}
}
/* ---------------------------------------------------------------------- */
NEB::~NEB()
{
MPI_Comm_free(&roots);
memory->destroy(all);
delete [] rdist;
}
/* ----------------------------------------------------------------------
perform NEB on multiple replicas
------------------------------------------------------------------------- */
void NEB::command(int narg, char **arg)
{
if (domain->box_exist == 0)
error->all(FLERR,"NEB command before simulation box is defined");
if (narg != 6) error->universe_all(FLERR,"Illegal NEB command");
etol = atof(arg[0]);
ftol = atof(arg[1]);
n1steps = atoi(arg[2]);
n2steps = atoi(arg[3]);
nevery = atoi(arg[4]);
infile = arg[5];
// error checks
if (etol < 0.0) error->all(FLERR,"Illegal NEB command");
if (ftol < 0.0) error->all(FLERR,"Illegal NEB command");
if (nevery == 0) error->universe_all(FLERR,"Illegal NEB command");
if (n1steps % nevery || n2steps % nevery)
error->universe_all(FLERR,"Illegal NEB command");
// replica info
nreplica = universe->nworlds;
ireplica = universe->iworld;
me_universe = universe->me;
uworld = universe->uworld;
MPI_Comm_rank(world,&me);
// error checks
if (nreplica == 1) error->all(FLERR,"Cannot use NEB with a single replica");
if (nreplica != universe->nprocs)
error->all(FLERR,"Can only use NEB with 1-processor replicas");
if (atom->sortfreq > 0)
error->all(FLERR,"Cannot use NEB with atom_modify sort enabled");
if (atom->map_style == 0)
error->all(FLERR,"Cannot use NEB unless atom map exists");
// read in file of final state atom coords and reset my coords
readfile(infile);
// run the NEB calculation
run();
}
/* ----------------------------------------------------------------------
run NEB on multiple replicas
------------------------------------------------------------------------- */
void NEB::run()
{
// create MPI communicator for root proc from each world
int color;
if (me == 0) color = 0;
else color = 1;
MPI_Comm_split(uworld,color,0,&roots);
int ineb;
for (ineb = 0; ineb < modify->nfix; ineb++)
if (strcmp(modify->fix[ineb]->style,"neb") == 0) break;
if (ineb == modify->nfix) error->all(FLERR,"NEB requires use of fix neb");
fneb = (FixNEB *) modify->fix[ineb];
nall = 4;
memory->create(all,nreplica,nall,"neb:all");
rdist = new double[nreplica];
// initialize LAMMPS
update->whichflag = 2;
update->etol = etol;
update->ftol = ftol;
update->multireplica = 1;
lmp->init();
if (update->minimize->searchflag)
error->all(FLERR,"NEB requires damped dynamics minimizer");
// setup regular NEB minimization
if (me_universe == 0 && universe->uscreen)
fprintf(universe->uscreen,"Setting up regular NEB ...\n");
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + n1steps;
update->nsteps = n1steps;
update->max_eval = n1steps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps for NEB");
update->minimize->setup();
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
if (universe->ulogfile)
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
}
print_status();
// perform regular NEB for n1steps or until replicas converge
// retrieve PE values from fix NEB and print every nevery iterations
// break induced if converged
// damped dynamic min styles insure all replicas converge together
+ timer->init();
timer->barrier_start(TIME_LOOP);
while (update->minimize->niter < n1steps) {
update->minimize->run(nevery);
print_status();
if (update->minimize->stop_condition) break;
}
timer->barrier_stop(TIME_LOOP);
update->minimize->cleanup();
Finish finish(lmp);
finish.end(1);
// switch fix NEB to climbing mode
// top = replica that becomes hill climber
double vmax = all[0][0];
int top = 0;
for (int m = 1; m < nreplica; m++)
if (vmax < all[m][0]) {
vmax = all[m][0];
top = m;
}
// setup climbing NEB minimization
// must reinitialize minimizer so it re-creates its fix MINIMIZE
if (me_universe == 0 && universe->uscreen)
fprintf(universe->uscreen,"Setting up climbing ...\n");
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,"Climbing replica = %d\n",top+1);
if (universe->ulogfile)
fprintf(universe->ulogfile,"Climbing replica = %d\n",top+1);
}
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + n2steps;
update->nsteps = n2steps;
update->max_eval = n2steps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
update->minimize->init();
fneb->rclimber = top;
update->minimize->setup();
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
if (universe->ulogfile)
fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
"GradV0 GradV1 GradVc "
"EBF EBR RDT "
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
}
print_status();
// perform climbing NEB for n2steps or until replicas converge
// retrieve PE values from fix NEB and print every nevery iterations
// break induced if converged
// damped dynamic min styles insure all replicas converge together
+ timer->init();
timer->barrier_start(TIME_LOOP);
+
while (update->minimize->niter < n2steps) {
update->minimize->run(nevery);
print_status();
if (update->minimize->stop_condition) break;
}
timer->barrier_stop(TIME_LOOP);
update->minimize->cleanup();
finish.end(1);
update->whichflag = 0;
update->multireplica = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
}
/* ----------------------------------------------------------------------
read target coordinates from file, store with appropriate atom
adjust coords of each atom based on ireplica
new coord = replica fraction between current and final state
------------------------------------------------------------------------- */
void NEB::readfile(char *file)
{
if (me_universe == 0) {
if (screen) fprintf(screen,"Reading NEB coordinate file %s ...\n",file);
open(file);
}
double fraction = ireplica/(nreplica-1.0);
double **x = atom->x;
int nlocal = atom->nlocal;
char *buffer = new char[CHUNK*MAXLINE];
char *ptr,*next,*bufptr;
int i,m,nlines,tag;
double xx,yy,zz,delx,dely,delz;
int firstline = 1;
int ncount = 0;
int eof = 0;
while (!eof) {
if (me_universe == 0) {
m = 0;
for (nlines = 0; nlines < CHUNK; nlines++) {
ptr = fgets(&buffer[m],MAXLINE,fp);
if (ptr == NULL) break;
m += strlen(&buffer[m]);
}
if (ptr == NULL) eof = 1;
buffer[m++] = '\n';
}
MPI_Bcast(&eof,1,MPI_INT,0,uworld);
MPI_Bcast(&nlines,1,MPI_INT,0,uworld);
MPI_Bcast(&m,1,MPI_INT,0,uworld);
MPI_Bcast(buffer,m,MPI_CHAR,0,uworld);
bufptr = buffer;
for (i = 0; i < nlines; i++) {
next = strchr(bufptr,'\n');
*next = '\0';
if (firstline) {
if (atom->count_words(bufptr) == 4) firstline = 0;
else error->all(FLERR,"Incorrect format in NEB coordinate file");
}
sscanf(bufptr,"%d %lg %lg %lg",&tag,&xx,&yy,&zz);
// adjust atom coord based on replica fraction
// ignore image flags of final x
// new x is displacement from old x
// if final x is across periodic boundary:
// new x may be outside box
// will be remapped back into box when simulation starts
// its image flags will be adjusted appropriately
m = atom->map(tag);
if (m >= 0 && m < nlocal) {
delx = xx - x[m][0];
dely = yy - x[m][1];
delz = zz - x[m][2];
domain->minimum_image(delx,dely,delz);
x[m][0] += fraction*delx;
x[m][1] += fraction*dely;
x[m][2] += fraction*delz;
ncount++;
}
bufptr = next + 1;
}
}
// clean up
delete [] buffer;
if (me_universe == 0) {
if (compressed) pclose(fp);
else fclose(fp);
}
}
/* ----------------------------------------------------------------------
universe proc 0 opens NEB data file
test if gzipped
------------------------------------------------------------------------- */
void NEB::open(char *file)
{
compressed = 0;
char *suffix = file + strlen(file) - 3;
if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
if (!compressed) fp = fopen(file,"r");
else {
#ifdef LAMMPS_GZIP
char gunzip[128];
sprintf(gunzip,"gunzip -c %s",file);
fp = popen(gunzip,"r");
#else
error->one(FLERR,"Cannot open gzipped file");
#endif
}
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
}
/* ----------------------------------------------------------------------
query fix NEB for PE of each replica
proc 0 prints current NEB status
------------------------------------------------------------------------- */
void NEB::print_status()
{
double fnorm2 = sqrt(update->minimize->fnorm_sqr());
double fmaxreplica;
MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots);
double fnorminf = update->minimize->fnorm_inf();
double fmaxatom;
MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots);
double one[4];
one[0] = fneb->veng;
one[1] = fneb->plen;
one[2] = fneb->nlen;
one[nall-1] = fneb->gradvnorm;
if (output->thermo->normflag) one[0] /= atom->natoms;
if (me == 0)
MPI_Allgather(one,nall,MPI_DOUBLE,&all[0][0],nall,MPI_DOUBLE,roots);
rdist[0] = 0.0;
for (int i = 1; i < nreplica; i++)
rdist[i] = rdist[i-1] + all[i][1];
double endpt = rdist[nreplica-1] = rdist[nreplica-2] + all[nreplica-2][2];
for (int i = 1; i < nreplica; i++)
rdist[i] /= endpt;
// look up GradV for the initial, final, and climbing replicas
// these are identical to fnorm2, but to be safe we
// take them straight from fix_neb
double gradvnorm0, gradvnorm1, gradvnormc;
int irep;
irep = 0;
gradvnorm0 = all[irep][3];
irep = nreplica-1;
gradvnorm1 = all[irep][3];
irep = fneb->rclimber;
if (irep > -1) {
gradvnormc = all[irep][3];
ebf = all[irep][0]-all[0][0];
ebr = all[irep][0]-all[nreplica-1][0];
} else {
double vmax = all[0][0];
int top = 0;
for (int m = 1; m < nreplica; m++)
if (vmax < all[m][0]) {
vmax = all[m][0];
top = m;
}
irep = top;
gradvnormc = all[irep][3];
ebf = all[irep][0]-all[0][0];
ebr = all[irep][0]-all[nreplica-1][0];
}
if (me_universe == 0) {
if (universe->uscreen) {
fprintf(universe->uscreen,BIGINT_FORMAT " %g %g ",update->ntimestep,
fmaxreplica,fmaxatom);
fprintf(universe->uscreen,"%g %g %g ",
gradvnorm0,gradvnorm1,gradvnormc);
fprintf(universe->uscreen,"%g %g %g ",ebf,ebr,endpt);
for (int i = 0; i < nreplica; i++)
fprintf(universe->uscreen,"%g %g ",rdist[i],all[i][0]);
fprintf(universe->uscreen,"\n");
}
if (universe->ulogfile) {
fprintf(universe->ulogfile,BIGINT_FORMAT " %g %g ",update->ntimestep,
fmaxreplica,fmaxatom);
fprintf(universe->ulogfile,"%g %g %g ",
gradvnorm0,gradvnorm1,gradvnormc);
fprintf(universe->ulogfile,"%g %g %g ",ebf,ebr,endpt);
for (int i = 0; i < nreplica; i++)
fprintf(universe->ulogfile,"%g %g ",rdist[i],all[i][0]);
fprintf(universe->ulogfile,"\n");
fflush(universe->ulogfile);
}
}
}
diff --git a/src/REPLICA/prd.cpp b/src/REPLICA/prd.cpp
index 909d7e35e..ff20afe73 100644
--- a/src/REPLICA/prd.cpp
+++ b/src/REPLICA/prd.cpp
@@ -1,817 +1,822 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "prd.h"
#include "universe.h"
#include "update.h"
#include "atom.h"
#include "domain.h"
#include "region.h"
#include "comm.h"
#include "velocity.h"
#include "integrate.h"
#include "min.h"
#include "neighbor.h"
#include "modify.h"
#include "compute.h"
#include "fix.h"
#include "fix_event_prd.h"
#include "force.h"
#include "pair.h"
#include "random_park.h"
#include "random_mars.h"
#include "output.h"
#include "dump.h"
#include "finish.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PRD::PRD(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
perform PRD simulation on one or more replicas
------------------------------------------------------------------------- */
void PRD::command(int narg, char **arg)
{
int flag,ireplica;
// error checks
if (domain->box_exist == 0)
error->all(FLERR,"PRD command before simulation box is defined");
if (universe->nworlds != universe->nprocs &&
atom->map_style == 0)
error->all(FLERR,"Cannot use PRD with multi-processor replicas "
"unless atom map exists");
if (universe->nworlds == 1 && comm->me == 0)
error->warning(FLERR,"Running PRD with only one replica");
if (narg < 7) error->universe_all(FLERR,"Illegal prd command");
nsteps = atoi(arg[0]);
t_event = atoi(arg[1]);
n_dephase = atoi(arg[2]);
t_dephase = atoi(arg[3]);
t_corr = atoi(arg[4]);
char id_compute[strlen(arg[5])+1];
strcpy(id_compute,arg[5]);
int seed = atoi(arg[6]);
options(narg-7,&arg[7]);
// total # of timesteps must be multiple of t_event
if (t_event <= 0) error->universe_all(FLERR,"Invalid t_event in prd command");
if (nsteps % t_event)
error->universe_all(FLERR,"PRD nsteps must be multiple of t_event");
if (t_corr % t_event)
error->universe_all(FLERR,"PRD t_corr must be multiple of t_event");
// local storage
int me_universe = universe->me;
int nprocs_universe = universe->nprocs;
int nreplica = universe->nworlds;
int iworld = universe->iworld;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
// comm_replica = communicator between same proc across replicas
// not used if replicas have unequal number of procs
// equal_size_replicas = 1 if all replicas have same # of procs
int color = me;
MPI_Comm_split(universe->uworld,color,0,&comm_replica);
flag = 0;
if (nreplica*nprocs == nprocs_universe) flag = 1;
MPI_Allreduce(&flag,&equal_size_replicas,1,MPI_INT,MPI_MIN,universe->uworld);
// workspace for inter-replica communication via gathers
natoms = atom->natoms;
displacements = NULL;
tagall = NULL;
xall = NULL;
imageall = NULL;
if (nreplica != nprocs_universe) {
displacements = new int[nprocs];
memory->create(tagall,natoms,"prd:tagall");
memory->create(xall,natoms,3,"prd:xall");
memory->create(imageall,natoms,"prd:imageall");
}
// random_select = same RNG for each replica for multiple event selection
// random_dephase = unique RNG for each replica for dephasing
random_select = new RanPark(lmp,seed);
random_dephase = new RanMars(lmp,seed+iworld);
// create ComputeTemp class to monitor temperature
char **args = new char*[3];
args[0] = (char *) "prd_temp";
args[1] = (char *) "all";
args[2] = (char *) "temp";
modify->add_compute(3,args);
temperature = modify->compute[modify->ncompute-1];
// create Velocity class for velocity creation in dephasing
// pass it temperature compute, loop_setting, dist_setting settings
atom->check_mass();
velocity = new Velocity(lmp);
velocity->init_external("all");
args[0] = (char *) "temp";
args[1] = (char *) "prd_temp";
velocity->options(2,args);
args[0] = (char *) "loop";
args[1] = (char *) loop_setting;
if (loop_setting) velocity->options(2,args);
args[0] = (char *) "dist";
args[1] = (char *) dist_setting;
if (dist_setting) velocity->options(2,args);
// create FixEventPRD class to store event and pre-quench states
args[0] = (char *) "prd_event";
args[1] = (char *) "all";
args[2] = (char *) "EVENT/PRD";
modify->add_fix(3,args);
fix_event = (FixEventPRD *) modify->fix[modify->nfix-1];
// create Finish for timing output
finish = new Finish(lmp);
// string clean-up
delete [] args;
delete [] loop_setting;
delete [] dist_setting;
// assign FixEventPRD to event-detection compute
// necessary so it will know atom coords at last event
int icompute = modify->find_compute(id_compute);
if (icompute < 0) error->all(FLERR,"Could not find compute ID for PRD");
compute_event = modify->compute[icompute];
compute_event->reset_extra_compute_fix("prd_event");
// reset reneighboring criteria since will perform minimizations
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
if (me == 0)
error->warning(FLERR,"Resetting reneighboring criteria during PRD");
}
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
// initialize PRD as if one long dynamics run
update->whichflag = 1;
update->nsteps = nsteps;
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + nsteps;
update->restrict_output = 1;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
lmp->init();
// init minimizer settings and minimizer itself
update->etol = etol;
update->ftol = ftol;
update->max_eval = maxeval;
update->minimize->init();
// cannot use PRD with time-dependent fixes or regions or atom sorting
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->time_depend)
error->all(FLERR,"Cannot use PRD with a time-dependent fix defined");
for (int i = 0; i < domain->nregion; i++)
if (domain->regions[i]->dynamic_check())
error->all(FLERR,"Cannot use PRD with a time-dependent region defined");
if (atom->sortfreq > 0)
error->all(FLERR,"Cannot use PRD with atom_modify sort enabled");
// perform PRD simulation
if (me_universe == 0 && universe->uscreen)
fprintf(universe->uscreen,"Setting up PRD ...\n");
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,"Step CPU Clock Event "
"Correlated Coincident Replica\n");
if (universe->ulogfile)
fprintf(universe->ulogfile,"Step CPU Clock Event "
"Correlated Coincident Replica\n");
}
// store hot state and quenched event for replica 0
// use share_event() to copy that info to all replicas
// this insures all start from same place
// need this line if quench() does only setup_minimal()
// update->minimize->setup();
fix_event->store_state();
quench();
ncoincident = 0;
share_event(0,0);
+
+ timer->init();
timer->barrier_start(TIME_LOOP);
time_start = timer->array[TIME_LOOP];
+
log_event();
// do full init/setup since are starting all replicas after event
// replica 0 bcasts temp to all replicas if temp_dephase is not set
update->whichflag = 1;
lmp->init();
update->integrate->setup();
if (temp_flag == 0) {
if (universe->iworld == 0) temp_dephase = temperature->compute_scalar();
MPI_Bcast(&temp_dephase,1,MPI_DOUBLE,universe->root_proc[0],
universe->uworld);
}
// main loop: look for events until out of time
// (1) dephase independently on each proc after event
// (2) loop: dynamics, store state, quench, check event, restore state
// (3) share and record event
nbuild = ndanger = 0;
time_dephase = time_dynamics = time_quench = time_comm = time_output = 0.0;
timer->barrier_start(TIME_LOOP);
time_start = timer->array[TIME_LOOP];
while (update->ntimestep < update->endstep) {
dephase();
ireplica = -1;
while (update->ntimestep < update->endstep) {
dynamics();
fix_event->store_state();
quench();
ireplica = check_event();
if (ireplica >= 0) break;
fix_event->restore_state();
}
if (ireplica < 0) break;
// potentially more efficient for correlated events if don't
// share until correlated check has completed
// this will complicate the dump (always on replica 0)
share_event(ireplica,1);
log_event();
int restart_flag = 0;
if (output->restart_every && universe->iworld == 0)
if (fix_event->event_number % output->restart_every == 0)
restart_flag = 1;
// correlated event loop
// other procs could be dephasing during this time
int corr_endstep = update->ntimestep + t_corr;
while (update->ntimestep < corr_endstep) {
if (update->ntimestep == update->endstep) {
restart_flag = 0;
break;
}
dynamics();
fix_event->store_state();
quench();
int corr_event_check = check_event(ireplica);
if (corr_event_check >= 0) {
share_event(ireplica,2);
log_event();
corr_endstep = update->ntimestep + t_corr;
} else fix_event->restore_state();
}
// full init/setup since are starting all replicas after event
// event replica bcasts temp to all replicas if temp_dephase is not set
update->whichflag = 1;
lmp->init();
update->integrate->setup();
timer->barrier_start(TIME_LOOP);
+
if (t_corr > 0) replicate(ireplica);
if (temp_flag == 0) {
if (ireplica == universe->iworld)
temp_dephase = temperature->compute_scalar();
MPI_Bcast(&temp_dephase,1,MPI_DOUBLE,universe->root_proc[ireplica],
universe->uworld);
}
+
timer->barrier_stop(TIME_LOOP);
time_comm += timer->array[TIME_LOOP];
// write restart file of hot coords
if (restart_flag) {
timer->barrier_start(TIME_LOOP);
output->write_restart(update->ntimestep);
timer->barrier_stop(TIME_LOOP);
time_output += timer->array[TIME_LOOP];
}
}
// set total timers and counters so Finish() will process them
timer->array[TIME_LOOP] = time_start;
timer->barrier_stop(TIME_LOOP);
timer->array[TIME_PAIR] = time_dephase;
timer->array[TIME_BOND] = time_dynamics;
timer->array[TIME_KSPACE] = time_quench;
timer->array[TIME_COMM] = time_comm;
timer->array[TIME_OUTPUT] = time_output;
neighbor->ncalls = nbuild;
neighbor->ndanger = ndanger;
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
}
finish->end(2);
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
update->restrict_output = 0;
// reset reneighboring criteria
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
// clean up
delete [] displacements;
memory->destroy(tagall);
memory->destroy(xall);
memory->destroy(imageall);
MPI_Comm_free(&comm_replica);
delete random_select;
delete random_dephase;
delete velocity;
delete finish;
modify->delete_compute("prd_temp");
modify->delete_fix("prd_event");
compute_event->reset_extra_compute_fix(NULL);
}
/* ----------------------------------------------------------------------
dephasing = one or more short runs with new random velocities
------------------------------------------------------------------------- */
void PRD::dephase()
{
bigint ntimestep_hold = update->ntimestep;
update->whichflag = 1;
update->nsteps = n_dephase*t_dephase;
timer->barrier_start(TIME_LOOP);
for (int i = 0; i < n_dephase; i++) {
int seed = static_cast<int> (random_dephase->uniform() * MAXSMALLINT);
if (seed == 0) seed = 1;
velocity->create(temp_dephase,seed);
update->integrate->run(t_dephase);
if (temp_flag == 0) temp_dephase = temperature->compute_scalar();
}
timer->barrier_stop(TIME_LOOP);
time_dephase += timer->array[TIME_LOOP];
update->integrate->cleanup();
finish->end(0);
// reset timestep as if dephase did not occur
// clear timestep storage from computes, since now invalid
update->ntimestep = ntimestep_hold;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
}
/* ----------------------------------------------------------------------
single short dynamics run
------------------------------------------------------------------------- */
void PRD::dynamics()
{
update->whichflag = 1;
update->nsteps = t_event;
lmp->init();
update->integrate->setup();
// this may be needed if don't do full init
//modify->addstep_compute_all(update->ntimestep);
int ncalls = neighbor->ncalls;
timer->barrier_start(TIME_LOOP);
update->integrate->run(t_event);
timer->barrier_stop(TIME_LOOP);
time_dynamics += timer->array[TIME_LOOP];
nbuild += neighbor->ncalls - ncalls;
ndanger += neighbor->ndanger;
update->integrate->cleanup();
finish->end(0);
}
/* ----------------------------------------------------------------------
quench minimization
------------------------------------------------------------------------- */
void PRD::quench()
{
bigint ntimestep_hold = update->ntimestep;
bigint endstep_hold = update->endstep;
// need to change whichflag so that minimize->setup() calling
// modify->setup() will call fix->min_setup()
update->whichflag = 2;
update->nsteps = maxiter;
update->endstep = update->laststep = update->firststep + maxiter;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many iterations");
// full init works
lmp->init();
update->minimize->setup();
// partial init does not work
//modify->addstep_compute_all(update->ntimestep);
//update->minimize->setup_minimal(1);
int ncalls = neighbor->ncalls;
timer->barrier_start(TIME_LOOP);
update->minimize->run(maxiter);
timer->barrier_stop(TIME_LOOP);
time_quench += timer->array[TIME_LOOP];
if (neighbor->ncalls == ncalls) quench_reneighbor = 0;
else quench_reneighbor = 1;
update->minimize->cleanup();
finish->end(0);
// reset timestep as if dephase did not occur
// clear timestep storage from computes, since now invalid
update->ntimestep = ntimestep_hold;
update->endstep = update->laststep = endstep_hold;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
}
/* ----------------------------------------------------------------------
check for an event in any replica
if replica_num is non-negative only check for event on replica_num
if multiple events, choose one at random
return -1 if no event
else return ireplica = world in which event occured
------------------------------------------------------------------------- */
int PRD::check_event(int replica_num)
{
int worldflag,universeflag,scanflag,replicaflag,ireplica;
worldflag = 0;
if (compute_event->compute_scalar() > 0.0) worldflag = 1;
if (replica_num >= 0 && replica_num != universe->iworld) worldflag = 0;
timer->barrier_start(TIME_LOOP);
if (me == 0) MPI_Allreduce(&worldflag,&universeflag,1,
MPI_INT,MPI_SUM,comm_replica);
MPI_Bcast(&universeflag,1,MPI_INT,0,world);
ncoincident = universeflag;
if (!universeflag) ireplica = -1;
else {
if (universeflag > 1) {
int iwhich = static_cast<int>
(universeflag*random_select->uniform()) + 1;
if (me == 0) MPI_Scan(&worldflag,&scanflag,1,
MPI_INT,MPI_SUM,comm_replica);
MPI_Bcast(&scanflag,1,MPI_INT,0,world);
if (scanflag != iwhich) worldflag = 0;
}
if (worldflag) replicaflag = universe->iworld;
else replicaflag = 0;
if (me == 0) MPI_Allreduce(&replicaflag,&ireplica,1,
MPI_INT,MPI_SUM,comm_replica);
MPI_Bcast(&ireplica,1,MPI_INT,0,world);
}
timer->barrier_stop(TIME_LOOP);
time_comm += timer->array[TIME_LOOP];
return ireplica;
}
/* ----------------------------------------------------------------------
share quenched and hot coords owned by ireplica with all replicas
all replicas store event in fix_event
replica 0 dumps event snapshot
flag = 0 = called before PRD run
flag = 1 = called during PRD run = not correlated event
flag = 2 = called during PRD run = correlated event
------------------------------------------------------------------------- */
void PRD::share_event(int ireplica, int flag)
{
timer->barrier_start(TIME_LOOP);
// communicate quenched coords to all replicas and store as event
// decrement event counter if flag = 0 since not really an event
replicate(ireplica);
timer->barrier_stop(TIME_LOOP);
time_comm += timer->array[TIME_LOOP];
// adjust time for last correlated event check (not on first event)
int corr_adjust = t_corr;
if (fix_event->event_number < 1 || flag == 2) corr_adjust = 0;
// delta = time since last correlated event check
int delta = update->ntimestep - fix_event->event_timestep - corr_adjust;
// if this is a correlated event, time elapsed only on one partition
if (flag != 2) delta *= universe->nworlds;
delta += corr_adjust;
// don't change the clock or timestep if this is a restart
if (flag == 0 && fix_event->event_number != 0)
fix_event->store_event_prd(fix_event->event_timestep,0);
else {
fix_event->store_event_prd(update->ntimestep,delta);
fix_event->replica_number = ireplica;
fix_event->correlated_event = 0;
if (flag == 2) fix_event->correlated_event = 1;
fix_event->ncoincident = ncoincident;
}
if (flag == 0) fix_event->event_number--;
// dump snapshot of quenched coords
// must reneighbor and compute forces before dumping
// since replica 0 possibly has new state from another replica
// addstep_compute_all insures eng/virial are calculated if needed
if (output->ndump && universe->iworld == 0) {
timer->barrier_start(TIME_LOOP);
modify->addstep_compute_all(update->ntimestep);
update->integrate->setup_minimal(1);
output->write_dump(update->ntimestep);
timer->barrier_stop(TIME_LOOP);
time_output += timer->array[TIME_LOOP];
}
// restore and communicate hot coords to all replicas
fix_event->restore_state();
timer->barrier_start(TIME_LOOP);
replicate(ireplica);
timer->barrier_stop(TIME_LOOP);
time_comm += timer->array[TIME_LOOP];
}
/* ----------------------------------------------------------------------
universe proc 0 prints event info
------------------------------------------------------------------------- */
void PRD::log_event()
{
timer->array[TIME_LOOP] = time_start;
if (universe->me == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,
BIGINT_FORMAT " %.3f %d %d %d %d %d\n",
fix_event->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->clock,
fix_event->event_number,fix_event->correlated_event,
fix_event->ncoincident,
fix_event->replica_number);
if (universe->ulogfile)
fprintf(universe->ulogfile,
BIGINT_FORMAT " %.3f %d %d %d %d %d\n",
fix_event->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->clock,
fix_event->event_number,fix_event->correlated_event,
fix_event->ncoincident,
fix_event->replica_number);
}
}
/* ----------------------------------------------------------------------
communicate atom coords and image flags in ireplica to all other replicas
one proc per replica:
direct overwrite via bcast
equal procs per replica and no replica reneighbored:
direct overwrite via bcast
unequal procs per replica or reneighboring occurred:
collect to root proc of event replica
bcast to roots of other replicas
bcast within each replica
each proc extracts info for atoms it owns using atom IDs
------------------------------------------------------------------------- */
void PRD::replicate(int ireplica)
{
int nreplica = universe->nworlds;
int nprocs_universe = universe->nprocs;
int i,m,flag,commflag;
int counts[nprocs];
if (nreplica == nprocs_universe) commflag = 0;
else if (equal_size_replicas) {
flag = 0;
if (quench_reneighbor) flag = 1;
MPI_Allreduce(&flag,&commflag,1,MPI_INT,MPI_MAX,universe->uworld);
} else commflag = 1;
if (commflag == 0) {
MPI_Bcast(atom->image,atom->nlocal,MPI_INT,ireplica,comm_replica);
MPI_Bcast(atom->x[0],3*atom->nlocal,MPI_DOUBLE,ireplica,comm_replica);
} else {
if (universe->iworld == ireplica) {
MPI_Gather(&atom->nlocal,1,MPI_INT,counts,1,MPI_INT,0,world);
displacements[0] = 0;
for (i = 0; i < nprocs-1; i++)
displacements[i+1] = displacements[i] + counts[i];
MPI_Gatherv(atom->tag,atom->nlocal,MPI_INT,
tagall,counts,displacements,MPI_INT,0,world);
MPI_Gatherv(atom->image,atom->nlocal,MPI_INT,
imageall,counts,displacements,MPI_INT,0,world);
for (i = 0; i < nprocs; i++) counts[i] *= 3;
for (i = 0; i < nprocs-1; i++)
displacements[i+1] = displacements[i] + counts[i];
MPI_Gatherv(atom->x[0],3*atom->nlocal,MPI_DOUBLE,
xall[0],counts,displacements,MPI_DOUBLE,0,world);
}
if (me == 0) {
MPI_Bcast(tagall,natoms,MPI_INT,ireplica,comm_replica);
MPI_Bcast(imageall,natoms,MPI_INT,ireplica,comm_replica);
MPI_Bcast(xall[0],3*natoms,MPI_DOUBLE,ireplica,comm_replica);
}
MPI_Bcast(tagall,natoms,MPI_INT,0,world);
MPI_Bcast(imageall,natoms,MPI_INT,0,world);
MPI_Bcast(xall[0],3*natoms,MPI_DOUBLE,0,world);
double **x = atom->x;
int nlocal = atom->nlocal;
for (i = 0; i < natoms; i++) {
m = atom->map(tagall[i]);
if (m >= 0 && m < nlocal) {
x[m][0] = xall[i][0];
x[m][1] = xall[i][1];
x[m][2] = xall[i][2];
atom->image[m] = imageall[i];
}
}
}
}
/* ----------------------------------------------------------------------
parse optional parameters at end of PRD input line
------------------------------------------------------------------------- */
void PRD::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal prd command");
// set defaults
etol = 0.1;
ftol = 0.1;
maxiter = 40;
maxeval = 50;
temp_flag = 0;
char *str = "geom";
int n = strlen(str) + 1;
loop_setting = new char[n];
strcpy(loop_setting,str);
str = "gaussian";
n = strlen(str) + 1;
dist_setting = new char[n];
strcpy(dist_setting,str);
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"min") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal prd command");
etol = atof(arg[iarg+1]);
ftol = atof(arg[iarg+2]);
maxiter = atoi(arg[iarg+3]);
maxeval = atoi(arg[iarg+4]);
if (maxiter < 0) error->all(FLERR,"Illegal prd command");
iarg += 5;
} else if (strcmp(arg[iarg],"temp") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal prd command");
temp_flag = 1;
temp_dephase = atof(arg[iarg+1]);
if (temp_dephase <= 0.0) error->all(FLERR,"Illegal prd command");
iarg += 2;
} else if (strcmp(arg[iarg],"vel") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal prd command");
delete [] loop_setting;
delete [] dist_setting;
if (strcmp(arg[iarg+1],"all") == 0) loop_setting = NULL;
else if (strcmp(arg[iarg+1],"local") == 0) loop_setting = NULL;
else if (strcmp(arg[iarg+1],"geom") == 0) loop_setting = NULL;
else error->all(FLERR,"Illegal prd command");
int n = strlen(arg[iarg+1]) + 1;
loop_setting = new char[n];
strcpy(loop_setting,arg[iarg+1]);
if (strcmp(arg[iarg+2],"uniform") == 0) dist_setting = NULL;
else if (strcmp(arg[iarg+2],"gaussian") == 0) dist_setting = NULL;
else error->all(FLERR,"Illegal prd command");
n = strlen(arg[iarg+2]) + 1;
dist_setting = new char[n];
strcpy(dist_setting,arg[iarg+2]);
iarg += 3;
} else error->all(FLERR,"Illegal prd command");
}
}
diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp
index 3f4ba9c16..50e352ebd 100644
--- a/src/REPLICA/tad.cpp
+++ b/src/REPLICA/tad.cpp
@@ -1,1011 +1,1014 @@
/* ----------------------------------------------------------------------
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: Aidan Thompson (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "tad.h"
#include "universe.h"
#include "update.h"
#include "atom.h"
#include "domain.h"
#include "region.h"
#include "comm.h"
#include "velocity.h"
#include "integrate.h"
#include "min.h"
#include "neighbor.h"
#include "modify.h"
#include "neb.h"
#include "compute.h"
#include "fix.h"
#include "fix_event_tad.h"
#include "fix_store_state.h"
#include "force.h"
#include "pair.h"
#include "random_park.h"
#include "random_mars.h"
#include "output.h"
#include "dump.h"
#include "finish.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
TAD::TAD(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
TAD::~TAD()
{
memory->sfree(fix_event_list);
if (neb_logfilename != NULL) delete [] neb_logfilename;
delete [] min_style;
delete [] min_style_neb;
}
/* ----------------------------------------------------------------------
perform TAD simulation on root proc
other procs only used for NEB calcs
------------------------------------------------------------------------- */
void TAD::command(int narg, char **arg)
{
fix_event_list = NULL;
n_event_list = 0;
nmax_event_list = 0;
nmin_event_list = 10;
// error checks
if (domain->box_exist == 0)
error->all(FLERR,"Tad command before simulation box is defined");
if (universe->nworlds == 1)
error->all(FLERR,"Cannot use TAD with a single replica for NEB");
if (universe->nworlds != universe->nprocs)
error->all(FLERR,"Can only use TAD with 1-processor replicas for NEB");
if (atom->sortfreq > 0)
error->all(FLERR,"Cannot use TAD with atom_modify sort enabled for NEB");
if (atom->map_style == 0)
error->all(FLERR,"Cannot use TAD unless atom map exists for NEB");
if (narg < 7) error->universe_all(FLERR,"Illegal tad command");
nsteps = atoi(arg[0]);
t_event = atoi(arg[1]);
templo = atof(arg[2]);
temphi = atof(arg[3]);
delta_conf = atof(arg[4]);
tmax = atof(arg[5]);
char id_compute[strlen(arg[6])+1];
strcpy(id_compute,arg[6]);
options(narg-7,&arg[7]);
// total # of timesteps must be multiple of t_event
if (t_event <= 0) error->universe_all(FLERR,"Invalid t_event in tad command");
if (nsteps % t_event)
error->universe_all(FLERR,"TAD nsteps must be multiple of t_event");
if (delta_conf <= 0.0 || delta_conf >= 1.0)
error->universe_all(FLERR,"Invalid delta_conf in tad command");
if (tmax <= 0.0)
error->universe_all(FLERR,"Invalid tmax in tad command");
// deltconf = (ln(1/delta))/freq_min (timestep units)
deltconf = -log(delta_conf)*tmax/update->dt;
// local storage
int me_universe = universe->me;
int nprocs_universe = universe->nprocs;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
delta_beta = (1.0/templo - 1.0/temphi) / force->boltz;
ratio_beta = templo/temphi;
// create FixEventTAD object to store last event
int narg2 = 3;
char **args = new char*[narg2];
args[0] = (char *) "tad_event";
args[1] = (char *) "all";
args[2] = (char *) "EVENT/TAD";
modify->add_fix(narg2,args);
fix_event = (FixEventTAD *) modify->fix[modify->nfix-1];
delete [] args;
// create FixStoreState object to store revert state
narg2 = 13;
args = new char*[narg2];
args[0] = (char *) "tad_revert";
args[1] = (char *) "all";
args[2] = (char *) "store/state";
args[3] = (char *) "0";
args[4] = (char *) "x";
args[5] = (char *) "y";
args[6] = (char *) "z";
args[7] = (char *) "ix";
args[8] = (char *) "iy";
args[9] = (char *) "iz";
args[10] = (char *) "vx";
args[11] = (char *) "vy";
args[12] = (char *) "vz";
modify->add_fix(narg2,args);
fix_revert = (FixStoreState *) modify->fix[modify->nfix-1];
delete [] args;
// create Finish for timing output
finish = new Finish(lmp);
// assign FixEventTAD to event-detection compute
// necessary so it will know atom coords at last event
int icompute = modify->find_compute(id_compute);
if (icompute < 0) error->all(FLERR,"Could not find compute ID for TAD");
compute_event = modify->compute[icompute];
compute_event->reset_extra_compute_fix("tad_event");
// reset reneighboring criteria since will perform minimizations
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
if (me_universe == 0)
error->warning(FLERR,"Resetting reneighboring criteria during TAD");
}
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
// initialize TAD as if one long dynamics run
update->whichflag = 1;
update->nsteps = nsteps;
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + nsteps;
update->restrict_output = 1;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
lmp->init();
// set minimize style for quench
narg2 = 1;
args = new char*[narg2];
args[0] = min_style;
update->create_minimize(narg2,args);
delete [] args;
// init minimizer settings and minimizer itself
update->etol = etol;
update->ftol = ftol;
update->max_eval = maxeval;
update->minimize->init();
// perform TAD simulation
if (me_universe == 0 && universe->uscreen)
fprintf(universe->uscreen,"Setting up TAD ...\n");
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,
"Step CPU N M Status Barrier Margin t_lo delt_lo\n"
);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Step CPU N M Status Barrier Margin t_lo delt_lo\n"
);
}
ulogfile_lammps = universe->ulogfile;
uscreen_lammps = universe->uscreen;
ulogfile_neb = NULL;
uscreen_neb = NULL;
if (me_universe == 0 && neb_logfilename)
ulogfile_neb = fopen(neb_logfilename,"w");
// store hot state and quenched event, only on replica 0
// need this line if quench() does only setup_minimal()
// update->minimize->setup();
// This should work with if uncommented, but does not
// if (universe->iworld == 0) {
+
fix_event->store_state();
quench();
+
+ timer->init();
timer->barrier_start(TIME_LOOP);
time_start = timer->array[TIME_LOOP];
fix_event->store_event_tad(update->ntimestep);
log_event(0);
fix_event->restore_state();
// do full init/setup
update->whichflag = 1;
lmp->init();
update->integrate->setup();
// }
// main loop: look for events until out of time
// (1) dynamics, store state, quench, check event, restore state
// (2) if event, perform NEB, record in fix_event_list
// (3) if confident, pick earliest event
nbuild = ndanger = 0;
time_neb = time_dynamics = time_quench = time_comm = time_output = 0.0;
timer->barrier_start(TIME_LOOP);
time_start = timer->array[TIME_LOOP];
int confident_flag, event_flag;
if (universe->iworld == 0) {
while (update->ntimestep < update->endstep) {
// initialize list of possible events
initialize_event_list();
confident_flag = 0;
while (update->ntimestep < update->endstep) {
event_flag = 0;
while (update->ntimestep < update->endstep) {
dynamics();
fix_event->store_state();
quench();
event_flag = check_event();
MPI_Bcast(&event_flag,1,MPI_INT,0,universe->uworld);
if (event_flag) break;
// restore hot state
fix_event->restore_state();
// store hot state in revert
fix_revert->end_of_step();
}
if (!event_flag) break;
add_event();
perform_neb(n_event_list-1);
compute_tlo(n_event_list-1);
confident_flag = check_confidence();
MPI_Bcast(&confident_flag,1,MPI_INT,0,universe->uworld);
if (confident_flag) break;
if (universe->iworld == 0) revert();
}
if (!confident_flag) break;
perform_event(event_first);
// need to sync timestep with TAD
MPI_Bcast(&(update->ntimestep),1,MPI_INT,0,universe->uworld);
int restart_flag = 0;
if (output->restart_every && universe->iworld == 0)
if (fix_event->event_number % output->restart_every == 0)
restart_flag = 1;
// full init/setup since are starting after event
update->whichflag = 1;
lmp->init();
update->integrate->setup();
// write restart file of hot coords
if (restart_flag) {
timer->barrier_start(TIME_LOOP);
output->write_restart(update->ntimestep);
timer->barrier_stop(TIME_LOOP);
time_output += timer->array[TIME_LOOP];
}
}
} else {
while (update->ntimestep < update->endstep) {
confident_flag = 0;
while (update->ntimestep < update->endstep) {
event_flag = 0;
while (update->ntimestep < update->endstep) {
update->ntimestep += t_event;
MPI_Bcast(&event_flag,1,MPI_INT,0,universe->uworld);
if (event_flag) break;
}
if (!event_flag) break;
perform_neb(-1);
MPI_Bcast(&confident_flag,1,MPI_INT,0,universe->uworld);
if (confident_flag) break;
}
if (!confident_flag) break;
// need to sync timestep with TAD
MPI_Bcast(&(update->ntimestep),1,MPI_INT,0,universe->uworld);
}
}
// set total timers and counters so Finish() will process them
timer->array[TIME_LOOP] = time_start;
timer->barrier_stop(TIME_LOOP);
timer->array[TIME_PAIR] = time_neb;
timer->array[TIME_BOND] = time_dynamics;
timer->array[TIME_KSPACE] = time_quench;
timer->array[TIME_COMM] = time_comm;
timer->array[TIME_OUTPUT] = time_output;
neighbor->ncalls = nbuild;
neighbor->ndanger = ndanger;
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
}
if (me_universe == 0) fclose(ulogfile_neb);
finish->end(3);
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
update->restrict_output = 0;
// reset reneighboring criteria
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
delete finish;
modify->delete_fix("tad_event");
modify->delete_fix("tad_revert");
delete_event_list();
compute_event->reset_extra_compute_fix(NULL);
}
/* ----------------------------------------------------------------------
single short dynamics run
------------------------------------------------------------------------- */
void TAD::dynamics()
{
update->whichflag = 1;
update->nsteps = t_event;
lmp->init();
update->integrate->setup();
// this may be needed if don't do full init
//modify->addstep_compute_all(update->ntimestep);
int ncalls = neighbor->ncalls;
timer->barrier_start(TIME_LOOP);
update->integrate->run(t_event);
timer->barrier_stop(TIME_LOOP);
time_dynamics += timer->array[TIME_LOOP];
nbuild += neighbor->ncalls - ncalls;
ndanger += neighbor->ndanger;
update->integrate->cleanup();
finish->end(0);
}
/* ----------------------------------------------------------------------
quench minimization
------------------------------------------------------------------------- */
void TAD::quench()
{
bigint ntimestep_hold = update->ntimestep;
bigint endstep_hold = update->endstep;
// need to change whichflag so that minimize->setup() calling
// modify->setup() will call fix->min_setup()
update->whichflag = 2;
update->nsteps = maxiter;
update->endstep = update->laststep = update->firststep + maxiter;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many iterations");
// full init works
lmp->init();
update->minimize->setup();
// partial init does not work
//modify->addstep_compute_all(update->ntimestep);
//update->minimize->setup_minimal(1);
int ncalls = neighbor->ncalls;
timer->barrier_start(TIME_LOOP);
update->minimize->run(maxiter);
timer->barrier_stop(TIME_LOOP);
time_quench += timer->array[TIME_LOOP];
if (neighbor->ncalls == ncalls) quench_reneighbor = 0;
else quench_reneighbor = 1;
update->minimize->cleanup();
finish->end(1);
// reset timestep as if quench did not occur
// clear timestep storage from computes, since now invalid
update->ntimestep = ntimestep_hold;
update->endstep = update->laststep = endstep_hold;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
}
/* ----------------------------------------------------------------------
check for an event
return 0 if no event
return 1 if event
------------------------------------------------------------------------- */
int TAD::check_event()
{
int flag;
flag = 0;
if (compute_event->compute_scalar() > 0.0) flag = 1;
return flag;
}
/* ----------------------------------------------------------------------
universe proc 0 prints event info
------------------------------------------------------------------------- */
void TAD::log_event(int ievent)
{
timer->array[TIME_LOOP] = time_start;
if (universe->me == 0) {
double tfrac = 0.0;
if (universe->uscreen)
fprintf(universe->uscreen,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->event_number,ievent,
"E ",
fix_event->ebarrier,tfrac,
fix_event->tlo,deltfirst);
if (universe->ulogfile)
fprintf(universe->ulogfile,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->event_number,ievent,
"E ",
fix_event->ebarrier,tfrac,
fix_event->tlo,deltfirst);
}
// dump snapshot of quenched coords
// must reneighbor and compute forces before dumping
// addstep_compute_all insures eng/virial are calculated if needed
if (output->ndump && universe->iworld == 0) {
timer->barrier_start(TIME_LOOP);
modify->addstep_compute_all(update->ntimestep);
update->integrate->setup_minimal(1);
output->write_dump(update->ntimestep);
timer->barrier_stop(TIME_LOOP);
time_output += timer->array[TIME_LOOP];
}
}
/* ----------------------------------------------------------------------
parse optional parameters at end of TAD input line
------------------------------------------------------------------------- */
void TAD::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal tad command");
// set defaults
etol = 0.1;
ftol = 0.1;
maxiter = 40;
maxeval = 50;
etol_neb = 0.01;
ftol_neb = 0.01;
n1steps_neb = 100;
n2steps_neb = 100;
nevery_neb = 10;
min_style = new char[3];
strcpy(min_style,"cg");
min_style_neb = new char[9];
strcpy(min_style_neb,"quickmin");
neb_logfilename = NULL;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"min") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal tad command");
etol = atof(arg[iarg+1]);
ftol = atof(arg[iarg+2]);
maxiter = atoi(arg[iarg+3]);
maxeval = atoi(arg[iarg+4]);
if (maxiter < 0 || maxeval < 0 ||
etol < 0.0 || ftol < 0.0 )
error->all(FLERR,"Illegal tad command");
iarg += 5;
} else if (strcmp(arg[iarg],"neb") == 0) {
if (iarg+6 > narg) error->all(FLERR,"Illegal tad command");
etol_neb = atof(arg[iarg+1]);
ftol_neb = atof(arg[iarg+2]);
n1steps_neb = atoi(arg[iarg+3]);
n2steps_neb = atoi(arg[iarg+4]);
nevery_neb = atoi(arg[iarg+5]);
if (etol_neb < 0.0 || ftol_neb < 0.0 ||
n1steps_neb < 0 || n2steps_neb < 0 ||
nevery_neb < 0) error->all(FLERR,"Illegal tad command");
iarg += 6;
} else if (strcmp(arg[iarg],"min_style") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal tad command");
int n = strlen(arg[iarg+1]) + 1;
delete [] min_style;
min_style = new char[n];
strcpy(min_style,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"neb_style") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal tad command");
int n = strlen(arg[iarg+1]) + 1;
delete [] min_style_neb;
min_style_neb = new char[n];
strcpy(min_style_neb,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"neb_log") == 0) {
delete [] neb_logfilename;
if (iarg+2 > narg) error->all(FLERR,"Illegal tad command");
if (strcmp(arg[iarg+1],"none") == 0) neb_logfilename = NULL;
else {
int n = strlen(arg[iarg+1]) + 1;
neb_logfilename = new char[n];
strcpy(neb_logfilename,arg[iarg+1]);
}
iarg += 2;
} else error->all(FLERR,"Illegal tad command");
}
}
/* ----------------------------------------------------------------------
perform NEB calculation
------------------------------------------------------------------------- */
void TAD::perform_neb(int ievent)
{
double **x = atom->x;
int nlocal = atom->nlocal;
double *buf_final;
memory->create(buf_final,3*nlocal,"tad:buffinal");
// set system to quenched state of event ievent
if (universe->iworld == 0) {
fix_event_list[ievent]->restore_event();
int ii = 0;
for (int i = 0; i < nlocal; i++) {
buf_final[ii++] = x[i][0];
buf_final[ii++] = x[i][1];
buf_final[ii++] = x[i][2];
}
}
MPI_Bcast(buf_final,3*nlocal,MPI_DOUBLE,universe->root_proc[0],
universe->uworld);
double *buf_init;
memory->create(buf_init,3*nlocal,"tad:bufinit");
// set system to quenched state of fix_event
if (universe->iworld == 0) {
fix_event->restore_event();
int ii = 0;
for (int i = 0; i < nlocal; i++) {
buf_init[ii++] = x[i][0];
buf_init[ii++] = x[i][1];
buf_init[ii++] = x[i][2];
}
}
MPI_Bcast(buf_init,3*nlocal,MPI_DOUBLE,universe->root_proc[0],
universe->uworld);
// create FixNEB object to support NEB
int narg2 = 4;
char **args = new char*[narg2];
args[0] = (char *) "neb";
args[1] = (char *) "all";
args[2] = (char *) "neb";
char str[128];
args[3] = str;
double kspring = 1.0;
sprintf(args[3],"%f",kspring);
modify->add_fix(narg2,args);
fix_neb = (Fix *) modify->fix[modify->nfix-1];
delete [] args;
// switch minimize style to quickmin for NEB
narg2 = 1;
args = new char*[narg2];
args[0] = min_style_neb;
update->create_minimize(narg2,args);
delete [] args;
// create NEB object
neb = new NEB(lmp,etol_neb,ftol_neb,n1steps_neb,
n2steps_neb,nevery_neb,buf_init,buf_final);
// free up temporary arrays
memory->destroy(buf_init);
memory->destroy(buf_final);
- // Run NEB
+ // run NEB
int beginstep_hold = update->beginstep;
int endstep_hold = update->endstep;
int ntimestep_hold = update->ntimestep;
int nsteps_hold = update->nsteps;
if (universe->me == 0) {
universe->ulogfile = ulogfile_neb;
universe->uscreen = uscreen_neb;
}
// Had to bypass timer interface
// because timer->array is reset
// inside neb->run()
// timer->barrier_start(TIME_LOOP);
// neb->run();
// timer->barrier_stop(TIME_LOOP);
// time_neb += timer->array[TIME_LOOP];
MPI_Barrier(world);
double time_tmp = MPI_Wtime();
neb->run();
MPI_Barrier(world);
time_neb += MPI_Wtime() - time_tmp;
if (universe->me == 0) {
universe->ulogfile = ulogfile_lammps;
universe->uscreen = uscreen_lammps;
}
- // Extract barrier energy from NEB
+ // extract barrier energy from NEB
if (universe->iworld == 0)
fix_event_list[ievent]->ebarrier = neb->ebf;
update->beginstep = update->firststep = beginstep_hold;
update->endstep = update->laststep = endstep_hold;
update->ntimestep = ntimestep_hold;
update->nsteps = nsteps_hold;
// switch minimize style back for quench
narg2 = 1;
args = new char*[narg2];
args[0] = min_style;
update->create_minimize(narg2,args);
update->etol = etol;
update->ftol = ftol;
delete [] args;
- // Clean up
+ // clean up
modify->delete_fix("neb");
delete neb;
}
/* ----------------------------------------------------------------------
check if confidence criterion for tstop is satisfied
return 0 if not satisfied
return 1 if satisfied
------------------------------------------------------------------------- */
int TAD::check_confidence()
{
int flag;
// update stopping time
deltstop = deltconf*pow(deltfirst/deltconf, ratio_beta);
flag = 0;
if (deltstop < update->ntimestep - fix_event->event_timestep) flag = 1;
return flag;
}
/* ----------------------------------------------------------------------
reflect back in to starting state
------------------------------------------------------------------------- */
void TAD::revert()
{
double **x = atom->x;
double **v = atom->v;
int *image = atom->image;
int nlocal = atom->nlocal;
double **array_atom = fix_revert->array_atom;
for (int i = 0; i < nlocal; i++) {
x[i][0] = array_atom[i][0];
x[i][1] = array_atom[i][1];
x[i][2] = array_atom[i][2];
image[i] = ((int(array_atom[i][5]) + 512 & 1023) << 20) |
((int(array_atom[i][4]) + 512 & 1023) << 10) |
(int(array_atom[i][3]) + 512 & 1023);
v[i][0] = -array_atom[i][6];
v[i][1] = -array_atom[i][7];
v[i][2] = -array_atom[i][8];
}
}
/* ----------------------------------------------------------------------
Initialize list of possible events
------------------------------------------------------------------------- */
void TAD::initialize_event_list() {
// First delete old events, if any
delete_event_list();
// Create new list
n_event_list = 0;
grow_event_list(nmin_event_list);
}
/* ----------------------------------------------------------------------
Delete list of possible events
------------------------------------------------------------------------- */
void TAD::delete_event_list() {
for (int i = 0; i < n_event_list; i++) {
char str[128];
sprintf(str,"tad_event_%d",i);
modify->delete_fix(str);
}
memory->sfree(fix_event_list);
fix_event_list = NULL;
n_event_list = 0;
nmax_event_list = 0;
}
/* ----------------------------------------------------------------------
add event
------------------------------------------------------------------------- */
void TAD::add_event()
{
// create FixEventTAD object to store possible event
int narg = 3;
char **args = new char*[narg];
char str[128];
sprintf(str,"tad_event_%d",n_event_list);
args[0] = str;
args[1] = (char *) "all";
args[2] = (char *) "EVENT/TAD";
modify->add_fix(narg,args);
if (n_event_list == nmax_event_list)
grow_event_list(nmax_event_list+nmin_event_list);
n_event_list += 1;
int ievent = n_event_list-1;
fix_event_list[ievent] = (FixEventTAD *) modify->fix[modify->nfix-1];
// store quenched state for new event
fix_event_list[ievent]->store_event_tad(update->ntimestep);
// store hot state for new event
fix_event->restore_state();
fix_event_list[ievent]->store_state();
// string clean-up
delete [] args;
}
/* ----------------------------------------------------------------------
compute cold time for event ievent
------------------------------------------------------------------------- */
void TAD::compute_tlo(int ievent)
{
double deltlo,delthi,ebarrier;
ebarrier = fix_event_list[ievent]->ebarrier;
delthi = fix_event_list[ievent]->event_timestep
- fix_event->event_timestep;
deltlo = delthi*exp(ebarrier*delta_beta);
fix_event_list[ievent]->tlo = fix_event->tlo + deltlo;
// update first event
char* statstr = "D ";
if (ievent == 0) {
deltfirst = deltlo;
event_first = ievent;
statstr = "DF";
} else if (deltlo < deltfirst) {
deltfirst = deltlo;
event_first = ievent;
statstr = "DF";
}
// first-replica output about each event
timer->array[TIME_LOOP] = time_start;
if (universe->me == 0) {
double tfrac = 0.0;
if (ievent > 0) tfrac = delthi/deltstop;
if (universe->uscreen)
fprintf(universe->uscreen,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event_list[ievent]->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->event_number,
ievent,statstr,ebarrier,tfrac,
fix_event->tlo,deltlo);
if (universe->ulogfile)
fprintf(universe->ulogfile,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event_list[ievent]->event_timestep,
timer->elapsed(TIME_LOOP),
fix_event->event_number,
ievent,statstr,ebarrier,tfrac,
fix_event->tlo,deltlo);
}
}
/* ----------------------------------------------------------------------
perform event
------------------------------------------------------------------------- */
void TAD::perform_event(int ievent)
{
// reset timestep to that of event
update->ntimestep = fix_event_list[ievent]->event_timestep;
// Copy event to current event
// Should really use copy constructor for this
fix_event->tlo = fix_event_list[ievent]->tlo;
fix_event->ebarrier = fix_event_list[ievent]->ebarrier;
fix_event->event_number++;
fix_event->event_timestep = update->ntimestep;
fix_event_list[ievent]->restore_event();
fix_event->store_event_tad(fix_event_list[ievent]->event_timestep);
// output stats and dump for quenched state
log_event(ievent);
// load and store hot state
fix_event_list[ievent]->restore_state();
fix_event->store_state();
}
/* ----------------------------------------------------------------------
Allocate list of pointers to events
------------------------------------------------------------------------- */
void TAD::grow_event_list(int nmax) {
if (nmax_event_list > nmax) return;
fix_event_list = (FixEventTAD **)
memory->srealloc(fix_event_list,nmax*sizeof(FixEventTAD *),"tad:eventlist");
nmax_event_list = nmax;
}
diff --git a/src/REPLICA/temper.cpp b/src/REPLICA/temper.cpp
index d95fb3d89..cd6c3e8e8 100644
--- a/src/REPLICA/temper.cpp
+++ b/src/REPLICA/temper.cpp
@@ -1,360 +1,363 @@
/* ----------------------------------------------------------------------
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: Mark Sears (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "temper.h"
#include "universe.h"
#include "domain.h"
#include "atom.h"
#include "update.h"
#include "integrate.h"
#include "modify.h"
#include "compute.h"
#include "force.h"
#include "output.h"
#include "thermo.h"
#include "fix.h"
#include "random_park.h"
#include "finish.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
// #define TEMPER_DEBUG 1
/* ---------------------------------------------------------------------- */
Temper::Temper(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
Temper::~Temper()
{
MPI_Comm_free(&roots);
if (ranswap) delete ranswap;
delete ranboltz;
delete [] set_temp;
delete [] temp2world;
delete [] world2temp;
delete [] world2root;
}
/* ----------------------------------------------------------------------
perform tempering with inter-world swaps
------------------------------------------------------------------------- */
void Temper::command(int narg, char **arg)
{
if (universe->nworlds == 1)
error->all(FLERR,"Must have more than one processor partition to temper");
if (domain->box_exist == 0)
error->all(FLERR,"Temper command before simulation box is defined");
- if (narg != 6 && narg != 7) error->universe_all(FLERR,"Illegal temper command");
+ if (narg != 6 && narg != 7)
+ error->universe_all(FLERR,"Illegal temper command");
int nsteps = atoi(arg[0]);
nevery = atoi(arg[1]);
double temp = atof(arg[2]);
for (whichfix = 0; whichfix < modify->nfix; whichfix++)
if (strcmp(arg[3],modify->fix[whichfix]->id) == 0) break;
if (whichfix == modify->nfix)
error->universe_all(FLERR,"Tempering fix ID is not defined");
seed_swap = atoi(arg[4]);
seed_boltz = atoi(arg[5]);
my_set_temp = universe->iworld;
if (narg == 7) my_set_temp = atoi(arg[6]);
// swap frequency must evenly divide total # of timesteps
- if (nevery == 0) error->universe_all(FLERR,"Invalid frequency in temper command");
+ if (nevery == 0)
+ error->universe_all(FLERR,"Invalid frequency in temper command");
nswaps = nsteps/nevery;
if (nswaps*nevery != nsteps)
error->universe_all(FLERR,"Non integer # of swaps in temper command");
// fix style must be appropriate for temperature control
if ((strcmp(modify->fix[whichfix]->style,"nvt") != 0) &&
(strcmp(modify->fix[whichfix]->style,"langevin") != 0) &&
(strcmp(modify->fix[whichfix]->style,"temp/berendsen") != 0) &&
(strcmp(modify->fix[whichfix]->style,"temp/rescale") != 0))
error->universe_all(FLERR,"Tempering temperature fix is not valid");
// setup for long tempering run
update->whichflag = 1;
update->nsteps = nsteps;
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + nsteps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
lmp->init();
// local storage
me_universe = universe->me;
MPI_Comm_rank(world,&me);
nworlds = universe->nworlds;
iworld = universe->iworld;
boltz = force->boltz;
// pe_compute = ptr to thermo_pe compute
// notify compute it will be called at first swap
int id = modify->find_compute("thermo_pe");
if (id < 0) error->all(FLERR,"Tempering could not find thermo_pe compute");
Compute *pe_compute = modify->compute[id];
pe_compute->addstep(update->ntimestep + nevery);
// create MPI communicator for root proc from each world
int color;
if (me == 0) color = 0;
else color = 1;
MPI_Comm_split(universe->uworld,color,0,&roots);
// RNGs for swaps and Boltzmann test
// warm up Boltzmann RNG
if (seed_swap) ranswap = new RanPark(lmp,seed_swap);
else ranswap = NULL;
ranboltz = new RanPark(lmp,seed_boltz + me_universe);
for (int i = 0; i < 100; i++) ranboltz->uniform();
// world2root[i] = global proc that is root proc of world i
world2root = new int[nworlds];
if (me == 0)
MPI_Allgather(&me_universe,1,MPI_INT,world2root,1,MPI_INT,roots);
MPI_Bcast(world2root,nworlds,MPI_INT,0,world);
// create static list of set temperatures
// allgather tempering arg "temp" across root procs
// bcast from each root to other procs in world
set_temp = new double[nworlds];
if (me == 0) MPI_Allgather(&temp,1,MPI_DOUBLE,set_temp,1,MPI_DOUBLE,roots);
MPI_Bcast(set_temp,nworlds,MPI_DOUBLE,0,world);
// create world2temp only on root procs from my_set_temp
// create temp2world on root procs from world2temp,
// then bcast to all procs within world
world2temp = new int[nworlds];
temp2world = new int[nworlds];
if (me == 0) {
MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots);
for (int i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i;
}
MPI_Bcast(temp2world,nworlds,MPI_INT,0,world);
// if restarting tempering, reset temp target of Fix to current my_set_temp
if (narg == 7) {
double new_temp = set_temp[my_set_temp];
modify->fix[whichfix]->reset_target(new_temp);
}
// setup tempering runs
int i,which,partner,swap,partner_set_temp,partner_world;
double pe,pe_partner,boltz_factor,new_temp;
MPI_Status status;
if (me_universe == 0 && universe->uscreen)
fprintf(universe->uscreen,"Setting up tempering ...\n");
update->integrate->setup();
if (me_universe == 0) {
if (universe->uscreen) {
fprintf(universe->uscreen,"Step");
for (int i = 0; i < nworlds; i++)
fprintf(universe->uscreen," T%d",i);
fprintf(universe->uscreen,"\n");
}
if (universe->ulogfile) {
fprintf(universe->ulogfile,"Step");
for (int i = 0; i < nworlds; i++)
fprintf(universe->ulogfile," T%d",i);
fprintf(universe->ulogfile,"\n");
}
print_status();
}
+ timer->init();
timer->barrier_start(TIME_LOOP);
for (int iswap = 0; iswap < nswaps; iswap++) {
// run for nevery timesteps
update->integrate->run(nevery);
// compute PE
// notify compute it will be called at next swap
pe = pe_compute->compute_scalar();
pe_compute->addstep(update->ntimestep + nevery);
// which = which of 2 kinds of swaps to do (0,1)
if (!ranswap) which = iswap % 2;
else if (ranswap->uniform() < 0.5) which = 0;
else which = 1;
// partner_set_temp = which set temp I am partnering with for this swap
if (which == 0) {
if (my_set_temp % 2 == 0) partner_set_temp = my_set_temp + 1;
else partner_set_temp = my_set_temp - 1;
} else {
if (my_set_temp % 2 == 1) partner_set_temp = my_set_temp + 1;
else partner_set_temp = my_set_temp - 1;
}
// partner = proc ID to swap with
// if partner = -1, then I am not a proc that swaps
partner = -1;
if (me == 0 && partner_set_temp >= 0 && partner_set_temp < nworlds) {
partner_world = temp2world[partner_set_temp];
partner = world2root[partner_world];
}
// swap with a partner, only root procs in each world participate
// hi proc sends PE to low proc
// lo proc make Boltzmann decision on whether to swap
// lo proc communicates decision back to hi proc
swap = 0;
if (partner != -1) {
if (me_universe > partner)
MPI_Send(&pe,1,MPI_DOUBLE,partner,0,universe->uworld);
else
MPI_Recv(&pe_partner,1,MPI_DOUBLE,partner,0,universe->uworld,&status);
if (me_universe < partner) {
boltz_factor = (pe - pe_partner) *
(1.0/(boltz*set_temp[my_set_temp]) -
1.0/(boltz*set_temp[partner_set_temp]));
if (boltz_factor >= 0.0) swap = 1;
else if (ranboltz->uniform() < exp(boltz_factor)) swap = 1;
}
if (me_universe < partner)
MPI_Send(&swap,1,MPI_INT,partner,0,universe->uworld);
else
MPI_Recv(&swap,1,MPI_INT,partner,0,universe->uworld,&status);
#ifdef TEMPER_DEBUG
if (me_universe < partner)
printf("SWAP %d & %d: yes = %d,Ts = %d %d, PEs = %g %g, Bz = %g %g\n",
me_universe,partner,swap,my_set_temp,partner_set_temp,
pe,pe_partner,boltz_factor,exp(boltz_factor));
#endif
}
// bcast swap result to other procs in my world
MPI_Bcast(&swap,1,MPI_INT,0,world);
// rescale kinetic energy via velocities if move is accepted
if (swap) scale_velocities(partner_set_temp,my_set_temp);
// if my world swapped, all procs in world reset temp target of Fix
if (swap) {
new_temp = set_temp[partner_set_temp];
modify->fix[whichfix]->reset_target(new_temp);
}
// update my_set_temp and temp2world on every proc
// root procs update their value if swap took place
// allgather across root procs
// bcast within my world
if (swap) my_set_temp = partner_set_temp;
if (me == 0) {
MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots);
for (i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i;
}
MPI_Bcast(temp2world,nworlds,MPI_INT,0,world);
// print out current swap status
if (me_universe == 0) print_status();
}
timer->barrier_stop(TIME_LOOP);
update->integrate->cleanup();
Finish finish(lmp);
finish.end(1);
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
}
/* ----------------------------------------------------------------------
scale kinetic energy via velocities a la Sugita
------------------------------------------------------------------------- */
void Temper::scale_velocities(int t_partner, int t_me)
{
double sfactor = sqrt(set_temp[t_partner]/set_temp[t_me]);
double **v = atom->v;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
v[i][0] = v[i][0]*sfactor;
v[i][1] = v[i][1]*sfactor;
v[i][2] = v[i][2]*sfactor;
}
}
/* ----------------------------------------------------------------------
proc 0 prints current tempering status
------------------------------------------------------------------------- */
void Temper::print_status()
{
if (universe->uscreen) {
fprintf(universe->uscreen,BIGINT_FORMAT,update->ntimestep);
for (int i = 0; i < nworlds; i++)
fprintf(universe->uscreen," %d",world2temp[i]);
fprintf(universe->uscreen,"\n");
}
if (universe->ulogfile) {
fprintf(universe->ulogfile,BIGINT_FORMAT,update->ntimestep);
for (int i = 0; i < nworlds; i++)
fprintf(universe->ulogfile," %d",world2temp[i]);
fprintf(universe->ulogfile,"\n");
fflush(universe->ulogfile);
}
}
diff --git a/src/REPLICA/verlet_split.cpp b/src/REPLICA/verlet_split.cpp
new file mode 100644
index 000000000..e84cbc81e
--- /dev/null
+++ b/src/REPLICA/verlet_split.cpp
@@ -0,0 +1,508 @@
+/* -------------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Yuxing Peng and Chris Knight (U Chicago)
+------------------------------------------------------------------------- */
+
+#include "string.h"
+#include "verlet_split.h"
+#include "universe.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "comm.h"
+#include "atom.h"
+#include "atom_vec.h"
+#include "force.h"
+#include "pair.h"
+#include "bond.h"
+#include "angle.h"
+#include "dihedral.h"
+#include "improper.h"
+#include "kspace.h"
+#include "output.h"
+#include "update.h"
+#include "modify.h"
+#include "timer.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+VerletSplit::VerletSplit(LAMMPS *lmp, int narg, char **arg) :
+ Verlet(lmp, narg, arg)
+{
+ // error checks on partitions
+
+ if (universe->nworlds != 2)
+ error->universe_all(FLERR,"Verlet/split requires 2 partitions");
+ if (universe->procs_per_world[0] % universe->procs_per_world[1])
+ error->universe_all(FLERR,"Verlet/split requires Rspace partition "
+ "size be multiple of Kspace partition size");
+
+ // master = 1 for Rspace procs, 0 for Kspace procs
+
+ if (universe->iworld == 0) master = 1;
+ else master = 0;
+
+ ratio = universe->procs_per_world[0] / universe->procs_per_world[1];
+
+ // Kspace root proc broadcasts info about Kspace proc layout to Rspace procs
+
+ int kspace_procgrid[3];
+
+ if (universe->me == universe->root_proc[1]) {
+ kspace_procgrid[0] = comm->procgrid[0];
+ kspace_procgrid[1] = comm->procgrid[1];
+ kspace_procgrid[2] = comm->procgrid[2];
+ }
+ MPI_Bcast(kspace_procgrid,3,MPI_INT,universe->root_proc[1],universe->uworld);
+
+ int ***kspace_grid2proc;
+ memory->create(kspace_grid2proc,kspace_procgrid[0],
+ kspace_procgrid[1],kspace_procgrid[2],
+ "verlet/split:kspace_grid2proc");
+
+ if (universe->me == universe->root_proc[1]) {
+ for (int i = 0; i < comm->procgrid[0]; i++)
+ for (int j = 0; j < comm->procgrid[1]; j++)
+ for (int k = 0; k < comm->procgrid[2]; k++)
+ kspace_grid2proc[i][j][k] = comm->grid2proc[i][j][k];
+ }
+ MPI_Bcast(&kspace_grid2proc[0][0][0],
+ kspace_procgrid[0]*kspace_procgrid[1]*kspace_procgrid[2],MPI_INT,
+ universe->root_proc[1],universe->uworld);
+
+ // Rspace partition must be multiple of Kspace partition in each dim
+ // so atoms of one Kspace proc coincide with atoms of several Rspace procs
+
+ if (master) {
+ int flag = 0;
+ if (comm->procgrid[0] % kspace_procgrid[0]) flag = 1;
+ if (comm->procgrid[1] % kspace_procgrid[1]) flag = 1;
+ if (comm->procgrid[2] % kspace_procgrid[2]) flag = 1;
+ if (flag)
+ error->one(FLERR,
+ "Verlet/split requires Rspace partition layout be "
+ "multiple of Kspace partition layout in each dim");
+ }
+
+ // block = 1 Kspace proc with set of Rspace procs it overlays
+ // me_block = 0 for Kspace proc
+ // me_block = 1 to ratio for Rspace procs
+ // block = MPI communicator for that set of procs
+
+ int iblock,key;
+
+ if (!master) {
+ iblock = comm->me;
+ key = 0;
+ } else {
+ int kpx = comm->myloc[0] / (comm->procgrid[0]/kspace_procgrid[0]);
+ int kpy = comm->myloc[1] / (comm->procgrid[1]/kspace_procgrid[1]);
+ int kpz = comm->myloc[2] / (comm->procgrid[2]/kspace_procgrid[2]);
+ iblock = kspace_grid2proc[kpx][kpy][kpz];
+ key = 1;
+ }
+
+ MPI_Comm_split(universe->uworld,iblock,key,&block);
+ MPI_Comm_rank(block,&me_block);
+
+ // output block groupings to universe screen/logfile
+ // bmap is ordered by block and then by proc within block
+
+ int *bmap = new int[universe->nprocs];
+ for (int i = 0; i < universe->nprocs; i++) bmap[i] = -1;
+ bmap[iblock*(ratio+1)+me_block] = universe->me;
+
+ int *bmapall = new int[universe->nprocs];
+ MPI_Allreduce(bmap,bmapall,universe->nprocs,MPI_INT,MPI_MAX,universe->uworld);
+
+ if (universe->me == 0) {
+ if (universe->uscreen) {
+ fprintf(universe->uscreen,"Rspace/Kspace procs in each block:\n");
+ int m = 0;
+ for (int i = 0; i < universe->nprocs/(ratio+1); i++) {
+ fprintf(universe->uscreen," block %d:",i);
+ int kspace_proc = bmapall[m];
+ for (int j = 1; j <= ratio; j++)
+ fprintf(universe->uscreen," %d",bmapall[m+j]);
+ fprintf(universe->uscreen," %d\n",kspace_proc);
+ /*
+ kspace_proc = bmapall[m];
+ for (int j = 1; j <= ratio; j++)
+ fprintf(universe->uscreen," %d",
+ universe->proc2original[bmapall[m+j]]);
+ fprintf(universe->uscreen," %d\n",universe->proc2original[kspace_proc]);
+ */
+ m += ratio + 1;
+ }
+ }
+ if (universe->ulogfile) {
+ fprintf(universe->ulogfile,"Rspace/Kspace procs in each block:\n");
+ int m = 0;
+ for (int i = 0; i < universe->nprocs/(ratio+1); i++) {
+ fprintf(universe->ulogfile," block %d:",i);
+ int kspace_proc = bmapall[m++];
+ for (int j = 1; j <= ratio; j++)
+ fprintf(universe->ulogfile," %d",bmapall[m++]);
+ fprintf(universe->ulogfile," %d\n",kspace_proc);
+ }
+ }
+ }
+
+ memory->destroy(kspace_grid2proc);
+ delete [] bmap;
+ delete [] bmapall;
+
+ // size/disp = vectors for MPI gather/scatter within block
+
+ qsize = new int[ratio+1];
+ qdisp = new int[ratio+1];
+ xsize = new int[ratio+1];
+ xdisp = new int[ratio+1];
+
+ // f_kspace = Rspace copy of Kspace forces
+ // allocate dummy version for Kspace partition
+
+ maxatom = 0;
+ f_kspace = NULL;
+ if (!master) memory->create(f_kspace,1,1,"verlet/split:f_kspace");
+}
+
+/* ---------------------------------------------------------------------- */
+
+VerletSplit::~VerletSplit()
+{
+ delete [] qsize;
+ delete [] qdisp;
+ delete [] xsize;
+ delete [] xdisp;
+ memory->destroy(f_kspace);
+ MPI_Comm_free(&block);
+}
+
+/* ----------------------------------------------------------------------
+ initialization before run
+------------------------------------------------------------------------- */
+
+void VerletSplit::init()
+{
+ if (!force->kspace && comm->me == 0)
+ error->warning(FLERR,"No Kspace calculation with verlet/split");
+
+ if (force->kspace_match("tip4p",0)) tip4p_flag = 1;
+ else tip4p_flag = 0;
+
+ Verlet::init();
+}
+
+/* ----------------------------------------------------------------------
+ run for N steps
+ master partition does everything but Kspace
+ servant partition does just Kspace
+ communicate back and forth every step:
+ atom coords from master -> servant
+ kspace forces from servant -> master
+ also box bounds from master -> servant if necessary
+------------------------------------------------------------------------- */
+
+void VerletSplit::run(int n)
+{
+ int nflag,ntimestep,sortflag;
+
+ // sync both partitions before start timer
+
+ MPI_Barrier(universe->uworld);
+ timer->init();
+ timer->barrier_start(TIME_LOOP);
+
+ // setup initial Rspace <-> Kspace comm params
+
+ rk_setup();
+
+ // flags for timestepping iterations
+
+ int n_post_integrate = modify->n_post_integrate;
+ int n_pre_exchange = modify->n_pre_exchange;
+ int n_pre_neighbor = modify->n_pre_neighbor;
+ int n_pre_force = modify->n_pre_force;
+ int n_post_force = modify->n_post_force;
+ int n_end_of_step = modify->n_end_of_step;
+
+ if (atom->sortfreq > 0) sortflag = 1;
+ else sortflag = 0;
+
+ for (int i = 0; i < n; i++) {
+
+ ntimestep = ++update->ntimestep;
+ ev_set(ntimestep);
+
+ // initial time integration
+
+ if (master) {
+ modify->initial_integrate(vflag);
+ if (n_post_integrate) modify->post_integrate();
+ }
+
+ // regular communication vs neighbor list rebuild
+
+ if (master) nflag = neighbor->decide();
+ MPI_Bcast(&nflag,1,MPI_INT,1,block);
+
+ if (master) {
+ if (nflag == 0) {
+ timer->stamp();
+ comm->forward_comm();
+ timer->stamp(TIME_COMM);
+ } else {
+ if (n_pre_exchange) modify->pre_exchange();
+ if (triclinic) domain->x2lamda(atom->nlocal);
+ domain->pbc();
+ if (domain->box_change) {
+ domain->reset_box();
+ comm->setup();
+ if (neighbor->style) neighbor->setup_bins();
+ }
+ timer->stamp();
+ comm->exchange();
+ if (sortflag && ntimestep >= atom->nextsort) atom->sort();
+ comm->borders();
+ if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
+ timer->stamp(TIME_COMM);
+ if (n_pre_neighbor) modify->pre_neighbor();
+ neighbor->build();
+ timer->stamp(TIME_NEIGHBOR);
+ }
+ }
+
+ // if reneighboring occurred, re-setup Rspace <-> Kspace comm params
+ // comm Rspace atom coords to Kspace procs
+
+ if (nflag) rk_setup();
+ r2k_comm();
+
+ // force computations
+
+ force_clear();
+
+ if (master) {
+ if (n_pre_force) modify->pre_force(vflag);
+
+ timer->stamp();
+ if (force->pair) {
+ force->pair->compute(eflag,vflag);
+ timer->stamp(TIME_PAIR);
+ }
+
+ if (atom->molecular) {
+ if (force->bond) force->bond->compute(eflag,vflag);
+ if (force->angle) force->angle->compute(eflag,vflag);
+ if (force->dihedral) force->dihedral->compute(eflag,vflag);
+ if (force->improper) force->improper->compute(eflag,vflag);
+ timer->stamp(TIME_BOND);
+ }
+
+ if (force->newton) {
+ comm->reverse_comm();
+ timer->stamp(TIME_COMM);
+ }
+
+ } else {
+ if (force->kspace) {
+ timer->stamp();
+ force->kspace->compute(eflag,vflag);
+ timer->stamp(TIME_KSPACE);
+ }
+
+ // TIP4P PPPM puts forces on ghost atoms, so must reverse_comm()
+
+ if (tip4p_flag && force->newton) {
+ comm->reverse_comm();
+ timer->stamp(TIME_COMM);
+ }
+ }
+
+ // comm and sum Kspace forces back to Rspace procs
+
+ k2r_comm();
+
+ // force modifications, final time integration, diagnostics
+ // all output
+
+ if (master) {
+ if (n_post_force) modify->post_force(vflag);
+ modify->final_integrate();
+ if (n_end_of_step) modify->end_of_step();
+
+ if (ntimestep == output->next) {
+ timer->stamp();
+ output->write(ntimestep);
+ timer->stamp(TIME_OUTPUT);
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ setup params for Rspace <-> Kspace communication
+ called initially and after every reneighbor
+ also communcicate atom charges from Rspace to KSpace since static
+------------------------------------------------------------------------- */
+
+void VerletSplit::rk_setup()
+{
+ // grow f_kspace array on master procs if necessary
+
+ if (master) {
+ if (atom->nlocal > maxatom) {
+ memory->destroy(f_kspace);
+ maxatom = atom->nmax;
+ memory->create(f_kspace,maxatom,3,"verlet/split:f_kspace");
+ }
+ }
+
+ // qsize = # of atoms owned by each master proc in block
+
+ int n = 0;
+ if (master) n = atom->nlocal;
+ MPI_Gather(&n,1,MPI_INT,qsize,1,MPI_INT,0,block);
+
+ // setup qdisp, xsize, xdisp based on qsize
+ // only needed by Kspace proc
+ // set Kspace nlocal to sum of Rspace nlocals
+ // insure Kspace atom arrays are large enough
+
+ if (!master) {
+ qsize[0] = qdisp[0] = xsize[0] = xdisp[0] = 0;
+ for (int i = 1; i <= ratio; i++) {
+ qdisp[i] = qdisp[i-1]+qsize[i-1];
+ xsize[i] = 3*qsize[i];
+ xdisp[i] = xdisp[i-1]+xsize[i-1];
+ }
+
+ atom->nlocal = qdisp[ratio] + qsize[ratio];
+ while (atom->nmax <= atom->nlocal) atom->avec->grow(0);
+ atom->nghost = 0;
+ }
+
+ // one-time gather of Rspace atom charges to Kspace proc
+
+ MPI_Gatherv(atom->q,n,MPI_DOUBLE,atom->q,qsize,qdisp,MPI_DOUBLE,0,block);
+
+ // for TIP4P also need to send atom type and tag
+ // KSpace procs need to acquire ghost atoms and map all their atoms
+ // map_clear() call is in lieu of comm->exchange() which performs map_clear
+ // borders() call acquires ghost atoms and maps them
+
+ if (tip4p_flag) {
+ MPI_Gatherv(atom->type,n,MPI_INT,atom->type,qsize,qdisp,MPI_INT,0,block);
+ MPI_Gatherv(atom->tag,n,MPI_INT,atom->tag,qsize,qdisp,MPI_INT,0,block);
+ if (!master) {
+ if (triclinic) domain->x2lamda(atom->nlocal);
+ if (domain->box_change) comm->setup();
+ timer->stamp();
+ atom->map_clear();
+ comm->borders();
+ if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
+ timer->stamp(TIME_COMM);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ communicate Rspace atom coords to Kspace
+ also eflag,vflag and box bounds if needed
+------------------------------------------------------------------------- */
+
+void VerletSplit::r2k_comm()
+{
+ MPI_Status status;
+
+ int n = 0;
+ if (master) n = atom->nlocal;
+ MPI_Gatherv(atom->x[0],n*3,MPI_DOUBLE,atom->x[0],xsize,xdisp,
+ MPI_DOUBLE,0,block);
+
+ // send eflag,vflag from Rspace to Kspace
+
+ if (me_block == 1) {
+ int flags[2];
+ flags[0] = eflag; flags[1] = vflag;
+ MPI_Send(flags,2,MPI_INT,0,0,block);
+ } else if (!master) {
+ int flags[2];
+ MPI_Recv(flags,2,MPI_DOUBLE,1,0,block,&status);
+ eflag = flags[0]; vflag = flags[1];
+ }
+
+ // send box bounds from Rspace to Kspace if simulation box is dynamic
+
+ if (domain->box_change) {
+ if (me_block == 1) {
+ MPI_Send(domain->boxlo,3,MPI_DOUBLE,0,0,block);
+ MPI_Send(domain->boxhi,3,MPI_DOUBLE,0,0,block);
+ } else if (!master) {
+ MPI_Recv(domain->boxlo,3,MPI_DOUBLE,1,0,block,&status);
+ MPI_Recv(domain->boxhi,3,MPI_DOUBLE,1,0,block,&status);
+ domain->set_global_box();
+ domain->set_local_box();
+ force->kspace->setup();
+ }
+ }
+
+ // for TIP4P, Kspace partition needs to update its ghost atoms
+
+ if (tip4p_flag && !master) {
+ timer->stamp();
+ comm->forward_comm();
+ timer->stamp(TIME_COMM);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ communicate and sum Kspace atom forces back to Rspace
+------------------------------------------------------------------------- */
+
+void VerletSplit::k2r_comm()
+{
+ if (eflag) MPI_Bcast(&force->kspace->energy,1,MPI_DOUBLE,0,block);
+ if (vflag) MPI_Bcast(force->kspace->virial,6,MPI_DOUBLE,0,block);
+
+ int n = 0;
+ if (master) n = atom->nlocal;
+ MPI_Scatterv(atom->f[0],xsize,xdisp,MPI_DOUBLE,
+ f_kspace[0],n*3,MPI_DOUBLE,0,block);
+
+ if (master) {
+ double **f = atom->f;
+ int nlocal = atom->nlocal;
+ for (int i = 0; i < nlocal; i++) {
+ f[i][0] += f_kspace[i][0];
+ f[i][1] += f_kspace[i][1];
+ f[i][2] += f_kspace[i][2];
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ memory usage of Kspace force array on master procs
+------------------------------------------------------------------------- */
+
+bigint VerletSplit::memory_usage()
+{
+ bigint bytes = maxatom*3 * sizeof(double);
+ return bytes;
+}
diff --git a/src/REPLICA/verlet_split.h b/src/REPLICA/verlet_split.h
new file mode 100644
index 000000000..080a6057e
--- /dev/null
+++ b/src/REPLICA/verlet_split.h
@@ -0,0 +1,54 @@
+/* -------------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef INTEGRATE_CLASS
+
+IntegrateStyle(verlet/split,VerletSplit)
+
+#else
+
+#ifndef LMP_VERLET_SPLIT_H
+#define LMP_VERLET_SPLIT_H
+
+#include "verlet.h"
+
+namespace LAMMPS_NS {
+
+class VerletSplit : public Verlet {
+ public:
+ VerletSplit(class LAMMPS *, int, char **);
+ ~VerletSplit();
+ void init();
+ void run(int);
+ bigint memory_usage();
+
+ private:
+ int master; // 1 if an Rspace proc, 0 if Kspace
+ int me_block; // proc ID within Rspace/Kspace block
+ int ratio; // ratio of Rspace procs to Kspace procs
+ int *qsize,*qdisp,*xsize,*xdisp; // MPI gather/scatter params for block comm
+ MPI_Comm block; // communicator within one block
+ int tip4p_flag; // 1 if PPPM/tip4p so do extra comm
+
+ double **f_kspace; // copy of Kspace forces on Rspace procs
+ int maxatom;
+
+ void rk_setup();
+ void r2k_comm();
+ void k2r_comm();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/STUBS/mpi.cpp b/src/STUBS/mpi.cpp
index 35dab3b1d..82288fff3 100644
--- a/src/STUBS/mpi.cpp
+++ b/src/STUBS/mpi.cpp
@@ -1,432 +1,453 @@
/* -----------------------------------------------------------------------
LAMMPS 2003 (July 31) - Molecular Dynamics Simulator
Sandia National Laboratories, www.cs.sandia.gov/~sjplimp/lammps.html
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.
------------------------------------------------------------------------ */
/* Single-processor "stub" versions of MPI routines */
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include <sys/time.h>
#include "mpi.h"
/* lo-level function prototypes */
void mpi_copy_int(void *, void *, int);
void mpi_copy_float(void *, void *, int);
void mpi_copy_double(void *, void *, int);
void mpi_copy_char(void *, void *, int);
void mpi_copy_byte(void *, void *, int);
/* lo-level data structure */
struct {
double value;
int proc;
} double_int;
/* ---------------------------------------------------------------------- */
/* MPI Functions */
/* ---------------------------------------------------------------------- */
int MPI_Init(int *argc, char ***argv) {return 0;}
/* ---------------------------------------------------------------------- */
int MPI_Initialized(int *flag)
{
*flag = 1;
return 0;
}
/* ---------------------------------------------------------------------- */
-/* Returns "localhost" as the name of the processor */
+/* return "localhost" as name of the processor */
void MPI_Get_processor_name(char *name, int *resultlen)
{
const char host[] = "localhost";
int len;
if (!name || !resultlen) return;
len = strlen(host);
memcpy(name,host,len+1);
*resultlen = len;
return;
}
/* ---------------------------------------------------------------------- */
int MPI_Comm_rank(MPI_Comm comm, int *me)
{
*me = 0;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Comm_size(MPI_Comm comm, int *nprocs)
{
*nprocs = 1;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Abort(MPI_Comm comm, int errorcode)
{
exit(1);
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Finalize() {return 0;}
/* ---------------------------------------------------------------------- */
double MPI_Wtime()
{
double time;
struct timeval tv;
gettimeofday(&tv,NULL);
time = 1.0 * tv.tv_sec + 1.0e-6 * tv.tv_usec;
return time;
}
/* ---------------------------------------------------------------------- */
int MPI_Type_size(MPI_Datatype datatype, int *size)
{
if (datatype == MPI_INT) *size = sizeof(int);
else if (datatype == MPI_FLOAT) *size = sizeof(float);
else if (datatype == MPI_DOUBLE) *size = sizeof(double);
else if (datatype == MPI_CHAR) *size = sizeof(char);
else if (datatype == MPI_BYTE) *size = sizeof(char);
else if (datatype == MPI_LONG_LONG) *size = sizeof(uint64_t);
else if (datatype == MPI_DOUBLE_INT) *size = sizeof(double_int);
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Send(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
{
printf("MPI Stub WARNING: Should not send message to self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
{
printf("MPI Stub WARNING: Should not rsend message to self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Status *status)
{
printf("MPI Stub WARNING: Should not recv message from self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Request *request)
{
printf("MPI Stub WARNING: Should not recv message from self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Wait(MPI_Request *request, MPI_Status *status)
{
printf("MPI Stub WARNING: Should not wait on message from self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Waitall(int n, MPI_Request *request, MPI_Status *status)
{
printf("MPI Stub WARNING: Should not wait on message from self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Waitany(int count, MPI_Request *request, int *index,
MPI_Status *status)
{
printf("MPI Stub WARNING: Should not wait on message from self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype sdatatype,
int dest, int stag, void *rbuf, int rcount,
MPI_Datatype rdatatype, int source, int rtag,
MPI_Comm comm, MPI_Status *status)
{
printf("MPI Stub WARNING: Should not send message to self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)
{
printf("MPI Stub WARNING: Should not get count of message to self\n");
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
{
*comm_out = comm;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out)
{
*comm_out = comm;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Comm_free(MPI_Comm *comm) {return 0;}
/* ---------------------------------------------------------------------- */
int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods,
int reorder, MPI_Comm *comm_cart)
{
*comm_cart = comm_old;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods,
int *coords)
{
dims[0] = dims[1] = dims[2] = 1;
periods[0] = periods[1] = periods[2] = 1;
coords[0] = coords[1] = coords[2] = 0;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
int *source, int *dest)
{
*source = *dest = 0;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank)
{
*rank = 0;
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Barrier(MPI_Comm comm) {return 0;}
/* ---------------------------------------------------------------------- */
int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
int root, MPI_Comm comm) {return 0;}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
{
int n;
if (datatype == MPI_INT) n = count*sizeof(int);
else if (datatype == MPI_FLOAT) n = count*sizeof(float);
else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
else if (datatype == MPI_CHAR) n = count*sizeof(char);
else if (datatype == MPI_BYTE) n = count*sizeof(char);
else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op,
int root, MPI_Comm comm)
{
int n;
if (datatype == MPI_INT) n = count*sizeof(int);
else if (datatype == MPI_FLOAT) n = count*sizeof(float);
else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
else if (datatype == MPI_CHAR) n = count*sizeof(char);
else if (datatype == MPI_BYTE) n = count*sizeof(char);
else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
int MPI_Scan(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
{
int n;
if (datatype == MPI_INT) n = count*sizeof(int);
else if (datatype == MPI_FLOAT) n = count*sizeof(float);
else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
else if (datatype == MPI_CHAR) n = count*sizeof(char);
else if (datatype == MPI_BYTE) n = count*sizeof(char);
else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)
{
int n;
if (sendtype == MPI_INT) n = sendcount*sizeof(int);
else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int *recvcounts, int *displs,
MPI_Datatype recvtype, MPI_Comm comm)
{
int n;
if (sendtype == MPI_INT) n = sendcount*sizeof(int);
else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
{
int n;
if (datatype == MPI_INT) n = *recvcounts*sizeof(int);
else if (datatype == MPI_FLOAT) n = *recvcounts*sizeof(float);
else if (datatype == MPI_DOUBLE) n = *recvcounts*sizeof(double);
else if (datatype == MPI_CHAR) n = *recvcounts*sizeof(char);
else if (datatype == MPI_BYTE) n = *recvcounts*sizeof(char);
else if (datatype == MPI_LONG_LONG) n = *recvcounts*sizeof(uint64_t);
else if (datatype == MPI_DOUBLE_INT) n = *recvcounts*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)
{
int n;
if (sendtype == MPI_INT) n = sendcount*sizeof(int);
else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
/* ---------------------------------------------------------------------- */
/* copy values from data1 to data2 */
int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
- void *recvbuf, int *recvcounts, int *displs,
- MPI_Datatype recvtype, int root, MPI_Comm comm)
+ void *recvbuf, int *recvcounts, int *displs,
+ MPI_Datatype recvtype, int root, MPI_Comm comm)
{
int n;
if (sendtype == MPI_INT) n = sendcount*sizeof(int);
else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
memcpy(recvbuf,sendbuf,n);
return 0;
}
+
+/* ---------------------------------------------------------------------- */
+
+/* copy values from data1 to data2 */
+
+int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
+ MPI_Datatype sendtype, void *recvbuf, int recvcount,
+ MPI_Datatype recvtype, int root, MPI_Comm comm)
+{
+ int n;
+ if (sendtype == MPI_INT) n = recvcount*sizeof(int);
+ else if (sendtype == MPI_FLOAT) n = recvcount*sizeof(float);
+ else if (sendtype == MPI_DOUBLE) n = recvcount*sizeof(double);
+ else if (sendtype == MPI_CHAR) n = recvcount*sizeof(char);
+ else if (sendtype == MPI_BYTE) n = recvcount*sizeof(char);
+ else if (sendtype == MPI_LONG_LONG) n = recvcount*sizeof(uint64_t);
+ else if (sendtype == MPI_DOUBLE_INT) n = recvcount*sizeof(double_int);
+
+ memcpy(recvbuf,sendbuf,n);
+ return 0;
+}
diff --git a/src/STUBS/mpi.h b/src/STUBS/mpi.h
index 4a4ce5644..bebf65316 100644
--- a/src/STUBS/mpi.h
+++ b/src/STUBS/mpi.h
@@ -1,121 +1,124 @@
/* -----------------------------------------------------------------------
LAMMPS 2003 (July 31) - Molecular Dynamics Simulator
Sandia National Laboratories, www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------ */
#ifndef MPI_STUBS
#define MPI_STUBS
/* Dummy defs for MPI stubs */
#define MPI_COMM_WORLD 0
#define MPI_SUCCESS 0
#define MPI_INT 1
#define MPI_FLOAT 2
#define MPI_DOUBLE 3
#define MPI_CHAR 4
#define MPI_BYTE 5
#define MPI_LONG_LONG 6
#define MPI_DOUBLE_INT 7
#define MPI_SUM 1
#define MPI_MAX 2
#define MPI_MIN 3
#define MPI_MAXLOC 4
#define MPI_MINLOC 5
#define MPI_LOR 6
#define MPI_ANY_SOURCE -1
#define MPI_Comm int
#define MPI_Request int
#define MPI_Datatype int
#define MPI_Op int
#define MPI_MAX_PROCESSOR_NAME 128
/* MPI data structs */
struct MPI_Status {
int MPI_SOURCE;
};
/* Function prototypes for MPI stubs */
int MPI_Init(int *argc, char ***argv);
int MPI_Initialized(int *flag);
void MPI_Get_processor_name(char *name, int *resultlen);
int MPI_Comm_rank(MPI_Comm comm, int *me);
int MPI_Comm_size(MPI_Comm comm, int *nprocs);
int MPI_Abort(MPI_Comm comm, int errorcode);
int MPI_Finalize();
double MPI_Wtime();
int MPI_Type_size(int, int *);
int MPI_Send(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm);
int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm);
int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Status *status);
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
int source, int tag, MPI_Comm comm, MPI_Request *request);
int MPI_Wait(MPI_Request *request, MPI_Status *status);
int MPI_Waitall(int n, MPI_Request *request, MPI_Status *status);
int MPI_Waitany(int count, MPI_Request *request, int *index,
MPI_Status *status);
int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype sdatatype,
int dest, int stag, void *rbuf, int rcount,
MPI_Datatype rdatatype, int source, int rtag,
MPI_Comm comm, MPI_Status *status);
int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out);
int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out);
int MPI_Comm_free(MPI_Comm *comm);
int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods,
int reorder, MPI_Comm *comm_cart);
int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods,
int *coords);
int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
int *source, int *dest);
int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank);
int MPI_Barrier(MPI_Comm comm);
int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
int root, MPI_Comm comm);
int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
int MPI_Scan(void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm);
int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int *recvcounts, int *displs,
MPI_Datatype recvtype, MPI_Comm comm);
int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm);
int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
- void *recvbuf, int *recvcounts, int *displs,
- MPI_Datatype recvtype, int root, MPI_Comm comm);
+ void *recvbuf, int *recvcounts, int *displs,
+ MPI_Datatype recvtype, int root, MPI_Comm comm);
+int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
+ MPI_Datatype sendtype, void *recvbuf, int recvcount,
+ MPI_Datatype recvtype, int root, MPI_Comm comm);
#endif
diff --git a/src/USER-CG-CMM/Install.sh b/src/USER-CG-CMM/Install.sh
index 83298b72f..2e56ff545 100644
--- a/src/USER-CG-CMM/Install.sh
+++ b/src/USER-CG-CMM/Install.sh
@@ -1,44 +1,63 @@
# Install/unInstall package files in LAMMPS
# do not install child files if parent does not exist
if (test $1 = 1) then
if (test -e ../angle_harmonic.cpp) then
cp angle_cg_cmm.h ..
cp angle_cg_cmm.cpp ..
+
+ cp angle_sdk.h ..
+ cp angle_sdk.cpp ..
fi
if (test -e ../pppm.cpp) then
cp pair_cg_cmm_coul_long.cpp ..
cp pair_cg_cmm_coul_long.h ..
+
+ cp pair_lj_sdk_coul_long.cpp ..
+ cp pair_lj_sdk_coul_long.h ..
fi
cp cg_cmm_parms.h ..
cp cg_cmm_parms.cpp ..
cp pair_cmm_common.h ..
cp pair_cmm_common.cpp ..
cp pair_cg_cmm.cpp ..
cp pair_cg_cmm.h ..
cp pair_cg_cmm_coul_cut.cpp ..
cp pair_cg_cmm_coul_cut.h ..
+ cp pair_lj_sdk.cpp ..
+ cp pair_lj_sdk.h ..
+ cp lj_sdk_common.h ..
+
elif (test $1 = 0) then
rm -f ../angle_cg_cmm.h
rm -f ../angle_cg_cmm.cpp
rm -f ../cg_cmm_parms.h
rm -f ../cg_cmm_parms.cpp
rm -f ../pair_cmm_common.h
rm -f ../pair_cmm_common.cpp
rm -f ../pair_cg_cmm.cpp
rm -f ../pair_cg_cmm.h
rm -f ../pair_cg_cmm_coul_cut.cpp
rm -f ../pair_cg_cmm_coul_cut.h
rm -f ../pair_cg_cmm_coul_long.cpp
rm -f ../pair_cg_cmm_coul_long.h
+ rm -f ../lj_sdk_common.h
+
+ rm -f ../angle_sdk.h
+ rm -f ../angle_sdk.cpp
+
+ rm -f ../pair_lj_sdk.cpp
+ rm -f ../pair_lj_sdk.h
+ rm -f ../pair_lj_sdk_coul_long.cpp
+ rm -f ../pair_lj_sdk_coul_long.h
fi
diff --git a/src/USER-CG-CMM/Package.sh b/src/USER-CG-CMM/Package.sh
index dcf6a8158..db51eed74 100644
--- a/src/USER-CG-CMM/Package.sh
+++ b/src/USER-CG-CMM/Package.sh
@@ -1,26 +1,38 @@
# Update package files in LAMMPS
# cp package file to src if doesn't exist or is different
# do not copy molecular and kspace files if corresponding versions do not exist
for file in *.cpp *.h; do
if (test $file = angle_cg_cmm.cpp -a ! -e ../pair_angle_harmonic.cpp) then
continue
fi
if (test $file = angle_cg_cmm.h -a ! -e ../pair_angle_harmonic.h) then
continue
fi
if (test $file = pair_cg_cmm_coul_long.cpp -a ! -e ../pair_lj_cut_coul_long.cpp) then
continue
fi
if (test $file = pair_cg_cmm_coul_long.h -a ! -e ../pair_lj_cut_coul_long.h) then
continue
fi
+ if (test $file = angle_sdk.cpp -a ! -e ../pair_angle_harmonic.cpp) then
+ continue
+ fi
+ if (test $file = angle_sdk.h -a ! -e ../pair_angle_harmonic.h) then
+ continue
+ fi
+ if (test $file = pair_lj_sdk_coul_long.cpp -a ! -e ../pair_lj_cut_coul_long.cpp) then
+ continue
+ fi
+ if (test $file = pair_lj_sdk_coul_long.h -a ! -e ../pair_lj_cut_coul_long.h) then
+ continue
+ fi
if (test ! -e ../$file) then
echo " creating src/$file"
cp $file ..
elif (test "`diff --brief $file ../$file`" != "") then
echo " updating src/$file"
cp $file ..
fi
done
diff --git a/src/USER-CG-CMM/README b/src/USER-CG-CMM/README
index e93e739b1..b37fbd376 100644
--- a/src/USER-CG-CMM/README
+++ b/src/USER-CG-CMM/README
@@ -1,36 +1,46 @@
-This package implements 4 commands which can be used in a LAMMPS input
+This package implements 3 commands which can be used in a LAMMPS input
script:
-pair_style cg/cmm
-pair_style cg/cmm/coul/cut
-pair_style cg/cmm/coul/long
-angle_style cg/cmm :ul
+pair_style lj/sdk
+pair_style lj/sdk/coul/long
+angle_style sdk
These styles allow coarse grained MD simulations with the
parametrization of Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007)
-(cg/cmm), with extensions to simulate ionic liquids, electrolytes,
-lipids and charged amino acids (to be published soon).
+(SDK), with extensions to simulate ionic liquids, electrolytes,
+lipids and charged amino acids.
See the doc pages for these commands for details.
There are example scripts for using this package in
examples/USER/cg-cmm.
+This is the second generation implementation reducing the the clutter
+of the previous version. For many systems with long range
+electrostatics, it will be faster to use pair_style hybrid/overlay
+with lj/sdk and coul/long instead of the combined lj/sdk/coul/long
+style, since the number of charged atom types is usually small. To
+exploit this property, the use of the kspace_style pppm/cg is
+recommended over regular pppm. For all new styles, input file backward
+compatibility is provided. The old implementation is still available
+through appending the /old suffix. These will be discontinued and
+removed after the new implementation has been fully validated.
+
The current version of this package should be considered beta
-quality. The CG potentials work correctly and well, but there will be
-optimizations, cleanups and additional tools to aid in setting up and
-analyzing simulations with this package added in the next months.
+quality. The CG potentials work correctly for "normal" situations, but
+have not been testing with all kinds of potential parameters and
+simuation systems.
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
---------------------------------
Thanks for contributions, support and testing goes to
Wataru Shinoda (AIST, Tsukuba)
-Russell DeVane (CMM / U Penn, Philadelphia)
-Balasubramanian Sundaram (JNCASR, Bangalore)
+Russell DeVane (Procter & Gamble)
Michael L. Klein (CMM / U Penn, Philadelphia)
+Balasubramanian Sundaram (JNCASR, Bangalore)
-version: 0.98 / 2008-01-31
+version: 0.99 / 2011-11-29
diff --git a/src/USER-CG-CMM/angle_cg_cmm.h b/src/USER-CG-CMM/angle_cg_cmm.h
index 7fef95d5a..506041584 100644
--- a/src/USER-CG-CMM/angle_cg_cmm.h
+++ b/src/USER-CG-CMM/angle_cg_cmm.h
@@ -1,55 +1,55 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ANGLE_CLASS
-AngleStyle(cg/cmm,AngleCGCMM)
+AngleStyle(cg/cmm/old,AngleCGCMM)
#else
#ifndef LMP_ANGLE_CG_CMM_H
#define LMP_ANGLE_CG_CMM_H
#include "stdio.h"
#include "angle.h"
#include "cg_cmm_parms.h"
namespace LAMMPS_NS {
class AngleCGCMM : public Angle, public CGCMMParms {
public:
AngleCGCMM(class LAMMPS *);
~AngleCGCMM();
void compute(int, int);
void coeff(int, char **);
double equilibrium_angle(int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, int, int, int);
protected:
void ev_tally_lj13(int, int, int, int, double, double,
double, double, double);
private:
double *k,*theta0;
int *cg_type;
double *epsilon, *sigma, *rcut;
void allocate();
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/angle_sdk.cpp b/src/USER-CG-CMM/angle_sdk.cpp
new file mode 100644
index 000000000..93b8c19a2
--- /dev/null
+++ b/src/USER-CG-CMM/angle_sdk.cpp
@@ -0,0 +1,494 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Variant of the harmonic angle potential for use with the
+ lj/sdk potential for coarse grained MD simulations.
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdlib.h"
+#include "angle_sdk.h"
+#include "atom.h"
+#include "neighbor.h"
+#include "pair.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+
+#include "lj_sdk_common.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+using namespace LJSDKParms;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+AngleSDK::AngleSDK(LAMMPS *lmp) : Angle(lmp) { repflag = 0;}
+
+/* ---------------------------------------------------------------------- */
+
+AngleSDK::~AngleSDK()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(k);
+ memory->destroy(theta0);
+ memory->destroy(repscale);
+
+ allocated = 0;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AngleSDK::compute(int eflag, int vflag)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
+ double eangle,f1[3],f3[3],e13,f13;
+ double dtheta,tk;
+ double rsq1,rsq2,rsq3,r1,r2,c,s,a,a11,a12,a22;
+
+ eangle = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ int **anglelist = neighbor->anglelist;
+ int nanglelist = neighbor->nanglelist;
+ int nlocal = atom->nlocal;
+ int newton_bond = force->newton_bond;
+
+ for (n = 0; n < nanglelist; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // 1-3 LJ interaction.
+ // we only want to use the repulsive part,
+ // and it can be scaled (or off).
+ // so this has to be done here and not in the
+ // general non-bonded code.
+
+ if (repflag) {
+
+ delx3 = x[i1][0] - x[i3][0];
+ dely3 = x[i1][1] - x[i3][1];
+ delz3 = x[i1][2] - x[i3][2];
+ domain->minimum_image(delx3,dely3,delz3);
+ rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
+
+ const int type1 = atom->type[i1];
+ const int type3 = atom->type[i3];
+
+ f13=0.0;
+ e13=0.0;
+
+ if (rsq3 < rminsq[type1][type3]) {
+ const int ljt = lj_type[type1][type3];
+ const double r2inv = 1.0/rsq3;
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+
+ f13 = r4inv*(lj1[type1][type3]*r4inv*r4inv - lj2[type1][type3]);
+ if (eflag) e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+
+ f13 = r6inv*(lj1[type1][type3]*r3inv - lj2[type1][type3]);
+ if (eflag) e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+
+ f13 = r6inv*(lj1[type1][type3]*r6inv - lj2[type1][type3]);
+ if (eflag) e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
+ }
+
+ // make sure energy is 0.0 at the cutoff.
+ if (eflag) e13 -= emin[type1][type3];
+
+ f13 *= r2inv;
+ }
+ }
+
+ // force & energy
+
+ dtheta = acos(c) - theta0[type];
+ tk = k[type] * dtheta;
+
+ if (eflag) eangle = tk*dtheta;
+
+ a = -2.0 * tk * s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of the 3 atoms
+
+ if (newton_bond || i1 < nlocal) {
+ f[i1][0] += f1[0] + f13*delx3;
+ f[i1][1] += f1[1] + f13*dely3;
+ f[i1][2] += f1[2] + f13*delz3;
+ }
+
+ if (newton_bond || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (newton_bond || i3 < nlocal) {
+ f[i3][0] += f3[0] - f13*delx3;
+ f[i3][1] += f3[1] - f13*dely3;
+ f[i3][2] += f3[2] - f13*delz3;
+ }
+
+ if (evflag) {
+ ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2);
+ ev_tally13(i1,i3,nlocal,newton_bond,e13,f13,delx3,dely3,delz3);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AngleSDK::allocate()
+{
+ allocated = 1;
+ int n = atom->nangletypes;
+
+ memory->create(k,n+1,"angle:k");
+ memory->create(theta0,n+1,"angle:theta0");
+ memory->create(repscale,n+1,"angle:repscale");
+
+ memory->create(setflag,n+1,"angle:setflag");
+ for (int i = 1; i <= n; i++) setflag[i] = 0;
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more types
+------------------------------------------------------------------------- */
+
+void AngleSDK::coeff(int narg, char **arg)
+{
+ if ((narg < 3) || (narg > 6))
+ error->all(FLERR,"Incorrect args for angle coefficients");
+
+ if (!allocated) allocate();
+
+ int ilo,ihi;
+ force->bounds(arg[0],atom->nangletypes,ilo,ihi);
+
+ double k_one = force->numeric(arg[1]);
+ double theta0_one = force->numeric(arg[2]);
+ double repscale_one;
+
+ // backward compatibility with old cg/cmm style input:
+ // this had <lj_type> <epsilon> <sigma>
+ // if epsilon is set to 0.0 we accept it as repscale 0.0
+ // otherwise assume repscale 1.0, since we were using
+ // epsilon to turn repulsion on or off.
+ if (narg == 6) {
+ repscale_one = force->numeric(arg[4]);
+ if (repscale_one > 0.0) repscale_one = 1.0;
+ } else if (narg == 4) repscale_one = force->numeric(arg[3]);
+ else if (narg == 3) repscale_one = 1.0;
+ else error->all(FLERR,"Incorrect args for angle coefficients");
+
+ // convert theta0 from degrees to radians and store coefficients
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ k[i] = k_one;
+ theta0[i] = theta0_one/180.0 * MY_PI;
+ repscale[i] = repscale_one;
+ setflag[i] = 1;
+ count++;
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ error check and initialize all values needed for force computation
+------------------------------------------------------------------------- */
+
+void AngleSDK::init_style()
+{
+
+ // make sure we use an SDK pair_style and that we need the 1-3 repulsion
+
+ repflag = 0;
+ for (int i = 1; i <= atom->nangletypes; i++)
+ if (repscale[i] > 0.0) repflag = 1;
+
+ // set up pointers to access SDK LJ parameters for 1-3 interactions
+
+ if (repflag) {
+ int itmp;
+ if (force->pair == NULL)
+ error->all(FLERR,"Angle style SDK requires use of a compatible with Pair style");
+
+ lj1 = (double **) force->pair->extract("lj1",itmp);
+ lj2 = (double **) force->pair->extract("lj2",itmp);
+ lj3 = (double **) force->pair->extract("lj3",itmp);
+ lj4 = (double **) force->pair->extract("lj4",itmp);
+ lj_type = (int **) force->pair->extract("lj_type",itmp);
+ rminsq = (double **) force->pair->extract("rminsq",itmp);
+ emin = (double **) force->pair->extract("emin",itmp);
+
+ if (!lj1 || !lj2 || !lj3 || !lj4 || !lj_type || !rminsq || !emin)
+ error->all(FLERR,"Angle style SDK is incompatible with Pair style");
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double AngleSDK::equilibrium_angle(int i)
+{
+ return theta0[i];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes out coeffs to restart file
+------------------------------------------------------------------------- */
+
+void AngleSDK::write_restart(FILE *fp)
+{
+ fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
+ fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
+ fwrite(&repscale[1],sizeof(double),atom->nangletypes,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads coeffs from restart file, bcasts them
+------------------------------------------------------------------------- */
+
+void AngleSDK::read_restart(FILE *fp)
+{
+ allocate();
+
+ if (comm->me == 0) {
+ fread(&k[1],sizeof(double),atom->nangletypes,fp);
+ fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
+ fread(&repscale[1],sizeof(double),atom->nangletypes,fp);
+ }
+ MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
+ MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
+ MPI_Bcast(&repscale[1],atom->nangletypes,MPI_DOUBLE,0,world);
+
+ for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AngleSDK::ev_tally13(int i, int j, int nlocal, int newton_bond,
+ double evdwl, double fpair,
+ double delx, double dely, double delz)
+{
+ double v[6];
+
+ if (eflag_either) {
+ if (eflag_global) {
+ if (newton_bond) {
+ energy += evdwl;
+ } else {
+ if (i < nlocal)
+ energy += 0.5*evdwl;
+ if (j < nlocal)
+ energy += 0.5*evdwl;
+ }
+ }
+ if (eflag_atom) {
+ if (newton_bond || i < nlocal) eatom[i] += 0.5*evdwl;
+ if (newton_bond || j < nlocal) eatom[i] += 0.5*evdwl;
+ }
+ }
+
+ if (vflag_either) {
+ v[0] = delx*delx*fpair;
+ v[1] = dely*dely*fpair;
+ v[2] = delz*delz*fpair;
+ v[3] = delx*dely*fpair;
+ v[4] = delx*delz*fpair;
+ v[5] = dely*delz*fpair;
+
+ if (vflag_global) {
+ if (newton_bond) {
+ virial[0] += v[0];
+ virial[1] += v[1];
+ virial[2] += v[2];
+ virial[3] += v[3];
+ virial[4] += v[4];
+ virial[5] += v[5];
+ } else {
+ if (i < nlocal) {
+ virial[0] += 0.5*v[0];
+ virial[1] += 0.5*v[1];
+ virial[2] += 0.5*v[2];
+ virial[3] += 0.5*v[3];
+ virial[4] += 0.5*v[4];
+ virial[5] += 0.5*v[5];
+ }
+ if (j < nlocal) {
+ virial[0] += 0.5*v[0];
+ virial[1] += 0.5*v[1];
+ virial[2] += 0.5*v[2];
+ virial[3] += 0.5*v[3];
+ virial[4] += 0.5*v[4];
+ virial[5] += 0.5*v[5];
+ }
+ }
+ }
+
+ if (vflag_atom) {
+ if (newton_bond || i < nlocal) {
+ vatom[i][0] += 0.5*v[0];
+ vatom[i][1] += 0.5*v[1];
+ vatom[i][2] += 0.5*v[2];
+ vatom[i][3] += 0.5*v[3];
+ vatom[i][4] += 0.5*v[4];
+ vatom[i][5] += 0.5*v[5];
+ }
+ if (newton_bond || j < nlocal) {
+ vatom[j][0] += 0.5*v[0];
+ vatom[j][1] += 0.5*v[1];
+ vatom[j][2] += 0.5*v[2];
+ vatom[j][3] += 0.5*v[3];
+ vatom[j][4] += 0.5*v[4];
+ vatom[j][5] += 0.5*v[5];
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double AngleSDK::single(int type, int i1, int i2, int i3)
+{
+ double **x = atom->x;
+
+ double delx1 = x[i1][0] - x[i2][0];
+ double dely1 = x[i1][1] - x[i2][1];
+ double delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+ double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
+
+ double delx2 = x[i3][0] - x[i2][0];
+ double dely2 = x[i3][1] - x[i2][1];
+ double delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+ double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
+
+ double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ double e13=0.0;
+ if (repflag) {
+
+ // 1-3 LJ interaction.
+ double delx3 = x[i1][0] - x[i3][0];
+ double dely3 = x[i1][1] - x[i3][1];
+ double delz3 = x[i1][2] - x[i3][2];
+ domain->minimum_image(delx3,dely3,delz3);
+
+ const int type1 = atom->type[i1];
+ const int type3 = atom->type[i3];
+
+ const double rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
+
+ if (rsq3 < rminsq[type1][type3]) {
+ const int ljt = lj_type[type1][type3];
+ const double r2inv = 1.0/rsq3;
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+
+ e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+
+ e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+
+ e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
+ }
+
+ // make sure energy is 0.0 at the cutoff.
+ e13 -= emin[type1][type3];
+ }
+ }
+
+ double dtheta = acos(c) - theta0[type];
+ double tk = k[type] * dtheta;
+ return tk*dtheta + e13;
+}
diff --git a/src/USER-CG-CMM/angle_cg_cmm.h b/src/USER-CG-CMM/angle_sdk.h
similarity index 58%
copy from src/USER-CG-CMM/angle_cg_cmm.h
copy to src/USER-CG-CMM/angle_sdk.h
index 7fef95d5a..91da40abe 100644
--- a/src/USER-CG-CMM/angle_cg_cmm.h
+++ b/src/USER-CG-CMM/angle_sdk.h
@@ -1,55 +1,62 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef ANGLE_CLASS
-AngleStyle(cg/cmm,AngleCGCMM)
+AngleStyle(sdk,AngleSDK)
+AngleStyle(cg/cmm,AngleSDK)
#else
-#ifndef LMP_ANGLE_CG_CMM_H
-#define LMP_ANGLE_CG_CMM_H
+#ifndef LMP_ANGLE_SDK_H
+#define LMP_ANGLE_SDK_H
#include "stdio.h"
#include "angle.h"
-#include "cg_cmm_parms.h"
namespace LAMMPS_NS {
-class AngleCGCMM : public Angle, public CGCMMParms {
+class AngleSDK : public Angle {
public:
- AngleCGCMM(class LAMMPS *);
- ~AngleCGCMM();
- void compute(int, int);
+ AngleSDK(class LAMMPS *);
+ virtual ~AngleSDK();
+ virtual void compute(int, int);
void coeff(int, char **);
+ void init_style();
double equilibrium_angle(int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, int, int, int);
protected:
- void ev_tally_lj13(int, int, int, int, double, double,
- double, double, double);
-
- private:
double *k,*theta0;
- int *cg_type;
- double *epsilon, *sigma, *rcut;
+ // scaling factor for repulsive 1-3 interaction
+ double *repscale;
+ // parameters from SDK pair style
+ int **lj_type;
+ double **lj1,**lj2, **lj3, **lj4;
+ double **rminsq,**emin;
+
+ int repflag; // 1 if we have to handle 1-3 repulsion
+
+ void ev_tally13(int, int, int, int, double, double,
+ double, double, double);
+
void allocate();
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_adp_omp.h b/src/USER-CG-CMM/lj_sdk_common.h
similarity index 50%
copy from src/USER-OMP/pair_adp_omp.h
copy to src/USER-CG-CMM/lj_sdk_common.h
index f7d2509cd..9b151b8a3 100644
--- a/src/USER-OMP/pair_adp_omp.h
+++ b/src/USER-CG-CMM/lj_sdk_common.h
@@ -1,49 +1,44 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
+ Common data for the Shinoda, DeVane, Klein (SDK) coarse grain model
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifndef LMP_LJ_SDK_COMMON_H
+#define LMP_LJ_SDK_COMMON_H
-PairStyle(adp/omp,PairADPOMP)
+#include "string.h"
-#else
+namespace LAMMPS_NS {
+namespace LJSDKParms {
-#ifndef LMP_PAIR_ADP_OMP_H
-#define LMP_PAIR_ADP_OMP_H
+ // LJ type flags. list of supported LJ exponent combinations
+ enum {LJ_NOT_SET=0, LJ9_6, LJ12_4, LJ12_6, NUM_LJ_TYPES};
-#include "pair_adp.h"
-#include "thr_omp.h"
+ static int find_lj_type(const char *label,
+ const char * const * const list) {
+ for (int i=0; i < NUM_LJ_TYPES; ++i)
+ if (strcmp(label,list[i]) == 0) return i;
-namespace LAMMPS_NS {
+ return LJ_NOT_SET;
+ }
-class PairADPOMP : public PairADP, public ThrOMP {
-
- public:
- PairADPOMP(class LAMMPS *);
-
- virtual void compute(int, int);
- virtual double memory_usage();
-
- private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double *rho_t, double **mu_t, double **lambda_t,
- int iifrom, int iito, int tid);
-};
-
-}
-
-#endif
+ static const char * const lj_type_list[] = {"none", "lj9_6", "lj12_4", "lj12_6"};
+ static const double lj_prefact[] = {0.0, 6.75, 2.59807621135332, 4.0};
+ static const double lj_pow1[] = {0.0, 9.00, 12.0, 12.0};
+ static const double lj_pow2[] = {0.0, 6.00, 4.0, 6.0};
+}}
#endif
+
diff --git a/src/USER-CG-CMM/pair_cg_cmm.h b/src/USER-CG-CMM/pair_cg_cmm.h
index 27eb4d830..74eee884e 100644
--- a/src/USER-CG-CMM/pair_cg_cmm.h
+++ b/src/USER-CG-CMM/pair_cg_cmm.h
@@ -1,51 +1,51 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm,PairCGCMM)
+PairStyle(cg/cmm/old,PairCGCMM)
#else
#ifndef LMP_PAIR_CG_CMM_H
#define LMP_PAIR_CG_CMM_H
#include "pair_cmm_common.h"
namespace LAMMPS_NS {
class PairCGCMM : public PairCMMCommon {
public:
PairCGCMM(class LAMMPS *);
virtual ~PairCGCMM();
void compute(int, int);
void compute_inner();
void compute_middle();
void compute_outer(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, int, int, int, double, double, double, double &);
private:
// disable default constructor
PairCGCMM();
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/pair_cg_cmm_coul_cut.h b/src/USER-CG-CMM/pair_cg_cmm_coul_cut.h
index 1309bec6d..2732fa4d5 100644
--- a/src/USER-CG-CMM/pair_cg_cmm_coul_cut.h
+++ b/src/USER-CG-CMM/pair_cg_cmm_coul_cut.h
@@ -1,53 +1,53 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm/coul/cut,PairCGCMMCoulCut)
+PairStyle(cg/cmm/coul/cut/old,PairCGCMMCoulCut)
#else
#ifndef LMP_PAIR_CG_CMM_COUL_CUT_H
#define LMP_PAIR_CG_CMM_COUL_CUT_H
#include "pair_cmm_common.h"
namespace LAMMPS_NS {
class PairCGCMMCoulCut : public PairCMMCommon {
public:
PairCGCMMCoulCut(class LAMMPS *);
~PairCGCMMCoulCut();
void compute(int, int);
void compute_inner();
void compute_middle();
void compute_outer(int, int);
void init_style();
double init_one(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
double memory_usage();
double single(int, int, int, int, double, double, double, double &);
protected:
void allocate();
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/pair_cg_cmm_coul_long.h b/src/USER-CG-CMM/pair_cg_cmm_coul_long.h
index d3fd0b453..7bc15a853 100644
--- a/src/USER-CG-CMM/pair_cg_cmm_coul_long.h
+++ b/src/USER-CG-CMM/pair_cg_cmm_coul_long.h
@@ -1,56 +1,56 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm/coul/long,PairCGCMMCoulLong)
+PairStyle(cg/cmm/coul/long/old,PairCGCMMCoulLong)
#else
#ifndef LMP_PAIR_CG_CMM_COUL_LONG_H
#define LMP_PAIR_CG_CMM_COUL_LONG_H
#include "pair_cmm_common.h"
namespace LAMMPS_NS {
class PairCGCMMCoulLong : public PairCMMCommon {
public:
PairCGCMMCoulLong(class LAMMPS *);
~PairCGCMMCoulLong();
void compute(int, int);
void compute_inner();
void compute_middle();
void compute_outer(int, int);
void init_style();
double init_one(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
double memory_usage();
double single(int, int, int, int, double, double, double, double &);
void *extract(char *str, int &);
protected:
void allocate();
void init_tables();
void free_tables();
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/pair_lj_sdk.cpp b/src/USER-CG-CMM/pair_lj_sdk.cpp
new file mode 100644
index 000000000..a31b9eac4
--- /dev/null
+++ b/src/USER-CG-CMM/pair_lj_sdk.cpp
@@ -0,0 +1,484 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+ This style is a simplified re-implementation of the CG/CMM pair style
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_lj_sdk.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "update.h"
+#include "integrate.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+
+#include "lj_sdk_common.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+using namespace LJSDKParms;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSDK::PairLJSDK(LAMMPS *lmp) : Pair(lmp)
+{
+ respa_enable = 0;
+ single_enable = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSDK::~PairLJSDK()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(lj_type);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ memory->destroy(offset);
+
+ memory->destroy(rminsq);
+ memory->destroy(emin);
+
+ allocated = 0;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJSDK::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = 0;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>();
+ else eval<1,1,0>();
+ } else {
+ if (force->newton_pair) eval<1,0,1>();
+ else eval<1,0,0>();
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>();
+ else eval<0,0,0>();
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+void PairLJSDK::eval()
+{
+ int i,j,ii,jj,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,forcelj,factor_lj;
+
+ evdwl = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = atom->f;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ const int inum = list->inum;
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp=fytmp=fztmp=0.0;
+
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ } else continue;
+
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl *= factor_lj;
+ if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairLJSDK::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ memory->create(lj_type,n+1,n+1,"pair:lj_type");
+ for (int i = 1; i <= n; i++) {
+ for (int j = i; j <= n; j++) {
+ setflag[i][j] = 0;
+ lj_type[i][j] = LJ_NOT_SET;
+ }
+ }
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+
+ memory->create(offset,n+1,n+1,"pair:offset");
+
+ memory->create(rminsq,n+1,n+1,"pair:rminsq");
+ memory->create(emin,n+1,n+1,"pair:emin");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairLJSDK::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // reset cutoffs that have been explicitly set
+
+ if (allocated) {
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i+1; j <= atom->ntypes; j++)
+ if (setflag[i][j]) cut[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairLJSDK::coeff(int narg, char **arg)
+{
+ if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ int lj_type_one = find_lj_type(arg[2],lj_type_list);
+ if (lj_type_one == LJ_NOT_SET)
+ error->all(FLERR,"Cannot parse LJ type flag.");
+
+ double epsilon_one = force->numeric(arg[3]);
+ double sigma_one = force->numeric(arg[4]);
+
+ double cut_one = cut_global;
+ if (narg == 6) cut_one = force->numeric(arg[5]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ lj_type[i][j] = lj_type_one;
+ epsilon[i][j] = epsilon_one;
+ sigma[i][j] = sigma_one;
+ cut[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairLJSDK::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0)
+ error->all(FLERR,"No mixing support for lj/sdk. "
+ "Coefficients for all pairs need to be set explicitly.");
+
+ const int ljt = lj_type[i][j];
+
+ if (ljt == LJ_NOT_SET)
+ error->all(FLERR,"unrecognized LJ parameter flag");
+
+ lj1[i][j] = lj_prefact[ljt] * lj_pow1[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow1[ljt]);
+ lj2[i][j] = lj_prefact[ljt] * lj_pow2[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow2[ljt]);
+ lj3[i][j] = lj_prefact[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow1[ljt]);
+ lj4[i][j] = lj_prefact[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow2[ljt]);
+
+ if (offset_flag) {
+ double ratio = sigma[i][j] / cut[i][j];
+ offset[i][j] = lj_prefact[ljt] * epsilon[i][j] * (pow(ratio,lj_pow1[ljt]) - pow(ratio,lj_pow2[ljt]));
+ } else offset[i][j] = 0.0;
+
+ lj1[j][i] = lj1[i][j];
+ lj2[j][i] = lj2[i][j];
+ lj3[j][i] = lj3[i][j];
+ lj4[j][i] = lj4[i][j];
+ cut[j][i] = cut[i][j];
+ cutsq[j][i] = cutsq[i][j];
+ offset[j][i] = offset[i][j];
+ lj_type[j][i] = lj_type[i][j];
+
+ // compute derived parameters for SDK angle potential
+
+ const double eps = epsilon[i][j];
+ const double sig = sigma[i][j];
+ const double rmin = sig*exp(1.0/(lj_pow1[ljt]-lj_pow2[ljt])
+ *log(lj_pow1[ljt]/lj_pow2[ljt]) );
+ rminsq[j][i] = rminsq[i][j] = rmin*rmin;
+
+ const double ratio = sig/rmin;
+ const double emin_one = lj_prefact[ljt] * eps * (pow(ratio,lj_pow1[ljt])
+ - pow(ratio,lj_pow2[ljt]));
+ emin[j][i] = emin[i][j] = emin_one;
+
+ // compute I,J contribution to long-range tail correction
+ // count total # of atoms of type I and J via Allreduce
+
+ if (tail_flag)
+ error->all(FLERR,"Tail flag not supported by lj/sdk pair style");
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairLJSDK::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&lj_type[i][j],sizeof(int),1,fp);
+ fwrite(&epsilon[i][j],sizeof(double),1,fp);
+ fwrite(&sigma[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairLJSDK::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+ MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+ if (setflag[i][j]) {
+ if (me == 0) {
+ fread(&lj_type[i][j],sizeof(int),1,fp);
+ fread(&epsilon[i][j],sizeof(double),1,fp);
+ fread(&sigma[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&lj_type[i][j],1,MPI_INT,0,world);
+ MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairLJSDK::write_restart_settings(FILE *fp)
+{
+ fwrite(&cut_global,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairLJSDK::read_restart_settings(FILE *fp)
+{
+ int me = comm->me;
+ if (me == 0) {
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSDK::single(int, int, int itype, int jtype, double rsq,
+ double, double factor_lj, double &fforce)
+{
+
+ if (rsq < cutsq[itype][jtype]) {
+
+ const int ljt = lj_type[itype][jtype];
+ const double ljpow1 = lj_pow1[ljt];
+ const double ljpow2 = lj_pow2[ljt];
+ const double ljpref = lj_prefact[ljt];
+
+ const double ratio = sigma[itype][jtype]/sqrt(rsq);
+ const double eps = epsilon[itype][jtype];
+
+ fforce = factor_lj * ljpref*eps * (ljpow1*pow(ratio,ljpow1)
+ - ljpow2*pow(ratio,ljpow2))/rsq;
+ return factor_lj * (ljpref*eps * (pow(ratio,ljpow1) - pow(ratio,ljpow2))
+ - offset[itype][jtype]);
+
+ } else fforce=0.0;
+
+ return 0.0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void *PairLJSDK::extract(char *str, int &dim)
+{
+ dim = 2;
+ if (strcmp(str,"epsilon") == 0) return (void *) epsilon;
+ if (strcmp(str,"sigma") == 0) return (void *) sigma;
+ if (strcmp(str,"lj_type") == 0) return (void *) lj_type;
+ if (strcmp(str,"lj1") == 0) return (void *) lj1;
+ if (strcmp(str,"lj2") == 0) return (void *) lj2;
+ if (strcmp(str,"lj3") == 0) return (void *) lj3;
+ if (strcmp(str,"lj4") == 0) return (void *) lj4;
+ if (strcmp(str,"rminsq") == 0) return (void *) rminsq;
+ if (strcmp(str,"emin") == 0) return (void *) emin;
+ return NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSDK::memory_usage()
+{
+ double bytes = Pair::memory_usage();
+ int n = atom->ntypes;
+
+ // setflag/lj_type
+ bytes += 2 * (n+1)*(n+1)*sizeof(int);
+ // cut/cutsq/epsilon/sigma/offset/lj1/lj2/lj3/lj4/rminsq/emin
+ bytes += 11 * (n+1)*(n+1)*sizeof(double);
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-CG-CMM/pair_lj_sdk.h
similarity index 51%
copy from src/USER-OMP/pair_buck_coul_long_omp.h
copy to src/USER-CG-CMM/pair_lj_sdk.h
index 2c87904de..65aea005c 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-CG-CMM/pair_lj_sdk.h
@@ -1,48 +1,74 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+PairStyle(lj/sdk,PairLJSDK)
+PairStyle(cg/cmm,PairLJSDK)
#else
-#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
-#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#ifndef LMP_PAIR_LJ_SDK_H
+#define LMP_PAIR_LJ_SDK_H
-#include "pair_buck_coul_long.h"
-#include "thr_omp.h"
+#include "pair.h"
namespace LAMMPS_NS {
-
-class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
-
+class LAMMPS;
+
+class PairLJSDK : public Pair {
public:
- PairBuckCoulLongOMP(class LAMMPS *);
-
+ PairLJSDK(LAMMPS *);
+ virtual ~PairLJSDK();
virtual void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+ void write_restart(FILE *);
+ void read_restart(FILE *);
+ void write_restart_settings(FILE *);
+ void read_restart_settings(FILE *);
+ double single(int, int, int, int, double, double, double, double &);
+ void *extract(char *, int &);
virtual double memory_usage();
+ protected:
+ int **lj_type; // type of lennard jones potential
+
+ double **cut;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4,**offset;
+
+ // cutoff and offset for minimum of LJ potential
+ // to be used in SDK angle potential, which
+ // uses only the repulsive part of the potential
+
+ double **rminsq, **emin;
+
+ double cut_global;
+
+ void allocate();
+
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void eval();
+
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/pair_lj_sdk_coul_long.cpp b/src/USER-CG-CMM/pair_lj_sdk_coul_long.cpp
new file mode 100644
index 000000000..24a0718b7
--- /dev/null
+++ b/src/USER-CG-CMM/pair_lj_sdk_coul_long.cpp
@@ -0,0 +1,765 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+ This style is a simplified re-implementation of the CG/CMM pair style
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_lj_sdk_coul_long.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "kspace.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "update.h"
+#include "integrate.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+
+#include "lj_sdk_common.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+using namespace LJSDKParms;
+
+#define EWALD_F 1.12837917
+#define EWALD_P 0.3275911
+#define A1 0.254829592
+#define A2 -0.284496736
+#define A3 1.421413741
+#define A4 -1.453152027
+#define A5 1.061405429
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSDKCoulLong::PairLJSDKCoulLong(LAMMPS *lmp) : Pair(lmp)
+{
+ respa_enable = 0;
+ ftable = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSDKCoulLong::~PairLJSDKCoulLong()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(lj_type);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut_lj);
+ memory->destroy(cut_ljsq);
+ memory->destroy(epsilon);
+ memory->destroy(sigma);
+ memory->destroy(lj1);
+ memory->destroy(lj2);
+ memory->destroy(lj3);
+ memory->destroy(lj4);
+ memory->destroy(offset);
+
+ memory->destroy(rminsq);
+ memory->destroy(emin);
+
+ allocated = 0;
+ }
+ if (ftable) free_tables();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = 0;
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>();
+ else eval<1,1,0>();
+ } else {
+ if (force->newton_pair) eval<1,0,1>();
+ else eval<1,0,0>();
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>();
+ else eval<0,0,0>();
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+void PairLJSDKCoulLong::eval()
+{
+ int i,ii,j,jj,jtype,itable;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double fraction,table;
+ double r,rsq,r2inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double grij,expm2,prefactor,t,erfc;
+
+ evdwl = ecoul = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = atom->f;
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
+ double fxtmp,fytmp,fztmp;
+
+ const int inum = list->inum;
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp=fytmp=fztmp=0.0;
+
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
+
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq) {
+ r = sqrt(rsq);
+ grij = g_ewald * r;
+ expm2 = exp(-grij*grij);
+ t = 1.0 / (1.0 + EWALD_P*grij);
+ erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
+ prefactor = qqrd2e * qtmp*q[j]/r;
+ forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else {
+ union_int_float_t rsq_lookup;
+ rsq_lookup.f = rsq;
+ itable = rsq_lookup.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
+ table = ftable[itable] + fraction*dftable[itable];
+ forcecoul = qtmp*q[j] * table;
+ if (factor_coul < 1.0) {
+ table = ctable[itable] + fraction*dctable[itable];
+ prefactor = qtmp*q[j] * table;
+ forcecoul -= (1.0-factor_coul)*prefactor;
+ }
+ }
+ } else {
+ forcecoul = 0.0;
+ ecoul = 0.0;
+ }
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ }
+ } else {
+ forcelj=0.0;
+ evdwl = 0.0;
+ }
+
+ fpair = (forcecoul + factor_lj*forcelj) * r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) {
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ ecoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ ecoul = qtmp*q[j] * table;
+ }
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
+ evdwl,ecoul,fpair,delx,dely,delz);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ memory->create(lj_type,n+1,n+1,"pair:lj_type");
+ for (int i = 1; i <= n; i++) {
+ for (int j = i; j <= n; j++) {
+ setflag[i][j] = 0;
+ lj_type[i][j] = LJ_NOT_SET;
+ }
+ }
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut_lj,n+1,n+1,"pair:cut_lj");
+ memory->create(cut_ljsq,n+1,n+1,"pair:cut_ljsq");
+ memory->create(epsilon,n+1,n+1,"pair:epsilon");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+
+ memory->create(lj1,n+1,n+1,"pair:lj1");
+ memory->create(lj2,n+1,n+1,"pair:lj2");
+ memory->create(lj3,n+1,n+1,"pair:lj3");
+ memory->create(lj4,n+1,n+1,"pair:lj4");
+
+ memory->create(offset,n+1,n+1,"pair:offset");
+
+ memory->create(rminsq,n+1,n+1,"pair:rminsq");
+ memory->create(emin,n+1,n+1,"pair:emin");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::settings(int narg, char **arg)
+{
+ if (narg < 1 || narg > 2) error->all(FLERR,"Illegal pair_style command");
+
+ cut_lj_global = force->numeric(arg[0]);
+ if (narg == 1) cut_coul = cut_lj_global;
+ else cut_coul = force->numeric(arg[1]);
+
+ // reset cutoffs that have been explicitly set
+
+ if (allocated) {
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i+1; j <= atom->ntypes; j++)
+ if (setflag[i][j]) cut_lj[i][j] = cut_lj_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::coeff(int narg, char **arg)
+{
+ if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ int lj_type_one = find_lj_type(arg[2],lj_type_list);
+ if (lj_type_one == LJ_NOT_SET)
+ error->all(FLERR,"Cannot parse LJ type flag.");
+
+ double epsilon_one = force->numeric(arg[3]);
+ double sigma_one = force->numeric(arg[4]);
+
+ double cut_lj_one = cut_lj_global;
+ if (narg == 6) cut_lj_one = force->numeric(arg[5]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ lj_type[i][j] = lj_type_one;
+ epsilon[i][j] = epsilon_one;
+ sigma[i][j] = sigma_one;
+ cut_lj[i][j] = cut_lj_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::init_style()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Pair style lj/cut/coul/long requires atom attribute q");
+
+ neighbor->request(this);
+
+ cut_coulsq = cut_coul * cut_coul;
+
+ // insure use of KSpace long-range solver, set g_ewald
+
+ if (force->kspace == NULL)
+ error->all(FLERR,"Pair style is incompatible with KSpace style");
+ g_ewald = force->kspace->g_ewald;
+
+ // setup force tables
+
+ if (ncoultablebits) init_tables();
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairLJSDKCoulLong::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0)
+ error->all(FLERR,"No mixing support for lj/sdk/coul/long. "
+ "Coefficients for all pairs need to be set explicitly.");
+
+ const int ljt = lj_type[i][j];
+
+ if (ljt == LJ_NOT_SET)
+ error->all(FLERR,"unrecognized LJ parameter flag");
+
+ double cut = MAX(cut_lj[i][j],cut_coul);
+ cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j];
+
+ lj1[i][j] = lj_prefact[ljt] * lj_pow1[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow1[ljt]);
+ lj2[i][j] = lj_prefact[ljt] * lj_pow2[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow2[ljt]);
+ lj3[i][j] = lj_prefact[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow1[ljt]);
+ lj4[i][j] = lj_prefact[ljt] * epsilon[i][j] * pow(sigma[i][j],lj_pow2[ljt]);
+
+ if (offset_flag) {
+ double ratio = sigma[i][j] / cut_lj[i][j];
+ offset[i][j] = lj_prefact[ljt] * epsilon[i][j] * (pow(ratio,lj_pow1[ljt]) - pow(ratio,lj_pow2[ljt]));
+ } else offset[i][j] = 0.0;
+
+ cut_ljsq[j][i] = cut_ljsq[i][j];
+ cut_lj[j][i] = cut_lj[i][j];
+ lj1[j][i] = lj1[i][j];
+ lj2[j][i] = lj2[i][j];
+ lj3[j][i] = lj3[i][j];
+ lj4[j][i] = lj4[i][j];
+ offset[j][i] = offset[i][j];
+ lj_type[j][i] = lj_type[i][j];
+
+ // compute LJ derived parameters for SDK angle potential (LJ only!)
+
+ const double eps = epsilon[i][j];
+ const double sig = sigma[i][j];
+ const double rmin = sig*exp(1.0/(lj_pow1[ljt]-lj_pow2[ljt])
+ *log(lj_pow1[ljt]/lj_pow2[ljt]) );
+ rminsq[j][i] = rminsq[i][j] = rmin*rmin;
+
+ const double ratio = sig/rmin;
+ const double emin_one = lj_prefact[ljt] * eps * (pow(ratio,lj_pow1[ljt])
+ - pow(ratio,lj_pow2[ljt]));
+ emin[j][i] = emin[i][j] = emin_one;
+
+ // compute I,J contribution to long-range tail correction
+ // count total # of atoms of type I and J via Allreduce
+
+ if (tail_flag)
+ error->all(FLERR,"Tail flag not supported by lj/sdk/coul/long pair style");
+
+ return cut;
+}
+
+/* ----------------------------------------------------------------------
+ setup force tables used in compute routines
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::init_tables()
+{
+ int masklo,maskhi;
+ double r,grij,expm2,derfc;
+ double qqrd2e = force->qqrd2e;
+
+ tabinnersq = tabinner*tabinner;
+ init_bitmap(tabinner,cut_coul,ncoultablebits,
+ masklo,maskhi,ncoulmask,ncoulshiftbits);
+
+ int ntable = 1;
+ for (int i = 0; i < ncoultablebits; i++) ntable *= 2;
+
+ // linear lookup tables of length N = 2^ncoultablebits
+ // stored value = value at lower edge of bin
+ // d values = delta from lower edge to upper edge of bin
+
+ if (ftable) free_tables();
+
+ memory->create(rtable,ntable,"pair:rtable");
+ memory->create(ftable,ntable,"pair:ftable");
+ memory->create(ctable,ntable,"pair:ctable");
+ memory->create(etable,ntable,"pair:etable");
+ memory->create(drtable,ntable,"pair:drtable");
+ memory->create(dftable,ntable,"pair:dftable");
+ memory->create(dctable,ntable,"pair:dctable");
+ memory->create(detable,ntable,"pair:detable");
+
+ union_int_float_t rsq_lookup;
+ union_int_float_t minrsq_lookup;
+ int itablemin;
+ minrsq_lookup.i = 0 << ncoulshiftbits;
+ minrsq_lookup.i |= maskhi;
+
+ for (int i = 0; i < ntable; i++) {
+ rsq_lookup.i = i << ncoulshiftbits;
+ rsq_lookup.i |= masklo;
+ if (rsq_lookup.f < tabinnersq) {
+ rsq_lookup.i = i << ncoulshiftbits;
+ rsq_lookup.i |= maskhi;
+ }
+ r = sqrtf(rsq_lookup.f);
+ grij = g_ewald * r;
+ expm2 = exp(-grij*grij);
+ derfc = erfc(grij);
+ rtable[i] = rsq_lookup.f;
+ ftable[i] = qqrd2e/r * (derfc + EWALD_F*grij*expm2);
+ ctable[i] = qqrd2e/r;
+ etable[i] = qqrd2e/r * derfc;
+
+ minrsq_lookup.f = MIN(minrsq_lookup.f,rsq_lookup.f);
+ }
+
+ tabinnersq = minrsq_lookup.f;
+
+ int ntablem1 = ntable - 1;
+
+ for (int i = 0; i < ntablem1; i++) {
+ drtable[i] = 1.0/(rtable[i+1] - rtable[i]);
+ dftable[i] = ftable[i+1] - ftable[i];
+ dctable[i] = ctable[i+1] - ctable[i];
+ detable[i] = etable[i+1] - etable[i];
+ }
+
+ // get the delta values for the last table entries
+ // tables are connected periodically between 0 and ntablem1
+
+ drtable[ntablem1] = 1.0/(rtable[0] - rtable[ntablem1]);
+ dftable[ntablem1] = ftable[0] - ftable[ntablem1];
+ dctable[ntablem1] = ctable[0] - ctable[ntablem1];
+ detable[ntablem1] = etable[0] - etable[ntablem1];
+
+ // get the correct delta values at itablemax
+ // smallest r is in bin itablemin
+ // largest r is in bin itablemax, which is itablemin-1,
+ // or ntablem1 if itablemin=0
+ // deltas at itablemax only needed if corresponding rsq < cut*cut
+ // if so, compute deltas between rsq and cut*cut
+
+ double f_tmp,c_tmp,e_tmp;
+ itablemin = minrsq_lookup.i & ncoulmask;
+ itablemin >>= ncoulshiftbits;
+ int itablemax = itablemin - 1;
+ if (itablemin == 0) itablemax = ntablem1;
+ rsq_lookup.i = itablemax << ncoulshiftbits;
+ rsq_lookup.i |= maskhi;
+
+ if (rsq_lookup.f < cut_coulsq) {
+ rsq_lookup.f = cut_coulsq;
+ r = sqrtf(rsq_lookup.f);
+ grij = g_ewald * r;
+ expm2 = exp(-grij*grij);
+ derfc = erfc(grij);
+
+ f_tmp = qqrd2e/r * (derfc + EWALD_F*grij*expm2);
+ c_tmp = qqrd2e/r;
+ e_tmp = qqrd2e/r * derfc;
+
+ drtable[itablemax] = 1.0/(rsq_lookup.f - rtable[itablemax]);
+ dftable[itablemax] = f_tmp - ftable[itablemax];
+ dctable[itablemax] = c_tmp - ctable[itablemax];
+ detable[itablemax] = e_tmp - etable[itablemax];
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&lj_type[i][j],sizeof(int),1,fp);
+ fwrite(&epsilon[i][j],sizeof(double),1,fp);
+ fwrite(&sigma[i][j],sizeof(double),1,fp);
+ fwrite(&cut_lj[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+ MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+ if (setflag[i][j]) {
+ if (me == 0) {
+ fread(&lj_type[i][j],sizeof(int),1,fp);
+ fread(&epsilon[i][j],sizeof(double),1,fp);
+ fread(&sigma[i][j],sizeof(double),1,fp);
+ fread(&cut_lj[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&lj_type[i][j],1,MPI_INT,0,world);
+ MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_lj[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::write_restart_settings(FILE *fp)
+{
+ fwrite(&cut_lj_global,sizeof(double),1,fp);
+ fwrite(&cut_coul,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&cut_lj_global,sizeof(double),1,fp);
+ fread(&cut_coul,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ----------------------------------------------------------------------
+ free memory for tables used in pair computations
+------------------------------------------------------------------------- */
+
+void PairLJSDKCoulLong::free_tables()
+{
+ memory->destroy(rtable);
+ memory->destroy(drtable);
+ memory->destroy(ftable);
+ memory->destroy(dftable);
+ memory->destroy(ctable);
+ memory->destroy(dctable);
+ memory->destroy(etable);
+ memory->destroy(detable);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSDKCoulLong::single(int i, int j, int itype, int jtype,
+ double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double r2inv,r,grij,expm2,t,erfc,prefactor;
+ double fraction,table,forcecoul,forcelj,phicoul,philj;
+ int itable;
+
+ r2inv = 1.0/rsq;
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq) {
+ r = sqrt(rsq);
+ grij = g_ewald * r;
+ expm2 = exp(-grij*grij);
+ t = 1.0 / (1.0 + EWALD_P*grij);
+ erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
+ prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r;
+ forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else {
+ union_int_float_t rsq_lookup_single;
+ rsq_lookup_single.f = rsq;
+ itable = rsq_lookup_single.i & ncoulmask;
+ itable >>= ncoulshiftbits;
+ fraction = (rsq_lookup_single.f - rtable[itable]) * drtable[itable];
+ table = ftable[itable] + fraction*dftable[itable];
+ forcecoul = atom->q[i]*atom->q[j] * table;
+ if (factor_coul < 1.0) {
+ table = ctable[itable] + fraction*dctable[itable];
+ prefactor = atom->q[i]*atom->q[j] * table;
+ forcecoul -= (1.0-factor_coul)*prefactor;
+ }
+ }
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ const int ljt = lj_type[itype][jtype];
+ const double ljpow1 = lj_pow1[ljt];
+ const double ljpow2 = lj_pow2[ljt];
+ const double ljpref = lj_prefact[ljt];
+
+ const double ratio = sigma[itype][jtype]/sqrt(rsq);
+ const double eps = epsilon[itype][jtype];
+
+ fforce = factor_lj * ljpref*eps * (ljpow1*pow(ratio,ljpow1)
+ - ljpow2*pow(ratio,ljpow2))/rsq;
+ philj = factor_lj * (ljpref*eps * (pow(ratio,ljpow1) - pow(ratio,ljpow2))
+ - offset[itype][jtype]);
+ } else fforce=0.0;
+
+ fforce = (forcecoul + factor_lj*forcelj) * r2inv;
+
+ double eng = 0.0;
+ if (rsq < cut_coulsq) {
+ if (!ncoultablebits || rsq <= tabinnersq)
+ phicoul = prefactor*erfc;
+ else {
+ table = etable[itable] + fraction*detable[itable];
+ phicoul = atom->q[i]*atom->q[j] * table;
+ }
+ if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor;
+ eng += phicoul;
+ }
+
+ if (rsq < cut_ljsq[itype][jtype])
+ eng += philj;
+
+ return eng;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void *PairLJSDKCoulLong::extract(char *str, int &dim)
+{
+ dim = 2;
+ if (strcmp(str,"epsilon") == 0) return (void *) epsilon;
+ if (strcmp(str,"sigma") == 0) return (void *) sigma;
+ if (strcmp(str,"lj_type") == 0) return (void *) lj_type;
+ if (strcmp(str,"lj1") == 0) return (void *) lj1;
+ if (strcmp(str,"lj2") == 0) return (void *) lj2;
+ if (strcmp(str,"lj3") == 0) return (void *) lj3;
+ if (strcmp(str,"lj4") == 0) return (void *) lj4;
+ if (strcmp(str,"rminsq") == 0) return (void *) rminsq;
+ if (strcmp(str,"emin") == 0) return (void *) emin;
+
+ dim = 0;
+ if (strcmp(str,"cut_coul") == 0) return (void *) &cut_coul;
+ return NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSDKCoulLong::memory_usage()
+{
+ double bytes = Pair::memory_usage();
+ int n = atom->ntypes;
+
+ // setflag/lj_type
+ bytes += 2 * (n+1)*(n+1)*sizeof(int);
+ // lj_cut/lj_cutsq/epsilon/sigma/offset/lj1/lj2/lj3/lj4/rminsq/emin
+ bytes += 11 * (n+1)*(n+1)*sizeof(double);
+
+ if (ncoultablebits) {
+ int ntable = 1<<ncoultablebits;
+ bytes += 8 * ntable*sizeof(double);
+ }
+
+ return bytes;
+}
diff --git a/src/USER-CG-CMM/pair_lj_sdk_coul_long.h b/src/USER-CG-CMM/pair_lj_sdk_coul_long.h
new file mode 100644
index 000000000..f4ed4b4d6
--- /dev/null
+++ b/src/USER-CG-CMM/pair_lj_sdk_coul_long.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(lj/sdk/coul/long,PairLJSDKCoulLong)
+PairStyle(cg/cmm/coul/long,PairLJSDKCoulLong)
+
+#else
+
+#ifndef LMP_PAIR_LJ_SDK_COUL_LONG_H
+#define LMP_PAIR_LJ_SDK_COUL_LONG_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairLJSDKCoulLong : public Pair {
+ public:
+ PairLJSDKCoulLong(class LAMMPS *);
+ virtual ~PairLJSDKCoulLong();
+ virtual void compute(int, int);
+ virtual void settings(int, char **);
+ void coeff(int, char **);
+ void init_style();
+ double init_one(int, int);
+ void write_restart(FILE *);
+ void read_restart(FILE *);
+ virtual void write_restart_settings(FILE *);
+ virtual void read_restart_settings(FILE *);
+ virtual double single(int, int, int, int, double, double, double, double &);
+ void *extract(char *, int &);
+ virtual double memory_usage();
+
+ protected:
+ double **cut_lj,**cut_ljsq;
+ double cut_coul,cut_coulsq;
+ double **epsilon,**sigma;
+ double **lj1,**lj2,**lj3,**lj4,**offset;
+ int **lj_type;
+
+ // cutoff and offset for minimum of LJ potential
+ // to be used in SDK angle potential, which
+ // uses only the repulsive part of the potential
+
+ double **rminsq, **emin;
+
+ double cut_lj_global;
+ double g_ewald;
+
+ double tabinnersq;
+ double *rtable,*drtable,*ftable,*dftable,*ctable,*dctable;
+ double *etable,*detable;
+ int ncoulshiftbits,ncoulmask;
+
+ void allocate();
+ void init_tables();
+ void free_tables();
+
+ private:
+ template <int EVFLAG, int EFLAG, int NEWTON_PAIR> void eval();
+
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-CUDA/cuda.cpp b/src/USER-CUDA/cuda.cpp
index 438312ee8..fff5c78b9 100644
--- a/src/USER-CUDA/cuda.cpp
+++ b/src/USER-CUDA/cuda.cpp
@@ -1,819 +1,825 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
Original Version:
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
-----------------------------------------------------------------------
USER-CUDA Package and associated modifications:
https://sourceforge.net/projects/lammpscuda/
Christian Trott, christian.trott@tu-ilmenau.de
Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
Theoretical Physics II, University of Technology Ilmenau, Germany
See the README file in the USER-CUDA directory.
This software is distributed under the GNU General Public License.
------------------------------------------------------------------------- */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include "cuda.h"
#include "atom.h"
#include "domain.h"
#include "force.h"
#include "pair.h"
#include "update.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "universe.h"
#include "input.h"
#include "error.h"
#include "cuda_neigh_list.h"
//#include "pre_binning_cu.h"
#include "binning_cu.h"
//#include "reverse_binning_cu.h"
#include <ctime>
#include <cmath>
#include "cuda_pair_cu.h"
#include "cuda_cu.h"
using namespace LAMMPS_NS;
Cuda::Cuda(LAMMPS *lmp) : Pointers(lmp)
{
cuda_exists=true;
lmp->cuda=this;
if(universe->me==0)
printf("# Using LAMMPS_CUDA \n");
shared_data.me=universe->me;
device_set=false;
Cuda_Cuda_GetCompileSettings(&shared_data);
if(shared_data.compile_settings.prec_glob!=sizeof(CUDA_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: Global Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_glob, sizeof(CUDA_FLOAT)/4);
if(shared_data.compile_settings.prec_x!=sizeof(X_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: X Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_x, sizeof(X_FLOAT)/4);
if(shared_data.compile_settings.prec_v!=sizeof(V_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: V Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_v, sizeof(V_FLOAT)/4);
if(shared_data.compile_settings.prec_f!=sizeof(F_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: F Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_f, sizeof(F_FLOAT)/4);
if(shared_data.compile_settings.prec_pppm!=sizeof(PPPM_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: PPPM Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_pppm, sizeof(PPPM_FLOAT)/4);
if(shared_data.compile_settings.prec_fft!=sizeof(FFT_FLOAT)/4) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: FFT Precision: cuda %i cpp %i\n\n",shared_data.compile_settings.prec_fft, sizeof(FFT_FLOAT)/4);
#ifdef FFT_CUFFT
if(shared_data.compile_settings.cufft!=1) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: cufft: cuda %i cpp %i\n\n",shared_data.compile_settings.cufft, 1);
#else
if(shared_data.compile_settings.cufft!=0) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: cufft: cuda %i cpp %i\n\n",shared_data.compile_settings.cufft, 0);
#endif
if(shared_data.compile_settings.arch!=CUDA_ARCH) printf("\n\n # CUDA WARNING: Compile Settings of cuda and cpp code differ! \n # CUDA WARNING: arch: cuda %i cpp %i\n\n",shared_data.compile_settings.cufft, CUDA_ARCH);
cu_x = 0;
cu_v = 0;
cu_f = 0;
cu_tag = 0;
cu_type = 0;
cu_mask = 0;
cu_image = 0;
cu_xhold = 0;
cu_q = 0;
cu_rmass = 0;
cu_mass = 0;
cu_virial = 0;
cu_eatom = 0;
cu_vatom = 0;
cu_radius = 0;
cu_density = 0;
cu_omega = 0;
cu_torque = 0;
cu_special = 0;
cu_nspecial = 0;
cu_molecule = 0;
cu_x_type = 0;
x_type = 0;
cu_v_radius = 0;
v_radius = 0;
cu_omega_rmass = 0;
omega_rmass = 0;
binned_id = 0;
cu_binned_id = 0;
binned_idnew = 0;
cu_binned_idnew = 0;
cu_map_array = 0;
copy_buffer=0;
copy_buffersize=0;
neighbor_decide_by_integrator=0;
pinned=true;
debugdata=0;
new int[2*CUDA_MAX_DEBUG_SIZE];
finished_setup = false;
begin_setup = false;
finished_run = false;
setSharedDataZero();
uploadtime=0;
downloadtime=0;
dotiming=false;
dotestatom = false;
testatom = 0;
oncpu = true;
self_comm = 0;
MYDBG( printf("# CUDA: Cuda::Cuda Done...\n");)
//cCudaData<double, float, yx >
}
Cuda::~Cuda()
{
print_timings();
if(universe->me==0) printf("# CUDA: Free memory...\n");
delete cu_q;
delete cu_x;
delete cu_v;
delete cu_f;
delete cu_tag;
delete cu_type;
delete cu_mask;
delete cu_image;
delete cu_xhold;
delete cu_mass;
delete cu_rmass;
delete cu_virial;
delete cu_eng_vdwl;
delete cu_eng_coul;
delete cu_eatom;
delete cu_vatom;
delete cu_radius;
delete cu_density;
delete cu_omega;
delete cu_torque;
delete cu_molecule;
delete cu_x_type;
delete [] x_type;
delete cu_v_radius;
delete [] v_radius;
delete cu_omega_rmass;
delete [] omega_rmass;
delete cu_map_array;
std::map<NeighList*, CudaNeighList*>::iterator p = neigh_lists.begin();
while(p != neigh_lists.end())
{
delete p->second;
++p;
}
}
void Cuda::accelerator(int narg, char** arg)
{
if(device_set) return;
if(universe->me==0)
printf("# CUDA: Activate GPU \n");
int* devicelist=NULL;
int pppn=2;
for(int i=0;i<narg;i++)
{
if(strcmp(arg[i],"gpu/node")==0)
{
- if(++i==narg)
- error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number or keyword 'special' after 'gpu/node' option.");
- if(strcmp(arg[i],"special")==0)
- {
- if(++i==narg)
- error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'.");
- pppn=atoi(arg[i]);
- if(pppn<1) error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'.");
- if(i+pppn==narg)
- error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting list of device ids after keyword 'gpu/node special'.");
- devicelist=new int[pppn];
- for(int k=0;k<pppn;k++)
- {i++;devicelist[k]=atoi(arg[i]);}
-
- }
- else
+ if(++i==narg)
+ error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'gpu/node' option.");
+ pppn=atoi(arg[i]);
+ }
+
+ if(strcmp(arg[i],"gpu/node/special")==0)
+ {
+ if(++i==narg)
+ error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node/special'.");
pppn=atoi(arg[i]);
+ if(pppn<1) error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting number of GPUs to be used per node after keyword 'gpu/node special'.");
+ if(i+pppn==narg)
+ error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting list of device ids after keyword 'gpu/node special'.");
+ devicelist=new int[pppn];
+ for(int k=0;k<pppn;k++)
+ {i++;devicelist[k]=atoi(arg[i]);}
}
+
if(strcmp(arg[i],"pinned")==0)
{
if(++i==narg)
error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'pinned' option.");
pinned=atoi(arg[i])==0?false:true;
if((pinned==false)&&(universe->me==0)) printf(" #CUDA: Pinned memory is not used for communication\n");
}
- if(strcmp(arg[i],"dotiming")==0)
+
+ if(strcmp(arg[i],"timing")==0)
{
dotiming=true;
}
+
if(strcmp(arg[i],"suffix")==0)
{
if(++i==narg)
error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a string after 'suffix' option.");
strcpy(lmp->suffix,arg[i]);
}
+
if(strcmp(arg[i],"overlap_comm")==0)
{
shared_data.overlap_comm=1;
}
- if(strcmp(arg[i],"dotest")==0)
+
+ if(strcmp(arg[i],"test")==0)
{
if(++i==narg)
- error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'dotest' option.");
+ error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'test' option.");
testatom=atof(arg[i]);
dotestatom=true;
}
- if(strcmp(arg[i],"override_bpa")==0)
+
+ if(strcmp(arg[i],"override/bpa")==0)
{
if(++i==narg)
- error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'override_bpa' option.");
+ error->all(FLERR,"Invalid Options for 'accelerator' command. Expecting a number after 'override/bpa' option.");
shared_data.pair.override_block_per_atom = atoi(arg[i]);
}
}
+
CudaWrapper_Init(0, (char**)0,universe->me,pppn,devicelist);
//if(shared_data.overlap_comm)
CudaWrapper_AddStreams(3);
cu_x = 0;
cu_v = 0;
cu_f = 0;
cu_tag = 0;
cu_type = 0;
cu_mask = 0;
cu_image = 0;
cu_xhold = 0;
cu_q = 0;
cu_rmass = 0;
cu_mass = 0;
cu_virial = 0;
cu_eatom = 0;
cu_vatom = 0;
cu_radius = 0;
cu_density = 0;
cu_omega = 0;
cu_torque = 0;
cu_special = 0;
cu_nspecial = 0;
cu_molecule = 0;
cu_x_type = 0;
cu_v_radius = 0;
cu_omega_rmass = 0;
cu_binned_id = 0;
cu_binned_idnew = 0;
device_set=true;
allocate();
delete devicelist;
}
void Cuda::setSharedDataZero()
{
MYDBG(printf("# CUDA: Cuda::setSharedDataZero ...\n");)
shared_data.atom.nlocal = 0;
shared_data.atom.nghost = 0;
shared_data.atom.nall = 0;
shared_data.atom.nmax = 0;
shared_data.atom.ntypes = 0;
shared_data.atom.q_flag = 0;
shared_data.atom.need_eatom = 0;
shared_data.atom.need_vatom = 0;
shared_data.atom.update_nmax = 1;
shared_data.atom.update_nlocal = 1;
shared_data.atom.update_neigh = 1;
shared_data.pair.cudable_force = 0;
shared_data.pair.collect_forces_later = 0;
shared_data.pair.use_block_per_atom = 0;
shared_data.pair.override_block_per_atom = -1;
shared_data.pair.cut = 0;
shared_data.pair.cutsq = 0;
shared_data.pair.cut_inner = 0;
shared_data.pair.cut_coul = 0;
shared_data.pair.special_lj = 0;
shared_data.pair.special_coul = 0;
shared_data.pair.neighall = false;
shared_data.pppm.cudable_force = 0;
shared_data.buffersize = 0;
shared_data.buffer_new = 1;
shared_data.buffer = NULL;
shared_data.comm.comm_phase=0;
shared_data.overlap_comm=0;
shared_data.comm.buffer = NULL;
shared_data.comm.buffer_size=0;
shared_data.comm.overlap_split_ratio=0;
// setTimingsZero();
}
void Cuda::allocate()
{
accelerator(0,NULL);
MYDBG(printf("# CUDA: Cuda::allocate ...\n");)
if(not cu_virial)
{
cu_virial = new cCudaData<double, ENERGY_FLOAT, x > (NULL, & shared_data.pair.virial , 6);
cu_eng_vdwl = new cCudaData<double, ENERGY_FLOAT, x > (NULL, & shared_data.pair.eng_vdwl ,1);
cu_eng_coul = new cCudaData<double, ENERGY_FLOAT, x > (NULL, & shared_data.pair.eng_coul ,1);
cu_extent = new cCudaData<double, double, x> (extent, 6);
shared_data.flag = CudaWrapper_AllocCudaData(sizeof(int));
int size=2*CUDA_MAX_DEBUG_SIZE;
debugdata = new int[size];
cu_debugdata = new cCudaData<int, int, x > (debugdata , size);
shared_data.debugdata=cu_debugdata->dev_data();
}
checkResize();
setSystemParams();
MYDBG(printf("# CUDA: Cuda::allocate done...\n");)
}
void Cuda::setSystemParams()
{
MYDBG(printf("# CUDA: Cuda::setSystemParams ...\n");)
shared_data.atom.nlocal = atom->nlocal;
shared_data.atom.nghost = atom->nghost;
shared_data.atom.nall = atom->nlocal + atom->nghost;
shared_data.atom.ntypes = atom->ntypes;
shared_data.atom.q_flag = atom->q_flag;
shared_data.atom.rmass_flag = atom->rmass_flag;
MYDBG(printf("# CUDA: Cuda::setSystemParams done ...\n");)
}
void Cuda::setDomainParams()
{
MYDBG(printf("# CUDA: Cuda::setDomainParams ...\n");)
cuda_shared_domain* cu_domain = &shared_data.domain;
cu_domain->triclinic = domain->triclinic;
for(short i=0; i<3; ++i)
{
cu_domain->periodicity[i] = domain->periodicity[i];
cu_domain->sublo[i] = domain->sublo[i];
cu_domain->subhi[i] = domain->subhi[i];
cu_domain->boxlo[i] = domain->boxlo[i];
cu_domain->boxhi[i] = domain->boxhi[i];
cu_domain->prd[i] = domain->prd[i];
}
if(domain->triclinic)
{
for(short i=0; i<3; ++i)
{
cu_domain->boxlo_lamda[i] = domain->boxlo_lamda[i];
cu_domain->boxhi_lamda[i] = domain->boxhi_lamda[i];
cu_domain->prd_lamda[i] = domain->prd_lamda[i];
}
cu_domain->xy = domain->xy;
cu_domain->xz = domain->xz;
cu_domain->yz = domain->yz;
}
for(int i=0;i<6;i++)
{
cu_domain->h[i]=domain->h[i];
cu_domain->h_inv[i]=domain->h_inv[i];
cu_domain->h_rate[i]=domain->h_rate[i];
}
cu_domain->update=2;
MYDBG(printf("# CUDA: Cuda::setDomainParams done ...\n");)
}
void Cuda::checkResize()
{
MYDBG(printf("# CUDA: Cuda::checkResize ...\n");)
accelerator(0,NULL);
cuda_shared_atom* cu_atom = & shared_data.atom;
cuda_shared_pair* cu_pair = & shared_data.pair;
cu_atom->q_flag = atom->q_flag;
cu_atom->rmass_flag = atom->rmass ? 1 : 0;
cu_atom->nall = atom->nlocal + atom->nghost;
cu_atom->nlocal = atom->nlocal;
cu_atom->nghost = atom->nghost;
// do we have more atoms to upload than currently allocated memory on device? (also true if nothing yet allocated)
if(atom->nmax > cu_atom->nmax || cu_tag == NULL)
{
delete cu_x; cu_x = new cCudaData<double, X_FLOAT, yx> ((double*)atom->x , & cu_atom->x , atom->nmax, 3,0,true); //cu_x->set_buffer(&(shared_data.buffer),&(shared_data.buffersize),true);
delete cu_v; cu_v = new cCudaData<double, V_FLOAT, yx> ((double*)atom->v, & cu_atom->v , atom->nmax, 3);
delete cu_f; cu_f = new cCudaData<double, F_FLOAT, yx> ((double*)atom->f, & cu_atom->f , atom->nmax, 3,0,true);
delete cu_tag; cu_tag = new cCudaData<int , int , x > (atom->tag , & cu_atom->tag , atom->nmax );
delete cu_type; cu_type = new cCudaData<int , int , x > (atom->type , & cu_atom->type , atom->nmax );
delete cu_mask; cu_mask = new cCudaData<int , int , x > (atom->mask , & cu_atom->mask , atom->nmax );
delete cu_image; cu_image = new cCudaData<int , int , x > (atom->image , & cu_atom->image , atom->nmax );
if(atom->rmass)
{delete cu_rmass; cu_rmass = new cCudaData<double, V_FLOAT, x > (atom->rmass , & cu_atom->rmass , atom->nmax );}
if(cu_atom->q_flag)
{delete cu_q; cu_q = new cCudaData<double, F_FLOAT, x > ((double*)atom->q, & cu_atom->q , atom->nmax );}// cu_q->set_buffer(&(copy_buffer),&(copy_buffersize),true);}
if(atom->radius)
{
delete cu_radius; cu_radius = new cCudaData<double, X_FLOAT, x > (atom->radius , & cu_atom->radius , atom->nmax );
delete cu_v_radius; cu_v_radius = new cCudaData<V_FLOAT, V_FLOAT, x> (v_radius , & cu_atom->v_radius , atom->nmax*4);
delete cu_omega_rmass; cu_omega_rmass = new cCudaData<V_FLOAT, V_FLOAT, x> (omega_rmass , & cu_atom->omega_rmass , atom->nmax*4);
}
if(atom->omega)
{delete cu_omega; cu_omega = new cCudaData<double, V_FLOAT, yx > (((double*) atom->omega) , & cu_atom->omega , atom->nmax,3 );}
if(atom->torque)
{delete cu_torque; cu_torque = new cCudaData<double, F_FLOAT, yx > (((double*) atom->torque) , & cu_atom->torque , atom->nmax,3 );}
if(atom->special)
{delete cu_special; cu_special = new cCudaData<int, int, yx > (((int*) &(atom->special[0][0])) , & cu_atom->special , atom->nmax,atom->maxspecial ); shared_data.atom.maxspecial=atom->maxspecial;}
if(atom->nspecial)
{delete cu_nspecial; cu_nspecial = new cCudaData<int, int, yx > (((int*) atom->nspecial) , & cu_atom->nspecial , atom->nmax,3 );}
if(atom->molecule)
{delete cu_molecule; cu_molecule = new cCudaData<int, int, x > (((int*) atom->molecule) , & cu_atom->molecule , atom->nmax );}
shared_data.atom.special_flag = neighbor->special_flag;
shared_data.atom.molecular = atom->molecular;
cu_atom->update_nmax = 2;
cu_atom->nmax = atom->nmax;
delete cu_x_type; cu_x_type = new cCudaData<X_FLOAT, X_FLOAT, x> (x_type , & cu_atom->x_type , atom->nmax*4);
}
if(((cu_xhold==NULL)||(cu_xhold->get_dim()[0]<neighbor->maxhold))&&neighbor->xhold)
{
delete cu_xhold; cu_xhold = new cCudaData<double, X_FLOAT, yx> ((double*)neighbor->xhold, & cu_atom->xhold , neighbor->maxhold, 3);
shared_data.atom.maxhold=neighbor->maxhold;
}
if(atom->mass && !cu_mass)
{cu_mass = new cCudaData<double, V_FLOAT, x > (atom->mass , & cu_atom->mass , atom->ntypes+1);}
cu_atom->mass_host = atom->mass;
if(atom->map_style==1)
{
if((cu_map_array==NULL))
{
cu_map_array = new cCudaData<int, int, x > (atom->get_map_array() , & cu_atom->map_array , atom->get_map_size() );
}
else
if(cu_map_array->dev_size()/sizeof(int)<atom->get_map_size())
{
delete cu_map_array;
cu_map_array = new cCudaData<int, int, x > (atom->get_map_array() , & cu_atom->map_array , atom->get_map_size() );
}
}
// if any of the host pointers have changed (e.g. re-allocated somewhere else), set to correct pointer
if(cu_x ->get_host_data() != atom->x) cu_x ->set_host_data((double*) (atom->x));
if(cu_v ->get_host_data() != atom->v) cu_v ->set_host_data((double*) (atom->v));
if(cu_f ->get_host_data() != atom->f) cu_f ->set_host_data((double*) (atom->f));
if(cu_tag ->get_host_data() != atom->tag) cu_tag ->set_host_data(atom->tag);
if(cu_type->get_host_data() != atom->type) cu_type->set_host_data(atom->type);
if(cu_mask->get_host_data() != atom->mask) cu_mask->set_host_data(atom->mask);
if(cu_image->get_host_data() != atom->image) cu_mask->set_host_data(atom->image);
if(cu_xhold)
if(cu_xhold->get_host_data()!= neighbor->xhold) cu_xhold->set_host_data((double*)(neighbor->xhold));
if(atom->rmass)
if(cu_rmass->get_host_data() != atom->rmass) cu_rmass->set_host_data((double*) (atom->rmass));
if(cu_atom->q_flag)
if(cu_q->get_host_data() != atom->q) cu_q->set_host_data((double*) (atom->q));
if(atom->radius)
if(cu_radius->get_host_data() != atom->radius) cu_radius->set_host_data((double*) (atom->radius));
if(atom->omega)
if(cu_omega->get_host_data() != atom->omega) cu_omega->set_host_data((double*) (atom->omega));
if(atom->torque)
if(cu_torque->get_host_data() != atom->torque) cu_torque->set_host_data((double*) (atom->torque));
if(atom->special)
if(cu_special->get_host_data() != atom->special)
{delete cu_special; cu_special = new cCudaData<int, int, yx > (((int*) atom->special) , & cu_atom->special , atom->nmax,atom->maxspecial ); shared_data.atom.maxspecial=atom->maxspecial;}
if(atom->nspecial)
if(cu_nspecial->get_host_data() != atom->nspecial) cu_nspecial->set_host_data((int*) (atom->nspecial));
if(atom->molecule)
if(cu_molecule->get_host_data() != atom->molecule) cu_molecule->set_host_data((int*) (atom->molecule));
if(force)
if(cu_virial ->get_host_data() != force->pair->virial) cu_virial ->set_host_data(force->pair->virial);
if(force)
if(cu_eng_vdwl ->get_host_data() != &force->pair->eng_vdwl) cu_eng_vdwl ->set_host_data(&force->pair->eng_vdwl);
if(force)
if(cu_eng_coul ->get_host_data() != &force->pair->eng_coul) cu_eng_coul ->set_host_data(&force->pair->eng_coul);
cu_atom->update_nlocal = 2;
MYDBG(printf("# CUDA: Cuda::checkResize done...\n");)
}
void Cuda::evsetup_eatom_vatom(int eflag_atom,int vflag_atom)
{
if(eflag_atom)
{
if(not cu_eatom)
cu_eatom = new cCudaData<double, ENERGY_FLOAT, x > (force->pair->eatom, & (shared_data.atom.eatom) , atom->nmax );// cu_eatom->set_buffer(&(copy_buffer),&(copy_buffersize),true);}
cu_eatom->set_host_data(force->pair->eatom);
cu_eatom->memset_device(0);
}
if(vflag_atom)
{
if(not cu_vatom)
cu_vatom = new cCudaData<double, ENERGY_FLOAT, yx > ((double*)force->pair->vatom, & (shared_data.atom.vatom) , atom->nmax ,6 );// cu_vatom->set_buffer(&(copy_buffer),&(copy_buffersize),true);}
cu_vatom->set_host_data((double*)force->pair->vatom);
cu_vatom->memset_device(0);
}
}
void Cuda::uploadAll()
{
MYDBG(printf("# CUDA: Cuda::uploadAll() ... start\n");)
timespec starttime;
timespec endtime;
if(atom->nmax!=shared_data.atom.nmax) checkResize();
clock_gettime(CLOCK_REALTIME,&starttime);
cu_x ->upload();
cu_v ->upload();
cu_f ->upload();
cu_tag ->upload();
cu_type->upload();
cu_mask->upload();
cu_image->upload();
if(shared_data.atom.q_flag) cu_q ->upload();
if(atom->rmass) cu_rmass->upload();
if(atom->radius) cu_radius->upload();
if(atom->omega) cu_omega->upload();
if(atom->torque) cu_torque->upload();
if(atom->special) cu_special->upload();
if(atom->nspecial) cu_nspecial->upload();
if(atom->molecule) cu_molecule->upload();
if(cu_eatom) cu_eatom->upload();
if(cu_vatom) cu_vatom->upload();
clock_gettime(CLOCK_REALTIME,&endtime);
uploadtime+=(endtime.tv_sec-starttime.tv_sec+1.0*(endtime.tv_nsec-starttime.tv_nsec)/1000000000);
CUDA_IF_BINNING(Cuda_PreBinning(& shared_data);)
CUDA_IF_BINNING(Cuda_Binning (& shared_data);)
shared_data.atom.triggerneighsq=neighbor->triggersq;
MYDBG(printf("# CUDA: Cuda::uploadAll() ... end\n");)
}
void Cuda::downloadAll()
{
MYDBG(printf("# CUDA: Cuda::downloadAll() ... start\n");)
timespec starttime;
timespec endtime;
if(atom->nmax!=shared_data.atom.nmax) checkResize();
CUDA_IF_BINNING( Cuda_ReverseBinning(& shared_data); )
clock_gettime(CLOCK_REALTIME,&starttime);
cu_x ->download();
cu_v ->download();
cu_f ->download();
cu_type->download();
cu_tag ->download();
cu_mask->download();
cu_image->download();
//if(shared_data.atom.need_eatom) cu_eatom->download();
//if(shared_data.atom.need_vatom) cu_vatom->download();
if(shared_data.atom.q_flag) cu_q ->download();
if(atom->rmass) cu_rmass->download();
if(atom->radius) cu_radius->download();
if(atom->omega) cu_omega->download();
if(atom->torque) cu_torque->download();
if(atom->special) cu_special->download();
if(atom->nspecial) cu_nspecial->download();
if(atom->molecule) cu_molecule->download();
if(cu_eatom) cu_eatom->download();
if(cu_vatom) cu_vatom->download();
clock_gettime(CLOCK_REALTIME,&endtime);
downloadtime+=(endtime.tv_sec-starttime.tv_sec+1.0*(endtime.tv_nsec-starttime.tv_nsec)/1000000000);
MYDBG(printf("# CUDA: Cuda::downloadAll() ... end\n");)
}
void Cuda::downloadX()
{
Cuda_Pair_RevertXType(& this->shared_data);
cu_x->download();
}
CudaNeighList* Cuda::registerNeighborList(class NeighList* neigh_list)
{
MYDBG(printf("# CUDA: Cuda::registerNeighborList() ... start a\n");)
std::map<NeighList*, CudaNeighList*>::iterator p = neigh_lists.find(neigh_list);
if(p != neigh_lists.end()) return p->second;
else
{
CudaNeighList* neigh_list_cuda = new CudaNeighList(lmp, neigh_list);
neigh_lists.insert(std::pair<NeighList*, CudaNeighList*>(neigh_list, neigh_list_cuda));
return neigh_list_cuda;
}
MYDBG(printf("# CUDA: Cuda::registerNeighborList() ... end b\n");)
}
void Cuda::uploadAllNeighborLists()
{
MYDBG(printf("# CUDA: Cuda::uploadAllNeighborList() ... start\n");)
std::map<NeighList*, CudaNeighList*>::iterator p = neigh_lists.begin();
while(p != neigh_lists.end())
{
p->second->nl_upload();
if(not (p->second->neigh_list->cuda_list->build_cuda))
for(int i=0;i<atom->nlocal;i++)
p->second->sneighlist.maxneighbors=MAX(p->second->neigh_list->numneigh[i],p->second->sneighlist.maxneighbors) ;
++p;
}
MYDBG(printf("# CUDA: Cuda::uploadAllNeighborList() ... done\n");)
}
void Cuda::downloadAllNeighborLists()
{
MYDBG(printf("# CUDA: Cuda::downloadAllNeighborList() ... start\n");)
std::map<NeighList*, CudaNeighList*>::iterator p = neigh_lists.begin();
while(p != neigh_lists.end())
{
p->second->nl_download();
++p;
}
}
void Cuda::update_xhold(int &maxhold,double* xhold)
{
if(this->shared_data.atom.maxhold<atom->nmax)
{
maxhold = atom->nmax;
delete this->cu_xhold; this->cu_xhold = new cCudaData<double, X_FLOAT, yx> ((double*)xhold, & this->shared_data.atom.xhold , maxhold, 3);
}
this->shared_data.atom.maxhold=maxhold;
CudaWrapper_CopyData(this->cu_xhold->dev_data(),this->cu_x->dev_data(),3*atom->nmax*sizeof(X_FLOAT));
}
void Cuda::setTimingsZero()
{
shared_data.cuda_timings.test1=0;
shared_data.cuda_timings.test2=0;
//communication
shared_data.cuda_timings.comm_forward_total = 0;
shared_data.cuda_timings.comm_forward_mpi_upper = 0;
shared_data.cuda_timings.comm_forward_mpi_lower = 0;
shared_data.cuda_timings.comm_forward_kernel_pack = 0;
shared_data.cuda_timings.comm_forward_kernel_unpack = 0;
shared_data.cuda_timings.comm_forward_upload = 0;
shared_data.cuda_timings.comm_forward_download = 0;
shared_data.cuda_timings.comm_exchange_total = 0;
shared_data.cuda_timings.comm_exchange_mpi = 0;
shared_data.cuda_timings.comm_exchange_kernel_pack = 0;
shared_data.cuda_timings.comm_exchange_kernel_unpack = 0;
shared_data.cuda_timings.comm_exchange_kernel_fill = 0;
shared_data.cuda_timings.comm_exchange_cpu_pack= 0;
shared_data.cuda_timings.comm_exchange_upload = 0;
shared_data.cuda_timings.comm_exchange_download = 0;
shared_data.cuda_timings.comm_border_total = 0;
shared_data.cuda_timings.comm_border_mpi = 0;
shared_data.cuda_timings.comm_border_kernel_pack = 0;
shared_data.cuda_timings.comm_border_kernel_unpack = 0;
shared_data.cuda_timings.comm_border_kernel_buildlist = 0;
shared_data.cuda_timings.comm_border_kernel_self = 0;
shared_data.cuda_timings.comm_border_upload = 0;
shared_data.cuda_timings.comm_border_download = 0;
//pair forces
shared_data.cuda_timings.pair_xtype_conversion = 0;
shared_data.cuda_timings.pair_kernel = 0;
shared_data.cuda_timings.pair_virial = 0;
shared_data.cuda_timings.pair_force_collection = 0;
//neighbor
shared_data.cuda_timings.neigh_bin = 0;
shared_data.cuda_timings.neigh_build = 0;
shared_data.cuda_timings.neigh_special = 0;
//PPPM
shared_data.cuda_timings.pppm_particle_map = 0;
shared_data.cuda_timings.pppm_make_rho = 0;
shared_data.cuda_timings.pppm_brick2fft = 0;
shared_data.cuda_timings.pppm_poisson = 0;
shared_data.cuda_timings.pppm_fillbrick = 0;
shared_data.cuda_timings.pppm_fieldforce = 0;
shared_data.cuda_timings.pppm_compute = 0;
CudaWrapper_CheckUploadTime(true);
CudaWrapper_CheckDownloadTime(true);
CudaWrapper_CheckCPUBufUploadTime(true);
CudaWrapper_CheckCPUBufDownloadTime(true);
}
void Cuda::print_timings()
{
if(universe->me!=0) return;
if(not dotiming) return;
printf("\n # CUDA: Special timings\n\n");
printf("\n Transfer Times\n");
printf(" PCIe Upload: \t %lf s\n",CudaWrapper_CheckUploadTime());
printf(" PCIe Download:\t %lf s\n",CudaWrapper_CheckDownloadTime());
printf(" CPU Tempbbuf Upload: \t %lf \n",CudaWrapper_CheckCPUBufUploadTime());
printf(" CPU Tempbbuf Download: \t %lf \n",CudaWrapper_CheckCPUBufDownloadTime());
printf("\n Communication \n");
printf(" Forward Total \t %lf \n",shared_data.cuda_timings.comm_forward_total);
printf(" Forward MPI Upper Bound \t %lf \n",shared_data.cuda_timings.comm_forward_mpi_upper);
printf(" Forward MPI Lower Bound \t %lf \n",shared_data.cuda_timings.comm_forward_mpi_lower);
printf(" Forward Kernel Pack \t %lf \n",shared_data.cuda_timings.comm_forward_kernel_pack);
printf(" Forward Kernel Unpack \t %lf \n",shared_data.cuda_timings.comm_forward_kernel_unpack);
printf(" Forward Kernel Self \t %lf \n",shared_data.cuda_timings.comm_forward_kernel_self);
printf(" Forward Upload \t %lf \n",shared_data.cuda_timings.comm_forward_upload);
printf(" Forward Download \t %lf \n",shared_data.cuda_timings.comm_forward_download);
printf(" Forward Overlap Split Ratio\t %lf \n",shared_data.comm.overlap_split_ratio);
printf("\n");
printf(" Exchange Total \t %lf \n",shared_data.cuda_timings.comm_exchange_total);
printf(" Exchange MPI \t %lf \n",shared_data.cuda_timings.comm_exchange_mpi);
printf(" Exchange Kernel Pack \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_pack);
printf(" Exchange Kernel Unpack \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_unpack);
printf(" Exchange Kernel Fill \t %lf \n",shared_data.cuda_timings.comm_exchange_kernel_fill);
printf(" Exchange CPU Pack \t %lf \n",shared_data.cuda_timings.comm_exchange_cpu_pack);
printf(" Exchange Upload \t %lf \n",shared_data.cuda_timings.comm_exchange_upload);
printf(" Exchange Download \t %lf \n",shared_data.cuda_timings.comm_exchange_download);
printf("\n");
printf(" Border Total \t %lf \n",shared_data.cuda_timings.comm_border_total);
printf(" Border MPI \t %lf \n",shared_data.cuda_timings.comm_border_mpi);
printf(" Border Kernel Pack \t %lf \n",shared_data.cuda_timings.comm_border_kernel_pack);
printf(" Border Kernel Unpack \t %lf \n",shared_data.cuda_timings.comm_border_kernel_unpack);
printf(" Border Kernel Self \t %lf \n",shared_data.cuda_timings.comm_border_kernel_self);
printf(" Border Kernel BuildList \t %lf \n",shared_data.cuda_timings.comm_border_kernel_buildlist);
printf(" Border Upload \t %lf \n",shared_data.cuda_timings.comm_border_upload);
printf(" Border Download \t %lf \n",shared_data.cuda_timings.comm_border_download);
printf("\n");
//pair forces
printf(" Pair XType Conversion \t %lf \n",shared_data.cuda_timings.pair_xtype_conversion );
printf(" Pair Kernel \t %lf \n",shared_data.cuda_timings.pair_kernel );
printf(" Pair Virial \t %lf \n",shared_data.cuda_timings.pair_virial );
printf(" Pair Force Collection \t %lf \n",shared_data.cuda_timings.pair_force_collection );
printf("\n");
//neighbor
printf(" Neighbor Binning \t %lf \n",shared_data.cuda_timings.neigh_bin );
printf(" Neighbor Build \t %lf \n",shared_data.cuda_timings.neigh_build );
printf(" Neighbor Special \t %lf \n",shared_data.cuda_timings.neigh_special );
printf("\n");
//pppm
if(force->kspace)
{
printf(" PPPM Total \t %lf \n",shared_data.cuda_timings.pppm_compute );
printf(" PPPM Particle Map \t %lf \n",shared_data.cuda_timings.pppm_particle_map );
printf(" PPPM Make Rho \t %lf \n",shared_data.cuda_timings.pppm_make_rho );
printf(" PPPM Brick2fft \t %lf \n",shared_data.cuda_timings.pppm_brick2fft );
printf(" PPPM Poisson \t %lf \n",shared_data.cuda_timings.pppm_poisson );
printf(" PPPM Fillbrick \t %lf \n",shared_data.cuda_timings.pppm_fillbrick );
printf(" PPPM Fieldforce \t %lf \n",shared_data.cuda_timings.pppm_fieldforce );
printf("\n");
}
printf(" Debug Test 1 \t %lf \n",shared_data.cuda_timings.test1);
printf(" Debug Test 2 \t %lf \n",shared_data.cuda_timings.test2);
printf("\n");
}
diff --git a/src/USER-CUDA/pppm_cuda.h b/src/USER-CUDA/pppm_cuda.h
index 0becd762c..ffd3dded3 100644
--- a/src/USER-CUDA/pppm_cuda.h
+++ b/src/USER-CUDA/pppm_cuda.h
@@ -1,114 +1,115 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
Original Version:
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
-----------------------------------------------------------------------
USER-CUDA Package and associated modifications:
https://sourceforge.net/projects/lammpscuda/
Christian Trott, christian.trott@tu-ilmenau.de
Lars Winterfeld, lars.winterfeld@tu-ilmenau.de
Theoretical Physics II, University of Technology Ilmenau, Germany
See the README file in the USER-CUDA directory.
This software is distributed under the GNU General Public License.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
KSpaceStyle(pppm/cuda,PPPMCuda)
#else
#ifndef LMP_PPPM_CUDA_H
#define LMP_PPPM_CUDA_H
#include "pppm.h"
#include "cuda_data.h"
#include "cuda_precision.h"
namespace LAMMPS_NS {
class PPPMCuda : public PPPM {
public:
PPPMCuda(class LAMMPS *, int, char **);
~PPPMCuda();
void init();
void setup();
void compute(int, int);
void timing(int, double &, double &);
double poissontime;
+
protected:
class Cuda *cuda;
class FFT3dCuda *fft1c,*fft2c;
double* work3;
cCudaData<double , FFT_FLOAT , x >* cu_work1;
cCudaData<double , FFT_FLOAT , x >* cu_work2;
cCudaData<double , FFT_FLOAT , x >* cu_work3;
cCudaData<double , PPPM_FLOAT , x >* cu_greensfn;
cCudaData<double , PPPM_FLOAT , x >* cu_gf_b;
cCudaData<double , PPPM_FLOAT , x >* cu_fkx;
cCudaData<double , PPPM_FLOAT , x >* cu_fky;
cCudaData<double , PPPM_FLOAT , x >* cu_fkz;
cCudaData<double , PPPM_FLOAT , xy>* cu_vg;
cCudaData<double , PPPM_FLOAT , x >* cu_density_brick;
cCudaData<int , int , x >* cu_density_brick_int;
cCudaData<double , PPPM_FLOAT , x >* cu_vdx_brick;
cCudaData<double , PPPM_FLOAT , x >* cu_vdy_brick;
cCudaData<double , PPPM_FLOAT , x >* cu_vdz_brick;
cCudaData<double , PPPM_FLOAT , x >* cu_density_fft;
cCudaData<double , ENERGY_FLOAT , x >* cu_energy;
cCudaData<double , ENERGY_FLOAT , x >* cu_virial;
cCudaData<double , X_FLOAT , yx>* cu_x;
cCudaData<double , V_FLOAT , yx>* cu_v;
cCudaData<double , F_FLOAT , yx>* cu_f;
cCudaData<double , F_FLOAT , yx>* cu_q;
cCudaData<int , int , yx>* cu_part2grid;
cCudaData<double , PPPM_FLOAT , x >* cu_rho_coeff;
cCudaData<PPPM_FLOAT , PPPM_FLOAT , x >* cu_debugdata;
cCudaData<int , int , x >* cu_flag;
cCudaData<int , int , x >* cu_pppm_grid_n;
cCudaData<int , int , x >* cu_pppm_grid_ids;
ENERGY_FLOAT* slabbuf;
cCudaData<ENERGY_FLOAT, ENERGY_FLOAT, x >* cu_slabbuf;
int*** density_brick_int;
PPPM_FLOAT density_intScale;
int pppm_grid_nmax;
int* pppm2partgrid;
int* pppm_grid;
PPPM_FLOAT* debugdata;
bool firstpass;
void set_grid();
void make_power_of_prime(int* n);
void allocate();
void deallocate();
virtual void particle_map();
virtual void make_rho();
void poisson(int, int);
virtual void fieldforce();
virtual void slabcorr(int);
double*** vdx_brick_tmp;
int old_nmax;
int global_flag;
dev_array* adev_data_array;
char precisionmodify;
-
+ double qqrd2e;
};
}
#endif
#endif
diff --git a/src/USER-EWALDN/ewald_n.cpp b/src/USER-EWALDN/ewald_n.cpp
index ed05ca504..f3d7fe08d 100644
--- a/src/USER-EWALDN/ewald_n.cpp
+++ b/src/USER-EWALDN/ewald_n.cpp
@@ -1,698 +1,704 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Pieter J. in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "ewald_n.h"
#include "math_vector.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define KSPACE_ILLEGAL "Illegal kspace_style ewald/n command"
#define KSPACE_ORDER "Unsupported order in kspace_style ewald/n for"
#define KSPACE_MIX "Unsupported mixing rule in kspace_style ewald/n for"
enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // same as in pair.cpp
//#define DEBUG
/* ---------------------------------------------------------------------- */
EwaldN::EwaldN(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
{
if (narg!=1) error->all(FLERR,KSPACE_ILLEGAL);
precision = fabs(atof(arg[0]));
memset(function, 0, EWALD_NORDER*sizeof(int));
kenergy = kvirial = NULL;
cek_local = cek_global = NULL;
ekr_local = NULL;
hvec = NULL;
kvec = NULL;
B = NULL;
first_output = 0;
}
EwaldN::~EwaldN()
{
deallocate();
delete [] ekr_local;
delete [] B;
}
/* --------------------------------------------------------------------- */
void EwaldN::init()
{
nkvec = nkvec_max = nevec = nevec_max = 0;
nfunctions = nsums = sums = 0;
nbox = -1;
bytes = 0.0;
if (!comm->me) { // output message
if (screen) fprintf(screen,"EwaldN initialization ...\n");
if (logfile) fprintf(logfile,"EwaldN initialization ...\n");
}
if (domain->dimension == 2) // check for errors
error->all(FLERR,"Cannot use EwaldN with 2d simulation");
if (slabflag == 0 && domain->nonperiodic > 0)
error->all(FLERR,"Cannot use nonperiodic boundaries with EwaldN");
if (slabflag == 1) {
if (domain->xperiodic != 1 || domain->yperiodic != 1 ||
domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1)
error->all(FLERR,"Incorrect boundaries with slab EwaldN");
}
- qqrd2e = force->qqrd2e; // check pair_style
scale = 1.0;
//mumurd2e = force->mumurd2e;
//dielectric = force->dielectric;
mumurd2e = dielectric = 1.0;
int tmp;
Pair *pair = force->pair;
int *ptr = pair ? (int *) pair->extract("ewald_order",tmp) : NULL;
double *cutoff = pair ? (double *) pair->extract("cut_coul",tmp) : NULL;
if (!(ptr||cutoff))
error->all(FLERR,"KSpace style is incompatible with Pair style");
int ewald_order = ptr ? *((int *) ptr) : 1<<1;
int ewald_mix = ptr ? *((int *) pair->extract("ewald_mix",tmp)) : GEOMETRIC;
memset(function, 0, EWALD_NFUNCS*sizeof(int));
for (int i=0; i<=EWALD_NORDER; ++i) // transcribe order
if (ewald_order&(1<<i)) { // from pair_style
int n[] = EWALD_NSUMS, k;
char str[128];
switch (i) {
case 1:
k = 0; break;
case 3:
k = 3; break;
case 6:
if (ewald_mix==GEOMETRIC) { k = 1; break; }
else if (ewald_mix==ARITHMETIC) { k = 2; break; }
sprintf(str, "%s pair_style %s", KSPACE_MIX, force->pair_style);
error->all(FLERR,str);
default:
sprintf(str, "%s pair_style %s", KSPACE_ORDER, force->pair_style);
error->all(FLERR,str);
}
nfunctions += function[k] = 1;
nsums += n[k];
}
g_ewald = (1.35 - 0.15*log(precision))/ *cutoff; // determine resolution
g2_max = -4.0*g_ewald*g_ewald*log(precision);
if (!comm->me) { // output results
if (screen) fprintf(screen, " G vector = %g\n", g_ewald);
if (logfile) fprintf(logfile, " G vector = %g\n", g_ewald);
}
}
/* ----------------------------------------------------------------------
adjust EwaldN coeffs, called initially and whenever volume has changed
------------------------------------------------------------------------- */
void EwaldN::setup()
{
volume = shape_det(domain->h)*slab_volfactor; // cell volume
memcpy(unit, domain->h_inv, sizeof(shape)); // wave vector units
shape_scalar_mult(unit, 2.0*M_PI);
unit[2] /= slab_volfactor;
//int nbox_old = nbox, nkvec_old = nkvec;
if (precision>=1) nbox = 0;
else {
vector n = {1.0, 1.0, 1.0}; // based on cutoff
vec_scalar_mult(n, g_ewald*sqrt(-log(precision))/M_PI);
shape_vec_dot(n, n, domain->h);
n[2] *= slab_volfactor;
nbox = (int) n[0];
if (nbox<(int) n[1]) nbox = (int) n[1];
if (nbox<(int) n[2]) nbox = (int) n[2];
}
reallocate();
coefficients(); // compute coeffs
init_coeffs();
init_coeff_sums();
init_self();
if (!(first_output||comm->me)) { // output on first
first_output = 1;
if (screen) fprintf(screen,
" vectors: nbox = %d, nkvec = %d\n", nbox, nkvec);
if (logfile) fprintf(logfile,
" vectors: nbox = %d, nkvec = %d\n", nbox, nkvec);
}
}
void EwaldN::reallocate() // allocate memory
{
int ix, iy, iz;
int nkvec_max = nkvec;
vector h;
nkvec = 0; // determine size(kvec)
int kflag[(nbox+1)*(2*nbox+1)*(2*nbox+1)], *flag = kflag;
for (ix=0; ix<=nbox; ++ix)
for (iy=-nbox; iy<=nbox; ++iy)
for (iz=-nbox; iz<=nbox; ++iz)
if (!(ix||iy||iz)) *(flag++) = 0;
else if ((!ix)&&(iy<0)) *(flag++) = 0;
else if ((!(ix||iy))&&(iz<0)) *(flag++) = 0; // use symmetry
else {
h[0] = unit[0]*ix;
h[1] = unit[5]*ix+unit[1]*iy;
h[2] = unit[4]*ix+unit[3]*iy+unit[2]*iz;
if ((*(flag++) = h[0]*h[0]+h[1]*h[1]+h[2]*h[2]<=g2_max)) ++nkvec;
}
if (nkvec>nkvec_max) {
deallocate(); // free memory
hvec = new hvector[nkvec]; // hvec
bytes += (nkvec-nkvec_max)*sizeof(hvector);
kvec = new kvector[nkvec]; // kvec
bytes += (nkvec-nkvec_max)*sizeof(kvector);
kenergy = new double[nkvec*nfunctions]; // kenergy
bytes += (nkvec-nkvec_max)*nfunctions*sizeof(double);
kvirial = new double[6*nkvec*nfunctions]; // kvirial
bytes += 6*(nkvec-nkvec_max)*nfunctions*sizeof(double);
cek_local = new complex[nkvec*nsums]; // cek_local
bytes += (nkvec-nkvec_max)*nsums*sizeof(complex);
cek_global = new complex[nkvec*nsums]; // cek_global
bytes += (nkvec-nkvec_max)*nsums*sizeof(complex);
nkvec_max = nkvec;
}
flag = kflag; // create index and
kvector *k = kvec; // wave vectors
hvector *hi = hvec;
for (ix=0; ix<=nbox; ++ix)
for (iy=-nbox; iy<=nbox; ++iy)
for (iz=-nbox; iz<=nbox; ++iz)
if (*(flag++)) {
hi->x = unit[0]*ix;
hi->y = unit[5]*ix+unit[1]*iy;
(hi++)->z = unit[4]*ix+unit[3]*iy+unit[2]*iz;
k->x = ix+nbox; k->y = iy+nbox; (k++)->z = iz+nbox; }
}
void EwaldN::reallocate_atoms()
{
if ((nevec = atom->nmax*(2*nbox+1))<=nevec_max) return;
delete [] ekr_local;
ekr_local = new cvector[nevec];
bytes += (nevec-nevec_max)*sizeof(cvector);
nevec_max = nevec;
}
void EwaldN::deallocate() // free memory
{
delete [] hvec; hvec = NULL;
delete [] kvec; kvec = NULL;
delete [] kenergy; kenergy = NULL;
delete [] kvirial; kvirial = NULL;
delete [] cek_local; cek_local = NULL;
delete [] cek_global; cek_global = NULL;
}
void EwaldN::coefficients() // set up pre-factors
{
vector h;
hvector *hi = hvec, *nh;
double eta2 = 0.25/(g_ewald*g_ewald);
double b1, b2, expb2, h1, h2, c1, c2;
double *ke = kenergy, *kv = kvirial;
int func0 = function[0], func12 = function[1]||function[2],
func3 = function[3];
for (nh = (hi = hvec)+nkvec; hi<nh; ++hi) { // wave vectors
memcpy(h, hi, sizeof(vector));
expb2 = exp(-(b2 = (h2 = vec_dot(h, h))*eta2));
if (func0) { // qi*qj/r coeffs
*(ke++) = c1 = expb2/h2;
*(kv++) = c1-(c2 = 2.0*c1*(1.0+b2)/h2)*h[0]*h[0];
*(kv++) = c1-c2*h[1]*h[1]; // lammps convention
*(kv++) = c1-c2*h[2]*h[2]; // instead of voigt
*(kv++) = -c2*h[1]*h[0];
*(kv++) = -c2*h[2]*h[0];
*(kv++) = -c2*h[2]*h[1];
}
if (func12) { // -Bij/r^6 coeffs
b1 = sqrt(b2); // minus sign folded
h1 = sqrt(h2); // into constants
*(ke++) = c1 = -h1*h2*((c2=sqrt(M_PI)*erfc(b1))+(0.5/b2-1.0)*expb2/b1);
*(kv++) = c1-(c2 = 3.0*h1*(c2-expb2/b1))*h[0]*h[0];
*(kv++) = c1-c2*h[1]*h[1]; // lammps convention
*(kv++) = c1-c2*h[2]*h[2]; // instead of voigt
*(kv++) = -c2*h[1]*h[0];
*(kv++) = -c2*h[2]*h[0];
*(kv++) = -c2*h[2]*h[1];
}
if (func3) { // dipole coeffs
*(ke++) = c1 = expb2/h2;
*(kv++) = c1-(c2 = 2.0*c1*(1.0+b2)/h2)*h[0]*h[0];
*(kv++) = c1-c2*h[1]*h[1]; // lammps convention
*(kv++) = c1-c2*h[2]*h[2]; // instead of voigt
*(kv++) = -c2*h[1]*h[0];
*(kv++) = -c2*h[2]*h[0];
*(kv++) = -c2*h[2]*h[1];
}
}
}
void EwaldN::init_coeffs() // local pair coeffs
{
int tmp;
int n = atom->ntypes;
if (function[1]) { // geometric 1/r^6
double **b = (double **) force->pair->extract("B",tmp);
delete [] B;
B = new double[n+1];
bytes += (n+1)*sizeof(double);
for (int i=0; i<=n; ++i) B[i] = sqrt(fabs(b[i][i]));
}
if (function[2]) { // arithmetic 1/r^6
double **epsilon = (double **) force->pair->extract("epsilon",tmp);
double **sigma = (double **) force->pair->extract("sigma",tmp);
if (!(epsilon&&sigma))
error->all(FLERR,"epsilon or sigma reference not set by pair style in ewald/n");
double eps_i, sigma_i, sigma_n, *bi = B = new double[7*n+7];
double c[7] = {
1.0, sqrt(6.0), sqrt(15.0), sqrt(20.0), sqrt(15.0), sqrt(6.0), 1.0};
for (int i=0; i<=n; ++i) {
eps_i = sqrt(epsilon[i][i]);
sigma_i = sigma[i][i];
sigma_n = 1.0;
for (int j=0; j<7; ++j) {
*(bi++) = sigma_n*eps_i*c[j]; sigma_n *= sigma_i;
}
}
}
}
void EwaldN::init_coeff_sums() // sums based on atoms
{
if (sums) return; // calculated only once
sums = 1;
Sum sum_local[EWALD_MAX_NSUMS];
memset(sum_local, 0, EWALD_MAX_NSUMS*sizeof(Sum));
if (function[0]) { // 1/r
double *q = atom->q, *qn = q+atom->nlocal;
for (double *i=q; i<qn; ++i) {
sum_local[0].x += i[0]; sum_local[0].x2 += i[0]*i[0]; }
}
if (function[1]) { // geometric 1/r^6
int *type = atom->type, *ntype = type+atom->nlocal;
for (int *i=type; i<ntype; ++i) {
sum_local[1].x += B[i[0]]; sum_local[1].x2 += B[i[0]]*B[i[0]]; }
}
if (function[2]) { // aritmetic 1/r^6
double *bi;
int *type = atom->type, *ntype = type+atom->nlocal;
for (int *i=type; i<ntype; ++i) {
bi = B+7*i[0];
sum_local[2].x2 += bi[0]*bi[6];
for (int k=2; k<9; ++k) sum_local[k].x += *(bi++);
}
}
if (function[3]) { // dipole
double **mu = atom->mu;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
sum_local[9].x2 += mu[i][3]*mu[i][3];
}
MPI_Allreduce(sum_local, sum, 2*EWALD_MAX_NSUMS, MPI_DOUBLE, MPI_SUM, world);
}
void EwaldN::init_self()
{
double g1 = g_ewald, g2 = g1*g1, g3 = g1*g2;
memset(energy_self, 0, EWALD_NFUNCS*sizeof(double)); // self energy
memset(virial_self, 0, EWALD_NFUNCS*sizeof(double));
+ const double qscale = force->qqrd2e * scale;
+
if (function[0]) { // 1/r
- virial_self[0] = -0.5*M_PI*qqrd2e*scale/(g2*volume)*sum[0].x*sum[0].x;
- energy_self[0] = sum[0].x2*qqrd2e*scale*g1/sqrt(M_PI)-virial_self[0];
+ virial_self[0] = -0.5*M_PI*qscale/(g2*volume)*sum[0].x*sum[0].x;
+ energy_self[0] = sum[0].x2*qscale*g1/sqrt(M_PI)-virial_self[0];
}
if (function[1]) { // geometric 1/r^6
virial_self[1] = M_PI*sqrt(M_PI)*g3/(6.0*volume)*sum[1].x*sum[1].x;
energy_self[1] = -sum[1].x2*g3*g3/12.0+virial_self[1];
}
if (function[2]) { // arithmetic 1/r^6
virial_self[2] = M_PI*sqrt(M_PI)*g3/(48.0*volume)*(sum[2].x*sum[8].x+
sum[3].x*sum[7].x+sum[4].x*sum[6].x+0.5*sum[5].x*sum[5].x);
energy_self[2] = -sum[2].x2*g3*g3/3.0+virial_self[2];
}
if (function[3]) { // dipole
virial_self[3] = 0; // in surface
energy_self[3] = sum[9].x2*mumurd2e*2.0*g3/3.0/sqrt(M_PI)-virial_self[3];
}
}
/* ----------------------------------------------------------------------
compute the EwaldN long-range force, energy, virial
------------------------------------------------------------------------- */
void EwaldN::compute(int eflag, int vflag)
{
if (!nbox) return;
reallocate_atoms();
compute_ek();
compute_force();
compute_surface();
compute_energy(eflag);
compute_virial(vflag);
}
void EwaldN::compute_ek()
{
cvector *ekr = ekr_local;
int lbytes = (2*nbox+1)*sizeof(cvector);
hvector *h;
kvector *k, *nk = kvec+nkvec;
cvector z1, z[2*nbox+1], *zx, *zy, *zz, *zn = z+2*nbox;
complex *cek, zxyz, zxy, cx;
vector mui;
double *x = atom->x[0], *xn = x+3*atom->nlocal, *q = atom->q, qi, bi, ci[7];
double *mu = atom->mu ? atom->mu[0] : NULL;
int i, kx, ky, n = nkvec*nsums, *type = atom->type, tri = domain->triclinic;
int func[EWALD_NFUNCS];
memcpy(func, function, EWALD_NFUNCS*sizeof(int));
memset(cek_local, 0, n*sizeof(complex)); // reset sums
while (x<xn) {
zx = (zy = (zz = z+nbox)+1)-2;
C_SET(zz->x, 1, 0); C_SET(zz->y, 1, 0); C_SET(zz->z, 1, 0); // z[0]
if (tri) { // triclinic z[1]
C_ANGLE(z1.x, unit[0]*x[0]+unit[5]*x[1]+unit[4]*x[2]);
C_ANGLE(z1.y, unit[1]*x[1]+unit[3]*x[2]);
C_ANGLE(z1.z, x[2]*unit[2]); x += 3;
}
else { // orthogonal z[1]
C_ANGLE(z1.x, *(x++)*unit[0]);
C_ANGLE(z1.y, *(x++)*unit[1]);
C_ANGLE(z1.z, *(x++)*unit[2]);
}
for (; zz<zn; --zx, ++zy, ++zz) { // set up z[k]=e^(ik.r)
C_RMULT(zy->x, zz->x, z1.x); // 3D k-vector
C_RMULT(zy->y, zz->y, z1.y); C_CONJ(zx->y, zy->y);
C_RMULT(zy->z, zz->z, z1.z); C_CONJ(zx->z, zy->z);
}
kx = ky = -1;
cek = cek_local;
if (func[0]) qi = *(q++);
if (func[1]) bi = B[*type];
if (func[2]) memcpy(ci, B+7*type[0], 7*sizeof(double));
if (func[3]) {
memcpy(mui, mu, sizeof(vector)); mu += 3;
vec_scalar_mult(mui, mu[3]);
mu += 4;
h = hvec;
}
for (k=kvec; k<nk; ++k) { // compute rho(k)
if (ky!=k->y) { // based on order in
if (kx!=k->x) cx = z[kx = k->x].x; // reallocate
C_RMULT(zxy, z[ky = k->y].y, cx);
}
C_RMULT(zxyz, z[k->z].z, zxy);
if (func[0]) {
cek->re += zxyz.re*qi; (cek++)->im += zxyz.im*qi;
}
if (func[1]) {
cek->re += zxyz.re*bi; (cek++)->im += zxyz.im*bi;
}
if (func[2]) for (i=0; i<7; ++i) {
cek->re += zxyz.re*ci[i]; (cek++)->im += zxyz.im*ci[i];
}
if (func[3]) {
register double muk = mui[0]*h->x+mui[1]*h->y+mui[2]*h->z; ++h;
cek->re += zxyz.re*muk; (cek++)->im += zxyz.im*muk;
}
}
ekr = (cvector *) ((char *) memcpy(ekr, z, lbytes)+lbytes);
++type;
}
MPI_Allreduce(cek_local, cek_global, 2*n, MPI_DOUBLE, MPI_SUM, world);
}
void EwaldN::compute_force()
{
kvector *k;
hvector *h, *nh;
cvector *z = ekr_local;
vector sum[EWALD_MAX_NSUMS], mui;
complex *cek, zc, zx, zxy;
double *f = atom->f[0], *fn = f+3*atom->nlocal, *q = atom->q, *t = NULL;
double *mu = atom->mu ? atom->mu[0] : NULL;
+ const double qscale = force->qqrd2e * scale;
double *ke, c[EWALD_NFUNCS] = {
- 8.0*M_PI*qqrd2e*scale/volume, 2.0*M_PI*sqrt(M_PI)/(12.0*volume),
+ 8.0*M_PI*qscale/volume, 2.0*M_PI*sqrt(M_PI)/(12.0*volume),
2.0*M_PI*sqrt(M_PI)/(192.0*volume), 8.0*M_PI*mumurd2e/volume};
double kt = 4.0*pow(g_ewald, 3.0)/3.0/sqrt(M_PI)/c[3];
int i, kx, ky, lbytes = (2*nbox+1)*sizeof(cvector), *type = atom->type;
int func[EWALD_NFUNCS];
if (atom->torque) t = atom->torque[0];
memcpy(func, function, EWALD_NFUNCS*sizeof(int));
memset(sum, 0, EWALD_MAX_NSUMS*sizeof(vector)); // fj = -dE/dr =
for (; f<fn; f+=3) { // -i*qj*fac*
k = kvec; // Sum[conj(d)-d]
kx = ky = -1; // d = k*conj(ekj)*ek
ke = kenergy;
cek = cek_global;
memset(sum, 0, EWALD_MAX_NSUMS*sizeof(vector));
if (func[3]) {
register double di = mu[3] * c[3];
mui[0] = di*(mu++)[0]; mui[1] = di*(mu++)[1]; mui[2] = di*(mu++)[2];
mu++;
}
for (nh = (h = hvec)+nkvec; h<nh; ++h, ++k) {
if (ky!=k->y) { // based on order in
if (kx!=k->x) zx = z[kx = k->x].x; // reallocate
C_RMULT(zxy, z[ky = k->y].y, zx);
}
C_CRMULT(zc, z[k->z].z, zxy);
if (func[0]) { // 1/r
register double im = *(ke++)*(zc.im*cek->re+cek->im*zc.re); ++cek;
sum[0][0] += h->x*im; sum[0][1] += h->y*im; sum[0][2] += h->z*im;
}
if (func[1]) { // geometric 1/r^6
register double im = *(ke++)*(zc.im*cek->re+cek->im*zc.re); ++cek;
sum[1][0] += h->x*im; sum[1][1] += h->y*im; sum[1][2] += h->z*im;
}
if (func[2]) { // arithmetic 1/r^6
register double im, c = *(ke++);
for (i=2; i<9; ++i) {
im = c*(zc.im*cek->re+cek->im*zc.re); ++cek;
sum[i][0] += h->x*im; sum[i][1] += h->y*im; sum[i][2] += h->z*im;
}
}
if (func[3]) { // dipole
register double im = *(ke++)*(zc.im*cek->re+
cek->im*zc.re)*(mui[0]*h->x+mui[1]*h->y+mui[2]*h->z); ++cek;
sum[9][0] += h->x*im; sum[9][1] += h->y*im; sum[9][2] += h->z*im;
}
}
if (func[0]) { // 1/r
register double qi = *(q++)*c[0];
f[0] -= sum[0][0]*qi; f[1] -= sum[0][1]*qi; f[2] -= sum[0][2]*qi;
}
if (func[1]) { // geometric 1/r^6
register double bi = B[*type]*c[1];
f[0] -= sum[1][0]*bi; f[1] -= sum[1][1]*bi; f[2] -= sum[1][2]*bi;
}
if (func[2]) { // arithmetic 1/r^6
register double *bi = B+7*type[0]+7;
for (i=2; i<9; ++i) {
register double c2 = (--bi)[0]*c[2];
f[0] -= sum[i][0]*c2; f[1] -= sum[i][1]*c2; f[2] -= sum[i][2]*c2;
}
}
if (func[3]) { // dipole
f[0] -= sum[9][0]; f[1] -= sum[9][1]; f[2] -= sum[9][2];
*(t++) -= mui[1]*sum[0][2]+mui[2]*sum[0][1]-mui[0]*kt; // torque
*(t++) -= mui[2]*sum[0][0]+mui[0]*sum[0][2]-mui[1]*kt;
*(t++) -= mui[0]*sum[0][1]+mui[1]*sum[0][0]-mui[2]*kt;
}
z = (cvector *) ((char *) z+lbytes);
++type;
}
}
void EwaldN::compute_surface()
{
if (!function[3]) return;
vector sum_local = VECTOR_NULL, sum_total;
double **mu = atom->mu;
int nlocal = atom->nlocal;
for (int i=0; i < nlocal; i++) {
register double di = mu[i][3];
sum_local[0] += di*mu[i][0];
sum_local[1] += di*mu[i][1];
sum_local[2] += di*mu[i][2];
}
MPI_Allreduce(sum_local, sum_total, 3, MPI_DOUBLE, MPI_SUM, world);
energy_self[3] += virial_self[3];
virial_self[3] =
mumurd2e*(2.0*M_PI*vec_dot(sum_total,sum_total)/(2.0*dielectric+1)/volume);
energy_self[3] -= virial_self[3];
}
void EwaldN::compute_energy(int eflag)
{
energy = 0.0;
if (!eflag) return;
complex *cek = cek_global;
double *ke = kenergy;
+ const double qscale = force->qqrd2e * scale;
double c[EWALD_NFUNCS] = {
- 4.0*M_PI*qqrd2e*scale/volume, 2.0*M_PI*sqrt(M_PI)/(24.0*volume),
+ 4.0*M_PI*qscale/volume, 2.0*M_PI*sqrt(M_PI)/(24.0*volume),
2.0*M_PI*sqrt(M_PI)/(192.0*volume), 4.0*M_PI*mumurd2e/volume};
double sum[EWALD_NFUNCS];
int func[EWALD_NFUNCS];
memcpy(func, function, EWALD_NFUNCS*sizeof(int));
memset(sum, 0, EWALD_NFUNCS*sizeof(double)); // reset sums
for (int k=0; k<nkvec; ++k) { // sum over k vectors
if (func[0]) { // 1/r
sum[0] += *(ke++)*(cek->re*cek->re+cek->im*cek->im); ++cek; }
if (func[1]) { // geometric 1/r^6
sum[1] += *(ke++)*(cek->re*cek->re+cek->im*cek->im); ++cek; }
if (func[2]) { // arithmetic 1/r^6
register double r =
(cek[0].re*cek[6].re+cek[0].im*cek[6].im)+
(cek[1].re*cek[5].re+cek[1].im*cek[5].im)+
(cek[2].re*cek[4].re+cek[2].im*cek[4].im)+
0.5*(cek[3].re*cek[3].re+cek[3].im*cek[3].im); cek += 7;
sum[2] += *(ke++)*r;
}
if (func[3]) { // dipole
sum[3] += *(ke++)*(cek->re*cek->re+cek->im*cek->im); ++cek; }
}
for (int k=0; k<EWALD_NFUNCS; ++k) energy += c[k]*sum[k]-energy_self[k];
if (slabflag) compute_slabcorr(eflag);
}
#define swap(a, b) { register double t = a; a= b; b = t; }
void EwaldN::compute_virial(int vflag)
{
memset(virial, 0, sizeof(shape));
if (!vflag) return;
complex *cek = cek_global;
double *kv = kvirial;
+ const double qscale = force->qqrd2e * scale;
double c[EWALD_NFUNCS] = {
- 4.0*M_PI*qqrd2e*scale/volume, 2.0*M_PI*sqrt(M_PI)/(24.0*volume),
+ 4.0*M_PI*qscale/volume, 2.0*M_PI*sqrt(M_PI)/(24.0*volume),
2.0*M_PI*sqrt(M_PI)/(192.0*volume), 4.0*M_PI*mumurd2e/volume};
shape sum[EWALD_NFUNCS];
int func[EWALD_NFUNCS];
memcpy(func, function, EWALD_NFUNCS*sizeof(int));
memset(sum, 0, EWALD_NFUNCS*sizeof(shape));
for (int k=0; k<nkvec; ++k) { // sum over k vectors
if (func[0]) { // 1/r
register double r = cek->re*cek->re+cek->im*cek->im; ++cek;
sum[0][0] += *(kv++)*r; sum[0][1] += *(kv++)*r; sum[0][2] += *(kv++)*r;
sum[0][3] += *(kv++)*r; sum[0][4] += *(kv++)*r; sum[0][5] += *(kv++)*r;
}
if (func[1]) { // geometric 1/r^6
register double r = cek->re*cek->re+cek->im*cek->im; ++cek;
sum[1][0] += *(kv++)*r; sum[1][1] += *(kv++)*r; sum[1][2] += *(kv++)*r;
sum[1][3] += *(kv++)*r; sum[1][4] += *(kv++)*r; sum[1][5] += *(kv++)*r;
}
if (func[2]) { // arithmetic 1/r^6
register double r =
(cek[0].re*cek[6].re+cek[0].im*cek[6].im)+
(cek[1].re*cek[5].re+cek[1].im*cek[5].im)+
(cek[2].re*cek[4].re+cek[2].im*cek[4].im)+
0.5*(cek[3].re*cek[3].re+cek[3].im*cek[3].im); cek += 7;
sum[2][0] += *(kv++)*r; sum[2][1] += *(kv++)*r; sum[2][2] += *(kv++)*r;
sum[2][3] += *(kv++)*r; sum[2][4] += *(kv++)*r; sum[2][5] += *(kv++)*r;
}
if (func[3]) {
register double r = cek->re*cek->re+cek->im*cek->im; ++cek;
sum[3][0] += *(kv++)*r; sum[3][1] += *(kv++)*r; sum[3][2] += *(kv++)*r;
sum[3][3] += *(kv++)*r; sum[3][4] += *(kv++)*r; sum[3][5] += *(kv++)*r;
}
}
for (int k=0; k<EWALD_NFUNCS; ++k)
if (func[k]) {
shape self = {virial_self[k], virial_self[k], virial_self[k], 0, 0, 0};
shape_scalar_mult(sum[k], c[k]);
shape_add(virial, sum[k]);
shape_subtr(virial, self);
}
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2-D EwaldN if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void EwaldN::compute_slabcorr(int eflag)
{
// compute local contribution to global dipole moment
double *q = atom->q;
double *x = atom->x[0]-1, *xn = x+3*atom->nlocal-1;
double dipole = 0.0, dipole_all;
while ((x+=3)<xn) dipole += *x * *(q++);
MPI_Allreduce(&dipole, &dipole_all, 1, MPI_DOUBLE, MPI_SUM, world);
+
+ const double qscale = force->qqrd2e * scale;
- double ffact = -4.0*M_PI*qqrd2e*scale*dipole_all/volume;
+ double ffact = -4.0*M_PI*qscale*dipole_all/volume;
double *f = atom->f[0]-1, *fn = f+3*atom->nlocal-3;
q = atom->q;
while ((f+=3)<fn) *f += ffact* *(q++);
if (eflag) // energy correction
- energy += qqrd2e*scale*(2.0*M_PI*dipole_all*dipole_all/volume);
+ energy += qscale*(2.0*M_PI*dipole_all*dipole_all/volume);
}
diff --git a/src/USER-EWALDN/ewald_n.h b/src/USER-EWALDN/ewald_n.h
index 721b45cce..2bec48532 100644
--- a/src/USER-EWALDN/ewald_n.h
+++ b/src/USER-EWALDN/ewald_n.h
@@ -1,82 +1,82 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
KSpaceStyle(ewald/n,EwaldN)
#else
#ifndef LMP_EWALD_N_H
#define LMP_EWALD_N_H
#include "kspace.h"
#include "math_complex.h"
namespace LAMMPS_NS {
#define EWALD_NORDER 6
#define EWALD_NFUNCS 4
#define EWALD_MAX_NSUMS 10
#define EWALD_NSUMS {1, 1, 7, 1}
typedef struct cvector { complex x, y, z; } cvector;
typedef struct hvector { double x, y, z; } hvector;
typedef struct kvector { long x, y, z; } kvector;
class EwaldN : public KSpace {
public:
EwaldN(class LAMMPS *, int, char **);
~EwaldN();
void init();
void setup();
void compute(int, int);
double memory_usage() {return bytes;}
private:
double unit[6];
int function[EWALD_NFUNCS], first_output;
int nkvec, nkvec_max, nevec, nevec_max,
nbox, nfunctions, nsums, sums;
double bytes;
double precision, g2_max;
double *kenergy, energy_self[EWALD_NFUNCS];
double *kvirial, virial_self[EWALD_NFUNCS];
cvector *ekr_local;
hvector *hvec;
kvector *kvec;
- double qqrd2e, mumurd2e, dielectric, *B, volume;
+ double mumurd2e, dielectric, *B, volume;
struct Sum { double x, x2; } sum[EWALD_MAX_NSUMS];
complex *cek_local, *cek_global;
void reallocate();
void reallocate_atoms();
void deallocate();
void coefficients();
void init_coeffs();
void init_coeff_sums();
void init_self();
void compute_ek();
void compute_force();
void compute_surface();
void compute_energy(int);
void compute_virial(int);
void compute_slabcorr(int);
};
}
#endif
#endif
diff --git a/src/USER-MISC/Install.sh b/src/USER-MISC/Install.sh
index d15156fdb..eb37f4815 100644
--- a/src/USER-MISC/Install.sh
+++ b/src/USER-MISC/Install.sh
@@ -1,67 +1,75 @@
# Install/unInstall package files in LAMMPS
if (test $1 = 1) then
cp angle_cosine_shift.cpp ..
cp angle_cosine_shift_exp.cpp ..
cp bond_harmonic_shift.cpp ..
cp bond_harmonic_shift_cut.cpp ..
cp compute_ackland_atom.cpp ..
cp compute_temp_rotate.cpp ..
cp dihedral_cosine_shift_exp.cpp ..
cp fix_addtorque.cpp ..
cp fix_imd.cpp ..
cp fix_smd.cpp ..
cp pair_cdeam.cpp ..
+ cp pair_coul_diel.cpp ..
cp pair_dipole_sf.cpp ..
cp pair_edip.cpp ..
+ cp pair_gauss_cut.cpp ..
cp pair_lj_sf.cpp ..
cp angle_cosine_shift.h ..
cp angle_cosine_shift_exp.h ..
cp bond_harmonic_shift.h ..
cp bond_harmonic_shift_cut.h ..
cp compute_ackland_atom.h ..
cp compute_temp_rotate.h ..
cp dihedral_cosine_shift_exp.h ..
cp fix_addtorque.h ..
cp fix_imd.h ..
cp fix_smd.h ..
cp pair_cdeam.h ..
+ cp pair_coul_diel.h ..
cp pair_dipole_sf.h ..
cp pair_edip.h ..
- cp pair_lj_sf.h ..
+ cp pair_gauss_cut.h ..
+ cp pair_lj_sf.h..
elif (test $1 = 0) then
rm -f ../angle_cosine_shift.cpp
rm -f ../angle_cosine_shift_exp.cpp
rm -f ../bond_harmonic_shift.cpp
rm -f ../bond_harmonic_shift_cut.cpp
rm -f ../compute_ackland_atom.cpp
rm -f ../compute_temp_rotate.cpp
rm -f ../dihedral_cosine_shift_exp.cpp
rm -f ../fix_addtorque.cpp
rm -f ../fix_imd.cpp
rm -f ../fix_smd.cpp
rm -f ../pair_cdeam.cpp
+ rm -f ../pair_coul_diel.cpp
rm -f ../pair_dipole_sf.cpp
rm -f ../pair_edip.cpp
+ rm -f ../pair_gauss_cut.cpp
rm -f ../pair_lj_sf.cpp
rm -f ../angle_cosine_shift.h
rm -f ../angle_cosine_shift_exp.h
rm -f ../bond_harmonic_shift.h
rm -f ../bond_harmonic_shift_cut.h
rm -f ../compute_ackland_atom.h
rm -f ../compute_temp_rotate.h
rm -f ../dihedral_cosine_shift_exp.h
rm -f ../fix_addtorque.h
rm -f ../fix_imd.h
rm -f ../fix_smd.h
rm -f ../pair_cdeam.h
+ rm -f ../pair_coul_diel.h
rm -f ../pair_dipole_sf.h
rm -f ../pair_edip.h
+ rm -f ../pair_gauss_cut.h
rm -f ../pair_lj_sf.h
fi
diff --git a/src/USER-MISC/README b/src/USER-MISC/README
index 5eb9f8de3..962702153 100644
--- a/src/USER-MISC/README
+++ b/src/USER-MISC/README
@@ -1,34 +1,37 @@
The files in this package are a potpourri of (mostly) unrelated
features contributed to LAMMPS by users. Each feature is a single
pair of files (*.cpp and *.h).
More information about each feature can be found by reading its doc
page in the LAMMPS doc directory. The doc page which lists all LAMMPS
input script commands is as follows:
doc/Section_commands.html, subsection 3.5
User-contributed features are listed at the bottom of the fix,
compute, pair, etc sections.
The list of features and author of each is given below.
You should contact the author directly if you have specific questions
about the feature or its coding.
------------------------------------------------------------
angle_style cosine/shift, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
angle_style cosine/shift/exp, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
bond_style harmonic/shift, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
bond_style harmonic/shift/cut, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
compute ackland/atom, Gerolf Ziegenhain, gerolf at ziegenhain.com, 4 Oct 2007
compute temp/rotate, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11
dihedral_style cosine/shift/exp, Carsten Svaneborg, science at zqex.dk, 8 Aug 11
fix addtorque, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11
fix imd, Axel Kohlmeyer, akohlmey at gmail.com, 9 Nov 2009
fix smd, Axel Kohlmeyer, akohlmey at gmail.com, 19 May 2008
+pair_style coul/diel, Axel Kohlmeyer, akohlmey at gmail.com, 1 Dec 11
pair_style dipole/sf, Mario Orsi, orsimario at gmail.com, 8 Aug 11
pair_style edip, Luca Ferraro, luca.ferraro at caspur.it, 15 Sep 11
pair_style eam/cd, Alexander Stukowski, stukowski at mm.tu-darmstadt.de, 7 Nov 09
+pair_style gauss/cut, Axel Kohlmeyer, akohlmey at gmail.com, 1 Dec 11
pair_style lj/sf, Laurent Joly (U Lyon), ljoly.ulyon at gmail.com, 8 Aug 11
+pair_style tersoff/table, Luca Ferraro, luca.ferraro@caspur.it, 1 Dec 11
diff --git a/src/USER-MISC/pair_coul_diel.cpp b/src/USER-MISC/pair_coul_diel.cpp
new file mode 100644
index 000000000..7f63b1a20
--- /dev/null
+++ b/src/USER-MISC/pair_coul_diel.cpp
@@ -0,0 +1,348 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ Contributiong authors: Arben Jusufi, Axel Kohlmeyer (Temple U.)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_coul_diel.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulDiel::PairCoulDiel(LAMMPS *lmp) : Pair(lmp) {}
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulDiel::~PairCoulDiel()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(sigmae);
+ memory->destroy(rme);
+ memory->destroy(offset);
+ memory->destroy(cutsq);
+ memory->destroy(cut);
+ allocated = 0;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCoulDiel::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
+ double rsq,r,rarg,th,depsdr,epsr,forcecoul,factor_coul;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ ecoul = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_coul = force->special_coul;
+ int newton_pair = force->newton_pair;
+ double qqrd2e = force->qqrd2e;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+
+ factor_coul = special_coul[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r = sqrt(rsq);
+ rarg = (r-rme[itype][jtype])/sigmae[itype][jtype];
+ th=tanh(rarg);
+ epsr=a_eps+b_eps*th;
+ depsdr=b_eps * (1.0 - th*th) / sigmae[itype][jtype];
+
+ forcecoul = qqrd2e*qtmp*q[j]*((eps_s*(epsr+r*depsdr)/epsr/epsr) -1.)/rsq;
+ fpair = factor_coul*forcecoul/r;
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (eflag) {
+ ecoul = (qqrd2e*qtmp*q[j]*((eps_s/epsr) -1.)/r) - offset[itype][jtype];
+ ecoul *= factor_coul;
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,0.0,
+ ecoul,fpair,delx,dely,delz);
+ }
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(sigmae,n+1,n+1,"pair:sigmae");
+ memory->create(rme,n+1,n+1,"pair:rme");
+ memory->create(offset,n+1,n+1,"pair:offset");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // reset cutoffs that have been explicitly set
+
+ if (allocated) {
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i+1; j <= atom->ntypes; j++)
+ if (setflag[i][j]) cut[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::coeff(int narg, char **arg)
+{
+ if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ eps_s = force->numeric(arg[2]);
+ double rme_one =force->numeric(arg[3]);
+ double sigmae_one = force->numeric(arg[4]);
+
+ double cut_one = cut_global;
+ if (narg == 6) cut_one = force->numeric(arg[5]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ sigmae[i][j] = sigmae_one;
+ rme[i][j] = rme_one;
+ cut[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+ a_eps = 0.5*(5.2+eps_s);
+ b_eps = 0.5*(eps_s-5.2);
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::init_style()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Pair style coul/diel requires atom attribute q");
+
+ int irequest = neighbor->request(this);
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairCoulDiel::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) {
+ error->all(FLERR,"for pair style coul/diel, parameters need to be set explicitly for all pairs.");
+ }
+
+ double *q = atom->q;
+ double qqrd2e = force->qqrd2e;
+
+ if (offset_flag) {
+ double rarg = (cut[i][j]-rme[i][j])/sigmae[i][j];
+ double epsr=a_eps+b_eps*tanh(rarg);
+ offset[i][j] = qqrd2e*q[i]*q[j]*((eps_s/epsr) -1.)/cut[i][j];
+ } else offset[i][j] = 0.0;
+
+
+ sigmae[j][i] = sigmae[i][j];
+ rme[j][i] = rme[i][j];
+ offset[j][i] = offset[i][j];
+ cut[j][i] = cut[i][j];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&rme[i][j],sizeof(double),1,fp);
+ fwrite(&sigmae[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (setflag[i][j]) {
+ if (me == 0) {
+ fread(&rme[i][j],sizeof(double),1,fp);
+ fread(&sigmae[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&rme[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigmae[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::write_restart_settings(FILE *fp)
+{
+ fwrite(&cut_global,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairCoulDiel::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCoulDiel::single(int i, int j, int itype, int jtype,
+ double rsq, double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double r, rarg,forcedielec,phidielec;
+ double th,epsr,depsdr;
+ double *q = atom->q;
+ double qqrd2e = force->qqrd2e;
+
+ r=sqrt(rsq);
+ rarg = (r-rme[itype][jtype])/sigmae[itype][jtype];
+ th = tanh(rarg);
+ epsr=a_eps+b_eps*th;
+ depsdr=b_eps*(1.-th*th)/sigmae[itype][jtype];
+
+ forcedielec = qqrd2e*q[i]*q[j]*((eps_s*(epsr+r*depsdr)/epsr/epsr) -1.)/rsq;
+ fforce = factor_coul*forcedielec/r;
+
+ phidielec = (qqrd2e*q[i]*q[j]*((eps_s/epsr) -1.)/r)- offset[itype][jtype];
+ return factor_coul*phidielec;
+}
diff --git a/src/USER-OMP/pair_dpd_omp.h b/src/USER-MISC/pair_coul_diel.h
similarity index 51%
copy from src/USER-OMP/pair_dpd_omp.h
copy to src/USER-MISC/pair_coul_diel.h
index 9385e5444..14d7b8b14 100644
--- a/src/USER-OMP/pair_dpd_omp.h
+++ b/src/USER-MISC/pair_coul_diel.h
@@ -1,52 +1,57 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
-------------------------------------------------------------------------- */
-
#ifdef PAIR_CLASS
-PairStyle(dpd/omp,PairDPDOMP)
+PairStyle(coul/diel,PairCoulDiel)
#else
-#ifndef LMP_PAIR_DPD_OMP_H
-#define LMP_PAIR_DPD_OMP_H
+#ifndef LMP_PAIR_COUL_DIEL_H
+#define LMP_PAIR_COUL_DIEL_H
-#include "pair_dpd.h"
-#include "thr_omp.h"
+#include "pair.h"
namespace LAMMPS_NS {
-class PairDPDOMP : public PairDPD, public ThrOMP {
-
+class PairCoulDiel : public Pair {
public:
- PairDPDOMP(class LAMMPS *);
- virtual ~PairDPDOMP();
+ PairCoulDiel(class LAMMPS *);
+ virtual ~PairCoulDiel();
virtual void compute(int, int);
- virtual double memory_usage();
+
+ virtual void settings(int, char **);
+ virtual void coeff(int, char **);
+ virtual void init_style();
+ virtual double init_one(int, int);
+ virtual void write_restart(FILE *);
+ virtual void read_restart(FILE *);
+ virtual void write_restart_settings(FILE *);
+ virtual void read_restart_settings(FILE *);
+
+ virtual double single(int, int, int, int, double, double, double, double &);
protected:
- class RanMars **random_thr;
+ double cut_global;
+ double **cut;
+ double **sigmae, **rme, **offset;
+ double a_eps, b_eps, eps_s;
- private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void allocate();
};
}
#endif
#endif
diff --git a/src/USER-MISC/pair_gauss_cut.cpp b/src/USER-MISC/pair_gauss_cut.cpp
new file mode 100644
index 000000000..0568c40ea
--- /dev/null
+++ b/src/USER-MISC/pair_gauss_cut.cpp
@@ -0,0 +1,371 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Arben Jusufi, Axel Kohlmeyer (Temple U.)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_gauss_cut.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "update.h"
+#include "integrate.h"
+#include "memory.h"
+#include "error.h"
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+/* ---------------------------------------------------------------------- */
+
+PairGaussCut::PairGaussCut(LAMMPS *lmp) : Pair(lmp)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairGaussCut::~PairGaussCut()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(hgauss);
+ memory->destroy(sigmah);
+ memory->destroy(rmh);
+ memory->destroy(pgauss);
+ memory->destroy(offset);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGaussCut::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r,rexp,ugauss,factor_lj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ evdwl = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r = sqrt(rsq);
+ rexp = (r-rmh[itype][jtype])/sigmah[itype][jtype];
+ ugauss = pgauss[itype][jtype]*exp(-0.5*rexp*rexp);
+ fpair = factor_lj*rexp/r*ugauss/sigmah[itype][jtype];
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (eflag) {
+ evdwl = ugauss - offset[itype][jtype];
+ evdwl *= factor_lj;
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,0.0,fpair,delx,dely,delz);
+ }
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairGaussCut::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut,n+1,n+1,"pair:cut");
+ memory->create(hgauss,n+1,n+1,"pair:hgauss");
+ memory->create(sigmah,n+1,n+1,"pair:sigmah");
+ memory->create(rmh,n+1,n+1,"pair:rmh");
+ memory->create(pgauss,n+1,n+1,"pair:pgauss");
+ memory->create(offset,n+1,n+1,"pair:offset");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairGaussCut::settings(int narg, char **arg)
+{
+ if (narg != 1) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(arg[0]);
+
+ // reset cutoffs that have been explicitly set
+
+ if (allocated) {
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i+1; j <= atom->ntypes; j++)
+ if (setflag[i][j]) cut[i][j] = cut_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairGaussCut::coeff(int narg, char **arg)
+{
+ if (narg < 5 || narg > 6) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ double hgauss_one = force->numeric(arg[2]);
+ double rmh_one = force->numeric(arg[3]);
+ double sigmah_one = force->numeric(arg[4]);
+
+ double cut_one = cut_global;
+ if (narg == 6) cut_one = force->numeric(arg[5]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ hgauss[i][j] = hgauss_one;
+ sigmah[i][j] = sigmah_one;
+ rmh[i][j] = rmh_one;
+ cut[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairGaussCut::init_one(int i, int j)
+{
+
+ if (setflag[i][j] == 0) {
+ error->all(FLERR,"for gauss/cut pair style, parameters need to be set explicitly for all pairs.");
+ }
+ pgauss[i][j] = hgauss[i][j] / sqrt(MY_2PI)/ sigmah[i][j];
+
+
+ if (offset_flag) {
+ double rexp = (cut[i][j]-rmh[i][j])/sigmah[i][j];
+ offset[i][j] = pgauss[i][j] * exp(-0.5*rexp*rexp);
+ } else offset[i][j] = 0.0;
+
+ hgauss[j][i] = hgauss[i][j];
+ sigmah[j][i] = sigmah[i][j];
+ rmh[j][i] = rmh[i][j];
+ pgauss[j][i] = pgauss[i][j];
+ offset[j][i] = offset[i][j];
+ cut[j][i] = cut[i][j];
+
+ // compute I,J contribution to long-range tail correction
+ // count total # of atoms of type I and J via Allreduce
+
+ if (tail_flag) {
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+
+ double count[2],all[2];
+ count[0] = count[1] = 0.0;
+ for (int k = 0; k < nlocal; k++) {
+ if (type[k] == i) count[0] += 1.0;
+ if (type[k] == j) count[1] += 1.0;
+ }
+ MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
+ }
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairGaussCut::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&hgauss[i][j],sizeof(double),1,fp);
+ fwrite(&rmh[i][j],sizeof(double),1,fp);
+ fwrite(&sigmah[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairGaussCut::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+ MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+ if (setflag[i][j]) {
+ if (me == 0) {
+ fread(&hgauss[i][j],sizeof(double),1,fp);
+ fread(&rmh[i][j],sizeof(double),1,fp);
+ fread(&sigmah[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&hgauss[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rmh[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigmah[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairGaussCut::write_restart_settings(FILE *fp)
+{
+ fwrite(&cut_global,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairGaussCut::read_restart_settings(FILE *fp)
+{
+ int me = comm->me;
+ if (me == 0) {
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairGaussCut::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double r, rexp,ugauss,phigauss;
+
+ r=sqrt(rsq);
+ rexp = (r-rmh[itype][jtype])/sigmah[itype][jtype];
+ ugauss = pgauss[itype][jtype]*exp(-0.5*rexp*rexp);
+
+ fforce = factor_lj*rexp/r*ugauss/sigmah[itype][jtype];
+
+ phigauss = ugauss - offset[itype][jtype];
+ return factor_lj*phigauss;
+}
+
+/* ---------------------------------------------------------------------- */
+double PairGaussCut::memory_usage()
+{
+ const int n=atom->ntypes;
+
+ double bytes = Pair::memory_usage();
+
+ bytes += 7*((n+1)*(n+1) * sizeof(double) + (n+1)*sizeof(double *));
+ bytes += 1*((n+1)*(n+1) * sizeof(int) + (n+1)*sizeof(int *));
+
+ return bytes;
+}
+
diff --git a/src/USER-OMP/pair_peri_lps_omp.h b/src/USER-MISC/pair_gauss_cut.h
similarity index 54%
copy from src/USER-OMP/pair_peri_lps_omp.h
copy to src/USER-MISC/pair_gauss_cut.h
index 2068830ca..8a1030827 100644
--- a/src/USER-OMP/pair_peri_lps_omp.h
+++ b/src/USER-MISC/pair_gauss_cut.h
@@ -1,52 +1,60 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-/* ----------------------------------------------------------------------
- Contributing author: Axel Kohlmeyer (Temple U)
-------------------------------------------------------------------------- */
-
#ifdef PAIR_CLASS
-PairStyle(peri/lps/omp,PairPeriLPSOMP)
+PairStyle(gauss/cut,PairGaussCut)
#else
-#ifndef LMP_PAIR_PERI_LPS_OMP_H
-#define LMP_PAIR_PERI_LPS_OMP_H
+#ifndef LMP_PAIR_GAUSS_CUT_H
+#define LMP_PAIR_GAUSS_CUT_H
-#include "pair_peri_lps.h"
-#include "thr_omp.h"
+#include "pair.h"
namespace LAMMPS_NS {
-class PairPeriLPSOMP : public PairPeriLPS, public ThrOMP {
-
+class PairGaussCut : public Pair {
public:
- PairPeriLPSOMP(class LAMMPS *);
+ PairGaussCut(class LAMMPS *);
+ ~PairGaussCut();
virtual void compute(int, int);
+
+ virtual double single(int, int, int, int, double, double, double, double &);
+
+ virtual void settings(int, char **);
+ virtual void coeff(int, char **);
+
+ virtual double init_one(int, int);
+
+ virtual void write_restart(FILE *);
+ virtual void read_restart(FILE *);
+ virtual void write_restart_settings(FILE *);
+ virtual void read_restart_settings(FILE *);
+
virtual double memory_usage();
protected:
- void compute_dilatation_thr(int ifrom, int ito);
-
+ double cut_global;
+ double **cut;
+ double **hgauss,**sigmah,**rmh;
+ double **pgauss,**offset;
- private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void allocate();
};
}
#endif
#endif
diff --git a/src/USER-MISC/pair_tersoff_table.cpp b/src/USER-MISC/pair_tersoff_table.cpp
new file mode 100644
index 000000000..25a8f32fa
--- /dev/null
+++ b/src/USER-MISC/pair_tersoff_table.cpp
@@ -0,0 +1,1007 @@
+/* ----------------------------------------------------------------------
+ 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: Luca Ferraro (CASPUR)
+ email: luca.ferraro@caspur.it
+
+ Tersoff Potential
+ References: (referenced as tersoff_2 functional form in LAMMPS manual)
+ 1) Tersoff, Phys. Rev. B 39, 5566 (1988)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_tersoff_table.h"
+#include "atom.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "force.h"
+#include "comm.h"
+#include "memory.h"
+
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+#define DELTA 4
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffTable::PairTersoffTable(LAMMPS *lmp) : Pair(lmp)
+{
+ single_enable = 0;
+ one_coeff = 1;
+
+ nelements = 0;
+ elements = NULL;
+ nparams = maxparam = 0;
+ params = NULL;
+ elem2param = NULL;
+}
+
+/* ----------------------------------------------------------------------
+ check if allocated, since class can be destructed when incomplete
+------------------------------------------------------------------------- */
+
+PairTersoffTable::~PairTersoffTable()
+{
+ if (elements)
+ for (int i = 0; i < nelements; i++) delete [] elements[i];
+ delete [] elements;
+ memory->destroy(params);
+ memory->destroy(elem2param);
+
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+ delete [] map;
+
+ deallocateGrids();
+ deallocatePreLoops();
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffTable::compute(int eflag, int vflag)
+{
+ int i,j,k,ii,inum,jnum;
+ int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+ double xtmp,ytmp,ztmp;
+ double fxtmp,fytmp,fztmp;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+
+ int interpolIDX;
+ double r_ik_x, r_ik_y, r_ik_z;
+ double directorCos_ij_x, directorCos_ij_y, directorCos_ij_z, directorCos_ik_x, directorCos_ik_y, directorCos_ik_z;
+ double invR_ij, invR_ik, cosTeta;
+ double repulsivePotential, attractivePotential;
+ double exponentRepulsivePotential, exponentAttractivePotential,interpolTMP,interpolDeltaX,interpolY1;
+ double interpolY2, cutoffFunctionIJ, attractiveExponential, repulsiveExponential, cutoffFunctionDerivedIJ,zeta;
+ double gtetaFunctionIJK,gtetaFunctionDerivedIJK,cutoffFunctionIK;
+ double cutoffFunctionDerivedIK,factor_force3_ij,factor_1_force3_ik;
+ double factor_2_force3_ik,betaZetaPowerIJK,betaZetaPowerDerivedIJK,factor_force_tot;
+ double factor_force_ij;
+ double gtetaFunctionDerived_temp,gtetaFunction_temp;
+
+ double evdwl = 0.0;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int newton_pair = force->newton_pair;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over full neighbor list of my atoms
+ for (ii = 0; ii < inum; ii++) {
+
+ i = ilist[ii];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ // Pre-calculate gteta and cutoff function
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+
+ double dr_ij[3], r_ij;
+
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ dr_ij[0] = xtmp - x[j][0];
+ dr_ij[1] = ytmp - x[j][1];
+ dr_ij[2] = ztmp - x[j][2];
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+
+ invR_ij = 1.0 / r_ij;
+
+ directorCos_ij_x = invR_ij * dr_ij[0];
+ directorCos_ij_y = invR_ij * dr_ij[1];
+ directorCos_ij_z = invR_ij * dr_ij[2];
+
+ // preCutoffFunction
+ interpolDeltaX = r_ij - GRIDSTART;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_FCUTOFF);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = cutoffFunction[itype][jtype][interpolIDX];
+ interpolY2 = cutoffFunction[itype][jtype][interpolIDX+1];
+ preCutoffFunction[neighbor_j] = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // preCutoffFunctionDerived
+ interpolY1 = cutoffFunctionDerived[itype][jtype][interpolIDX];
+ interpolY2 = cutoffFunctionDerived[itype][jtype][interpolIDX+1];
+ preCutoffFunctionDerived[neighbor_j] = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+
+ for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y + directorCos_ij_z * directorCos_ik_z;
+
+ // preGtetaFunction
+ interpolDeltaX=cosTeta+1.0;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_GTETA);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = gtetaFunction[itype][interpolIDX];
+ interpolY2 = gtetaFunction[itype][interpolIDX+1];
+ gtetaFunction_temp = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // preGtetaFunctionDerived
+ interpolY1 = gtetaFunctionDerived[itype][interpolIDX];
+ interpolY2 = gtetaFunctionDerived[itype][interpolIDX+1];
+ gtetaFunctionDerived_temp = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+ preGtetaFunction[neighbor_j][neighbor_k]=params[ijkparam].gamma*gtetaFunction_temp;
+ preGtetaFunctionDerived[neighbor_j][neighbor_k]=params[ijkparam].gamma*gtetaFunctionDerived_temp;
+ preGtetaFunction[neighbor_k][neighbor_j]=params[ijkparam].gamma*gtetaFunction_temp;
+ preGtetaFunctionDerived[neighbor_k][neighbor_j]=params[ijkparam].gamma*gtetaFunctionDerived_temp;
+
+ } // loop on K
+
+ } // loop on J
+
+
+ // loop over neighbours of atom i
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+
+ double dr_ij[3], r_ij, f_ij[3];
+
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ dr_ij[0] = xtmp - x[j][0];
+ dr_ij[1] = ytmp - x[j][1];
+ dr_ij[2] = ztmp - x[j][2];
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+ invR_ij = 1.0 / r_ij;
+
+ directorCos_ij_x = invR_ij * dr_ij[0];
+ directorCos_ij_y = invR_ij * dr_ij[1];
+ directorCos_ij_z = invR_ij * dr_ij[2];
+
+ exponentRepulsivePotential = params[ijparam].lam1 * r_ij;
+ exponentAttractivePotential = params[ijparam].lam2 * r_ij;
+
+ // repulsiveExponential
+ interpolDeltaX = exponentRepulsivePotential - minArgumentExponential;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_EXP);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = exponential[interpolIDX];
+ interpolY2 = exponential[interpolIDX+1];
+ repulsiveExponential = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // attractiveExponential
+ interpolDeltaX = exponentAttractivePotential - minArgumentExponential;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_EXP);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = exponential[interpolIDX];
+ interpolY2 = exponential[interpolIDX+1];
+ attractiveExponential = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+ repulsivePotential = params[ijparam].biga * repulsiveExponential;
+ attractivePotential = -params[ijparam].bigb * attractiveExponential;
+
+ cutoffFunctionIJ = preCutoffFunction[neighbor_j];
+ cutoffFunctionDerivedIJ = preCutoffFunctionDerived[neighbor_j];
+
+ zeta = 0.0;
+
+ // first loop over neighbours of atom i except j - part 1/2
+ for (int neighbor_k = 0; neighbor_k < neighbor_j; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * r_ik_x;
+ directorCos_ik_y = invR_ik * r_ik_y;
+ directorCos_ik_z = invR_ik * r_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ zeta += cutoffFunctionIK * gtetaFunctionIJK;
+
+ }
+
+ // first loop over neighbours of atom i except j - part 2/2
+ for (int neighbor_k = neighbor_j+1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ zeta += cutoffFunctionIK * gtetaFunctionIJK;
+ }
+
+ // betaZetaPowerIJK
+ interpolDeltaX= params[ijparam].beta * zeta;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_BIJ);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = betaZetaPower[itype][interpolIDX];
+ interpolY2 = betaZetaPower[itype][interpolIDX+1];
+ betaZetaPowerIJK = (interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX));
+ // betaZetaPowerDerivedIJK
+ interpolY1 = betaZetaPowerDerived[itype][interpolIDX];
+ interpolY2 = betaZetaPowerDerived[itype][interpolIDX+1];
+ betaZetaPowerDerivedIJK = params[ijparam].beta*(interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX));
+
+ // Forces and virial
+ factor_force_ij = 0.5*cutoffFunctionDerivedIJ*(repulsivePotential + attractivePotential * betaZetaPowerIJK)+0.5*cutoffFunctionIJ*(-repulsivePotential*params[ijparam].lam1-betaZetaPowerIJK*attractivePotential*params[ijparam].lam2);
+
+ f_ij[0] = factor_force_ij * directorCos_ij_x;
+ f_ij[1] = factor_force_ij * directorCos_ij_y;
+ f_ij[2] = factor_force_ij * directorCos_ij_z;
+
+ f[j][0] += f_ij[0];
+ f[j][1] += f_ij[1];
+ f[j][2] += f_ij[2];
+
+ fxtmp -= f_ij[0];
+ fytmp -= f_ij[1];
+ fztmp -= f_ij[2];
+
+ // potential energy
+ evdwl = cutoffFunctionIJ * repulsivePotential + cutoffFunctionIJ * attractivePotential * betaZetaPowerIJK;
+
+ if (evflag) ev_tally(i, j, nlocal, newton_pair, 0.5 * evdwl, 0.0,
+ -factor_force_ij*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2]);
+
+ factor_force_tot= 0.5*cutoffFunctionIJ*attractivePotential*betaZetaPowerDerivedIJK;
+
+ // second loop over neighbours of atom i except j, forces and virial only - part 1/2
+ for (int neighbor_k = 0; neighbor_k < neighbor_j; neighbor_k++) {
+ double dr_ik[3], r_ik, f_ik[3];
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y + directorCos_ij_z * directorCos_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ gtetaFunctionDerivedIJK = preGtetaFunctionDerived[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ cutoffFunctionDerivedIK = preCutoffFunctionDerived[neighbor_k];
+
+ factor_force3_ij= cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ij *factor_force_tot;
+
+ f_ij[0] = factor_force3_ij * (directorCos_ij_x*cosTeta - directorCos_ik_x);
+ f_ij[1] = factor_force3_ij * (directorCos_ij_y*cosTeta - directorCos_ik_y);
+ f_ij[2] = factor_force3_ij * (directorCos_ij_z*cosTeta - directorCos_ik_z);
+
+ factor_1_force3_ik = (cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ik)*factor_force_tot;
+ factor_2_force3_ik = -(cutoffFunctionDerivedIK * gtetaFunctionIJK)*factor_force_tot;
+
+ f_ik[0] = factor_1_force3_ik * (directorCos_ik_x*cosTeta - directorCos_ij_x) + factor_2_force3_ik * directorCos_ik_x;
+ f_ik[1] = factor_1_force3_ik * (directorCos_ik_y*cosTeta - directorCos_ij_y) + factor_2_force3_ik * directorCos_ik_y;
+ f_ik[2] = factor_1_force3_ik * (directorCos_ik_z*cosTeta - directorCos_ij_z) + factor_2_force3_ik * directorCos_ik_z;
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[k][0] -= f_ik[0];
+ f[k][1] -= f_ik[1];
+ f[k][2] -= f_ik[2];
+
+ fxtmp += f_ij[0] + f_ik[0];
+ fytmp += f_ij[1] + f_ik[1];
+ fztmp += f_ij[2] + f_ik[2];
+
+ // potential energy
+ evdwl = 0.0;
+
+ if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik);
+ }
+
+ // second loop over neighbours of atom i except j, forces and virial only - part 2/2
+ for (int neighbor_k = neighbor_j+1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik, f_ik[3];
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y + directorCos_ij_z * directorCos_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ gtetaFunctionDerivedIJK = preGtetaFunctionDerived[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ cutoffFunctionDerivedIK = preCutoffFunctionDerived[neighbor_k];
+
+ factor_force3_ij= cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ij *factor_force_tot;
+
+ f_ij[0] = factor_force3_ij * (directorCos_ij_x*cosTeta - directorCos_ik_x);
+ f_ij[1] = factor_force3_ij * (directorCos_ij_y*cosTeta - directorCos_ik_y);
+ f_ij[2] = factor_force3_ij * (directorCos_ij_z*cosTeta - directorCos_ik_z);
+
+ factor_1_force3_ik = (cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ik)*factor_force_tot;
+ factor_2_force3_ik = -(cutoffFunctionDerivedIK * gtetaFunctionIJK)*factor_force_tot;
+
+ f_ik[0] = factor_1_force3_ik * (directorCos_ik_x*cosTeta - directorCos_ij_x) + factor_2_force3_ik * directorCos_ik_x;
+ f_ik[1] = factor_1_force3_ik * (directorCos_ik_y*cosTeta - directorCos_ij_y) + factor_2_force3_ik * directorCos_ik_y;
+ f_ik[2] = factor_1_force3_ik * (directorCos_ik_z*cosTeta - directorCos_ij_z) + factor_2_force3_ik * directorCos_ik_z;
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[k][0] -= f_ik[0];
+ f[k][1] -= f_ik[1];
+ f[k][2] -= f_ik[2];
+
+ fxtmp += f_ij[0] + f_ik[0];
+ fytmp += f_ij[1] + f_ik[1];
+ fztmp += f_ij[2] + f_ik[2];
+
+ // potential energy
+ evdwl = 0.0;
+
+ if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik);
+
+ }
+ } // loop on J
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ } // loop on I
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffTable::deallocatePreLoops(void)
+{
+ memory->destroy (preGtetaFunction);
+ memory->destroy (preGtetaFunctionDerived);
+ memory->destroy(preCutoffFunction);
+ memory->destroy(preCutoffFunctionDerived);
+}
+
+void PairTersoffTable::allocatePreLoops(void)
+{
+ memory->create(preGtetaFunction,leadingDimensionInteractionList,leadingDimensionInteractionList,"tersofftable:preGtetaFunction");
+
+ memory->create(preGtetaFunctionDerived,leadingDimensionInteractionList,leadingDimensionInteractionList,"tersofftable:preGtetaFunctionDerived");
+
+ memory->create(preCutoffFunction,leadingDimensionInteractionList,"tersofftable:preCutoffFunction");
+
+ memory->create(preCutoffFunctionDerived,leadingDimensionInteractionList,"tersofftable:preCutoffFunctionDerived");
+}
+
+void PairTersoffTable::deallocateGrids()
+{
+ int i,j;
+
+ memory->destroy(exponential);
+ memory->destroy(gtetaFunction);
+ memory->destroy(gtetaFunctionDerived);
+ memory->destroy(cutoffFunction);
+ memory->destroy(cutoffFunctionDerived);
+ memory->destroy(betaZetaPower);
+ memory->destroy(betaZetaPowerDerived);
+}
+
+void PairTersoffTable::allocateGrids(void)
+{
+ int i, j, l;
+
+ int numGridPointsExponential, numGridPointsGtetaFunction, numGridPointsOneCutoffFunction;
+ int numGridPointsNotOneCutoffFunction, numGridPointsCutoffFunction, numGridPointsBetaZetaPower;
+ // double minArgumentExponential;
+ double deltaArgumentCutoffFunction, deltaArgumentExponential, deltaArgumentBetaZetaPower;
+ double deltaArgumentGtetaFunction;
+ double r, minMu, maxLambda, maxCutoff;
+ double const PI=acos(-1.0);
+
+ // exponential
+
+ // find min and max argument
+ minMu=params[0].lam2;
+ maxLambda=params[0].lam1;
+ for (i=1; i<nparams; i++) {
+ if (params[i].lam2 < minMu) minMu = params[i].lam2;
+ if (params[i].lam1 > maxLambda) maxLambda = params[i].lam1;
+ }
+ maxCutoff=cutmax;
+
+ minArgumentExponential=minMu*GRIDSTART;
+
+ numGridPointsExponential=(int)((maxLambda*maxCutoff-minArgumentExponential)*GRIDDENSITY_EXP)+2;
+
+ memory->create(exponential,numGridPointsExponential,"tersofftable:exponential");
+
+ r = minArgumentExponential;
+ deltaArgumentExponential = 1.0 / GRIDDENSITY_EXP;
+ for (i = 0; i < numGridPointsExponential; i++)
+ {
+ exponential[i] = exp(-r);
+ r += deltaArgumentExponential;
+ }
+
+
+ // gtetaFunction
+
+ numGridPointsGtetaFunction=(int)(2.0*GRIDDENSITY_GTETA)+2;
+
+ memory->create(gtetaFunction,nelements,numGridPointsGtetaFunction,"tersofftable:gtetaFunction");
+ memory->create(gtetaFunctionDerived,nelements,numGridPointsGtetaFunction,"tersofftable:gtetaFunctionDerived");
+
+ r = minArgumentExponential;
+ for (i=0; i<nelements; i++) {
+ r = -1.0;
+ deltaArgumentGtetaFunction = 1.0 / GRIDDENSITY_GTETA;
+
+ int iparam = elem2param[i][i][i];
+ double c = params[iparam].c;
+ double d = params[iparam].d;
+ double h = params[iparam].h;
+
+ for (j = 0; j < numGridPointsGtetaFunction; j++) {
+ gtetaFunction[i][j]=1.0+(c*c)/(d*d)-(c*c)/(d*d+(h-r)*(h-r));
+ gtetaFunctionDerived[i][j]= -2.0 * c * c * (h-r) / ((d*d+(h-r)*(h-r))*(d*d+(h-r)*(h-r)));
+ r += deltaArgumentGtetaFunction;
+ }
+ }
+
+
+ // cutoffFunction, zetaFunction, find grids.
+
+ int ngrid_max = -1;
+ int zeta_max = -1;
+
+ for (i=0; i<nelements; i++) {
+
+ int iparam = elem2param[i][i][i];
+ double c = params[iparam].c;
+ double d = params[iparam].d;
+ double beta = params[iparam].beta;
+
+ numGridPointsBetaZetaPower=(int)(((1.0+(c*c)/(d*d)-(c*c)/(d*d+4))*beta*leadingDimensionInteractionList*GRIDDENSITY_BIJ))+2;
+ zeta_max = MAX(zeta_max,numGridPointsBetaZetaPower);
+
+ for (j=0; j<nelements; j++) {
+ for (j=0; j<nelements; j++) {
+
+ int ijparam = elem2param[i][j][j];
+ double cutoffR = params[ijparam].cutoffR;
+ double cutoffS = params[ijparam].cutoffS;
+
+ numGridPointsOneCutoffFunction=(int) ((cutoffR-GRIDSTART)*GRIDDENSITY_FCUTOFF)+1;
+ numGridPointsNotOneCutoffFunction=(int) ((cutoffS-cutoffR)*GRIDDENSITY_FCUTOFF)+2;
+ numGridPointsCutoffFunction=numGridPointsOneCutoffFunction+numGridPointsNotOneCutoffFunction;
+
+ ngrid_max = MAX(ngrid_max,numGridPointsCutoffFunction);
+ }
+ }
+ }
+
+ memory->create(cutoffFunction,nelements,nelements,ngrid_max,"tersoff:cutfunc");
+ memory->create(cutoffFunctionDerived,nelements,nelements,ngrid_max,"tersoff:cutfuncD");
+
+ // cutoffFunction, compute.
+
+ for (i=0; i<nelements; i++) {
+ for (j=0; j<nelements; j++) {
+ for (j=0; j<nelements; j++) {
+ int ijparam = elem2param[i][j][j];
+ double cutoffR = params[ijparam].cutoffR;
+ double cutoffS = params[ijparam].cutoffS;
+
+ numGridPointsOneCutoffFunction=(int) ((cutoffR-GRIDSTART)*GRIDDENSITY_FCUTOFF)+1;
+ numGridPointsNotOneCutoffFunction=(int) ((cutoffS-cutoffR)*GRIDDENSITY_FCUTOFF)+2;
+ numGridPointsCutoffFunction=numGridPointsOneCutoffFunction+numGridPointsNotOneCutoffFunction;
+
+ r = GRIDSTART;
+ deltaArgumentCutoffFunction = 1.0 / GRIDDENSITY_FCUTOFF;
+
+ for (l = 0; l < numGridPointsOneCutoffFunction; l++) {
+ cutoffFunction[i][j][l] = 1.0;
+ cutoffFunctionDerived[i][j][l]=0.0;
+ r += deltaArgumentCutoffFunction;
+ }
+
+ for (l = numGridPointsOneCutoffFunction; l < numGridPointsCutoffFunction; l++) {
+ cutoffFunction[i][j][l] = 0.5 + 0.5 * cos (PI * (r - cutoffR)/(cutoffS-cutoffR)) ;
+ cutoffFunctionDerived[i][j][l] = -0.5 * PI * sin (PI * (r - cutoffR)/(cutoffS-cutoffR)) / (cutoffS-cutoffR) ;
+ r += deltaArgumentCutoffFunction;
+ }
+ }
+ }
+ }
+
+ // betaZetaPower, compute
+
+ memory->create(betaZetaPower,nelements,zeta_max,"tersoff:zetafunc");
+ memory->create(betaZetaPowerDerived,nelements,zeta_max,"tersoff:zetafuncD");
+
+ for (i=0; i<nelements; i++) {
+
+ int iparam = elem2param[i][i][i];
+ double c = params[iparam].c;
+ double d = params[iparam].d;
+ double beta = params[iparam].beta;
+
+ numGridPointsBetaZetaPower=(int)(((1.0+(c*c)/(d*d)-(c*c)/(d*d+4))*beta*leadingDimensionInteractionList*GRIDDENSITY_BIJ))+2;
+
+ r=0.0;
+ deltaArgumentBetaZetaPower = 1.0 / GRIDDENSITY_BIJ;
+
+ betaZetaPower[i][0]=1.0;
+
+ r += deltaArgumentBetaZetaPower;
+
+ for (j = 1; j < numGridPointsBetaZetaPower; j++) {
+ double powern=params[iparam].powern;
+ betaZetaPower[i][j]=pow((1+pow(r,powern)),-1/(2*powern));
+ betaZetaPowerDerived[i][j]=-0.5*pow(r,powern-1.0)*pow((1+pow(r,powern)),-1/(2*powern)-1) ;
+ r += deltaArgumentBetaZetaPower;
+ }
+ betaZetaPowerDerived[i][0]=(betaZetaPower[i][1]-1.0)*GRIDDENSITY_BIJ;
+ }
+}
+
+void PairTersoffTable::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ map = new int[n+1];
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairTersoffTable::settings(int narg, char **arg)
+{
+ if (narg != 0) error->all(FLERR,"Illegal pair_style command");
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairTersoffTable::coeff(int narg, char **arg)
+{
+ int i,j,n;
+
+ if (!allocated) allocate();
+
+ if (narg != 3 + atom->ntypes)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // insure I,J args are * *
+
+ if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // read args that map atom types to elements in potential file
+ // map[i] = which element the Ith atom type is, -1 if NULL
+ // nelements = # of unique elements
+ // elements = list of element names
+
+ if (elements) {
+ for (i = 0; i < nelements; i++) delete [] elements[i];
+ delete [] elements;
+ }
+ elements = new char*[atom->ntypes];
+ for (i = 0; i < atom->ntypes; i++) elements[i] = NULL;
+
+ nelements = 0;
+ for (i = 3; i < narg; i++) {
+ if (strcmp(arg[i],"NULL") == 0) {
+ map[i-2] = -1;
+ continue;
+ }
+ for (j = 0; j < nelements; j++)
+ if (strcmp(arg[i],elements[j]) == 0) break;
+ map[i-2] = j;
+ if (j == nelements) {
+ n = strlen(arg[i]) + 1;
+ elements[j] = new char[n];
+ strcpy(elements[j],arg[i]);
+ nelements++;
+ }
+ }
+
+ // read potential file and initialize potential parameters
+
+ read_file(arg[2]);
+ setup();
+
+ // clear setflag since coeff() called once with I,J = * *
+
+ n = atom->ntypes;
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ // set setflag i,j for type pairs where both are mapped to elements
+
+ int count = 0;
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ if (map[i] >= 0 && map[j] >= 0) {
+ setflag[i][j] = 1;
+ count++;
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // allocate tables and internal structures
+ allocatePreLoops();
+ allocateGrids();
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairTersoffTable::init_style()
+{
+ if (atom->tag_enable == 0)
+ error->all(FLERR,"Pair style Tersoff requires atom IDs");
+ if (force->newton_pair == 0)
+ error->all(FLERR,"Pair style Tersoff requires newton pair on");
+
+ // need a full neighbor list
+
+ int irequest = neighbor->request(this);
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->full = 1;
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairTersoffTable::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ return cutmax;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffTable::read_file(char *file)
+{
+ int params_per_line = 17;
+ char **words = new char*[params_per_line+1];
+
+ memory->sfree(params);
+ params = NULL;
+ nparams = maxparam = 0;
+
+ // open file on proc 0
+
+ FILE *fp;
+ if (comm->me == 0) {
+ fp = fopen(file,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open Tersoff potential file %s",file);
+ error->one(FLERR,str);
+ }
+ }
+
+ // read each set of params from potential file
+ // one set of params can span multiple lines
+ // store params if all 3 element tags are in element list
+
+ int n,nwords,ielement,jelement,kelement;
+ char line[MAXLINE],*ptr;
+ int eof = 0;
+
+ while (1) {
+ if (comm->me == 0) {
+ ptr = fgets(line,MAXLINE,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ // strip comment, skip line if blank
+
+ if ((ptr = strchr(line,'#'))) *ptr = '\0';
+ nwords = atom->count_words(line);
+ if (nwords == 0) continue;
+
+ // concatenate additional lines until have params_per_line words
+
+ while (nwords < params_per_line) {
+ n = strlen(line);
+ if (comm->me == 0) {
+ ptr = fgets(&line[n],MAXLINE-n,fp);
+ if (ptr == NULL) {
+ eof = 1;
+ fclose(fp);
+ } else n = strlen(line) + 1;
+ }
+ MPI_Bcast(&eof,1,MPI_INT,0,world);
+ if (eof) break;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+ if ((ptr = strchr(line,'#'))) *ptr = '\0';
+ nwords = atom->count_words(line);
+ }
+
+ if (nwords != params_per_line)
+ error->all(FLERR,"Incorrect format in Tersoff potential file");
+
+ // words = ptrs to all words in line
+
+ nwords = 0;
+ words[nwords++] = strtok(line," \t\n\r\f");
+ while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue;
+
+ // ielement,jelement,kelement = 1st args
+ // if all 3 args are in element list, then parse this line
+ // else skip to next entry in file
+
+ for (ielement = 0; ielement < nelements; ielement++)
+ if (strcmp(words[0],elements[ielement]) == 0) break;
+ if (ielement == nelements) continue;
+ for (jelement = 0; jelement < nelements; jelement++)
+ if (strcmp(words[1],elements[jelement]) == 0) break;
+ if (jelement == nelements) continue;
+ for (kelement = 0; kelement < nelements; kelement++)
+ if (strcmp(words[2],elements[kelement]) == 0) break;
+ if (kelement == nelements) continue;
+
+ // load up parameter settings and error check their values
+
+ if (nparams == maxparam) {
+ maxparam += DELTA;
+ params = (Param *) memory->srealloc(params,maxparam*sizeof(Param),
+ "pair:params");
+ }
+
+ params[nparams].ielement = ielement;
+ params[nparams].jelement = jelement;
+ params[nparams].kelement = kelement;
+ params[nparams].powerm = atof(words[3]); // not used (only tersoff_2 is implemented)
+ params[nparams].gamma = atof(words[4]); // not used (only tersoff_2 is implemented)
+ params[nparams].lam3 = atof(words[5]); // not used (only tersoff_2 is implemented)
+ params[nparams].c = atof(words[6]);
+ params[nparams].d = atof(words[7]);
+ params[nparams].h = atof(words[8]);
+ params[nparams].powern = atof(words[9]);
+ params[nparams].beta = atof(words[10]);
+ params[nparams].lam2 = atof(words[11]);
+ params[nparams].bigb = atof(words[12]);
+ // current implementation is based on functional form
+ // of tersoff_2 as reported in the reference paper
+ double bigr = atof(words[13]);
+ double bigd = atof(words[14]);
+ params[nparams].cutoffR = bigr - bigd;
+ params[nparams].cutoffS = bigr + bigd;
+ params[nparams].lam1 = atof(words[15]);
+ params[nparams].biga = atof(words[16]);
+
+ // currently only allow m exponent of 1 or 3
+ params[nparams].powermint = int(params[nparams].powerm);
+
+ if (params[nparams].c < 0.0 || params[nparams].d < 0.0 ||
+ params[nparams].powern < 0.0 || params[nparams].beta < 0.0 ||
+ params[nparams].lam2 < 0.0 || params[nparams].bigb < 0.0 ||
+ params[nparams].cutoffR < 0.0 ||params[nparams].cutoffS < 0.0 ||
+ params[nparams].cutoffR > params[nparams].cutoffS ||
+ params[nparams].lam1 < 0.0 || params[nparams].biga < 0.0
+ ) error->all(FLERR,"Illegal Tersoff parameter");
+
+ // only tersoff_2 parametrization is implemented
+ if (params[nparams].gamma != 1.0 || params[nparams].lam3 != 0.0)
+ error->all(FLERR,"Current tersoff/table pair_style implements only tersoff_2 parametrization");
+ nparams++;
+ }
+
+ delete [] words;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffTable::setup()
+{
+ int i,j,k,m,n;
+
+ // set elem2param for all triplet combinations
+ // must be a single exact match to lines read from file
+ // do not allow for ACB in place of ABC
+
+ memory->destroy(elem2param);
+ memory->create(elem2param,nelements,nelements,nelements,"pair:elem2param");
+
+ for (i = 0; i < nelements; i++)
+ for (j = 0; j < nelements; j++)
+ for (k = 0; k < nelements; k++) {
+ n = -1;
+ for (m = 0; m < nparams; m++) {
+ if (i == params[m].ielement && j == params[m].jelement &&
+ k == params[m].kelement) {
+ if (n >= 0) error->all(FLERR,"Potential file has duplicate entry");
+ n = m;
+ }
+ }
+ if (n < 0) error->all(FLERR,"Potential file is missing an entry");
+ elem2param[i][j][k] = n;
+ }
+
+ // set cutoff square
+ for (m = 0; m < nparams; m++) {
+ params[m].cut = params[m].cutoffS;
+ params[m].cutsq = params[m].cut*params[m].cut;
+ }
+
+ // set cutmax to max of all params
+ cutmax = 0.0;
+ for (m = 0; m < nparams; m++) {
+ if (params[m].cut > cutmax) cutmax = params[m].cut;
+ }
+}
diff --git a/src/USER-MISC/pair_tersoff_table.h b/src/USER-MISC/pair_tersoff_table.h
new file mode 100644
index 000000000..3be63cde0
--- /dev/null
+++ b/src/USER-MISC/pair_tersoff_table.h
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------
+ 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: Luca Ferraro (CASPUR)
+ email: luca.ferraro@caspur.it
+
+ Tersoff Potential
+ References:
+ 1) Tersoff, Phys. Rev. B 39, 5566 (1988)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tersoff/table,PairTersoffTable)
+
+#else
+
+#ifndef LMP_PAIR_Tersoff_H
+#define LMP_PAIR_Tersoff_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairTersoffTable : public Pair {
+ public:
+ PairTersoffTable(class LAMMPS *);
+ virtual ~PairTersoffTable();
+ virtual void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ double init_one(int, int);
+ void init_style();
+
+ protected:
+ struct Param {
+ double lam1,lam2,lam3;
+ double c,d,h;
+ double gamma,powerm;
+ double powern,beta;
+ double biga,bigb,cutoffR, cutoffS;
+ double cut,cutsq;
+ int ielement,jelement,kelement;
+ int powermint;
+ };
+
+
+ double cutmax; // max cutoff for all elements
+ int nelements; // # of unique elements
+ char **elements; // names of unique elements
+ int ***elem2param; // mapping from element triplets to parameters
+ int *map; // mapping from atom types to elements
+ int nparams; // # of stored parameter sets
+ int maxparam; // max # of parameter sets
+ Param *params; // parameter set for an I-J-K interaction
+
+ void allocate();
+
+ void read_file(char *);
+ void setup();
+
+ // max number of interaction per atom for environment potential
+ static const int leadingDimensionInteractionList = 64;
+ // pre-loop coordination functions
+ double **preGtetaFunction, **preGtetaFunctionDerived;
+ double *preCutoffFunction, *preCutoffFunctionDerived;
+ void allocatePreLoops(void);
+ void deallocatePreLoops(void);
+ // grids
+ static const double GRIDSTART = 0.1;
+ static const int GRIDDENSITY_FCUTOFF = 5000;
+ static const int GRIDDENSITY_EXP = 12000;
+ static const int GRIDDENSITY_GTETA = 12000;
+ static const int GRIDDENSITY_BIJ = 7500;
+ double minArgumentExponential;
+ double *exponential, ***cutoffFunction, ***cutoffFunctionDerived;
+ double **gtetaFunction, **gtetaFunctionDerived, **betaZetaPower, **betaZetaPowerDerived;
+ void allocateGrids(void);
+ void deallocateGrids(void);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/Install.sh b/src/USER-OMP/Install.sh
index db0beb521..503fc66c3 100644
--- a/src/USER-OMP/Install.sh
+++ b/src/USER-OMP/Install.sh
@@ -1,20 +1,49 @@
# Install/unInstall package files in LAMMPS
# do not install child files if parent does not exist
-for file in *_omp.cpp *_omp.h; do
+for file in *_omp.cpp *_omp.h pppm*proxy.h pppm*proxy.cpp; do
# let us see if the "rain man" can count the toothpicks...
- ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
-
+ ofile=`echo $file | sed -e s,_pppm_tip4p_omp,_long_tip4p_omp, \
+ -e s,pppm.\\*_proxy,pppm_omp, -e s,_pppm_omp,_long_omp, \
+ -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
if (test $1 = 1) then
if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then
: # always install those files.
elif (test ! -e ../$ofile) then
continue
fi
cp $file ..
elif (test $1 = 0) then
rm -f ../$file
fi
done
+
+if (test $1 = 1) then
+
+ if (test -e ../Makefile.package) then
+ sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_USER_OMP |' ../Makefile.package
+ fi
+
+ # force rebuild of files with LMP_USER_OMP switch
+
+ touch ../accelerator_omp.h
+
+ cp thr_data.h ..
+ cp thr_data.cpp ..
+
+elif (test $1 = 0) then
+
+ if (test -e ../Makefile.package) then
+ sed -i -e 's/[^ \t]*OMP[^ \t]* //g' ../Makefile.package
+ fi
+
+ # force rebuild of files with LMP_USER_OMP switch
+
+ touch ../accelerator_omp.h
+
+ rm -f ../thr_data.h
+ rm -f ../thr_data.cpp
+
+fi
diff --git a/src/USER-OMP/Package.sh b/src/USER-OMP/Package.sh
index 5a004c918..6f577b279 100644
--- a/src/USER-OMP/Package.sh
+++ b/src/USER-OMP/Package.sh
@@ -1,28 +1,46 @@
# Update package files in LAMMPS
-# cp package file to src if doesn't exist or is different
-# do not copy certain files if non-OMP versions do not exist
-# do remove OpenMP style files that have no matching
-# non-OpenMP version installed, e.g. after a package has been removed
-
-for file in *_omp.cpp *_omp.h; do
+# copy package file to src if it doesn't exists or is different
+# do not copy OpenMP style files, if a non-OpenMP version does
+# not exist. Do remove OpenMP style files that have no matching
+# non-OpenMP version installed, e.g. after a package has been
+# removed
+for file in *_omp.cpp *_omp.h pppm*proxy.h pppm*proxy.cpp thr_data.h thr_data.cpp; do
# let us see if the "rain man" can count the toothpicks...
- ofile=`echo $file | sed -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
- if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") then
- : # always check for those files.
+ ofile=`echo $file | sed -e s,_pppm_tip4p_omp,_long_tip4p_omp, \
+ -e s,pppm.\\*_proxy,pppm_omp, -e s,_pppm_omp,_long_omp, \
+ -e s,\\\\\\(.\\*\\\\\\)_omp\\\\.\\\\\\(h\\\\\\|cpp\\\\\\),\\\\1.\\\\2,`
+ if (test $file = "thr_omp.h") || (test $file = "thr_omp.cpp") \
+ || (test $file = "thr_data.h") || (test $file = "thr_data.cpp") then
+ if (test ! -e ../$file) then
+ echo " creating src/$file"
+ cp $file ..
+ elif ! cmp -s $file ../$file ; then
+ echo " updating src/$file"
+ cp $file ..
+ fi
elif (test ! -e ../$ofile) then
if (test -e ../$file) then
echo " removing src/$file"
rm -f ../$file
fi
- continue
+ else
+ if (test ! -e ../$file) then
+ echo " creating src/$file"
+ cp $file ..
+ elif ! cmp -s $file ../$file ; then
+ echo " updating src/$file"
+ cp $file ..
+ fi
fi
+done
+for file in thr_data.h thr_data.cpp; do
if (test ! -e ../$file) then
echo " creating src/$file"
cp $file ..
elif ! cmp -s $file ../$file ; then
echo " updating src/$file"
cp $file ..
fi
done
diff --git a/src/USER-OMP/README b/src/USER-OMP/README
index b200fee47..46f63f646 100644
--- a/src/USER-OMP/README
+++ b/src/USER-OMP/README
@@ -1,10 +1,19 @@
This package provides OpenMP multi-threading support and other
optimizations of various LAMMPS pair styles, dihedral styles, and fix
styles.
See this section of the manual to get started:
doc/Section_accelerate.html, sub-section 5.2
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
+
+--------------------------
+
+This directory also contains a shell script:
+
+hack_openmp_for_pgi.sh
+
+which will convert OpenMP directives in src files
+into a form compatible with the PGI compiler.
diff --git a/src/USER-OMP/angle_charmm_omp.cpp b/src/USER-OMP/angle_charmm_omp.cpp
new file mode 100644
index 000000000..989bb08ef
--- /dev/null
+++ b/src/USER-OMP/angle_charmm_omp.cpp
@@ -0,0 +1,191 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_charmm_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCharmmOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCharmmOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double dtheta,tk;
+ double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
+ double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // Urey-Bradley bond
+
+ delxUB = x[i3][0] - x[i1][0];
+ delyUB = x[i3][1] - x[i1][1];
+ delzUB = x[i3][2] - x[i1][2];
+ domain->minimum_image(delxUB,delyUB,delzUB);
+
+ rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB;
+ rUB = sqrt(rsqUB);
+
+ // Urey-Bradley force & energy
+
+ dr = rUB - r_ub[type];
+ rk = k_ub[type] * dr;
+
+ if (rUB > 0.0) forceUB = -2.0*rk/rUB;
+ else forceUB = 0.0;
+
+ if (EFLAG) eangle = rk*dr;
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // harmonic force & energy
+
+ dtheta = acos(c) - theta0[type];
+ tk = k[type] * dtheta;
+
+ if (EFLAG) eangle += tk*dtheta;
+
+ a = -2.0 * tk * s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2 - delxUB*forceUB;
+ f1[1] = a11*dely1 + a12*dely2 - delyUB*forceUB;
+ f1[2] = a11*delz1 + a12*delz2 - delzUB*forceUB;
+
+ f3[0] = a22*delx2 + a12*delx1 + delxUB*forceUB;
+ f3[1] = a22*dely2 + a12*dely1 + delyUB*forceUB;
+ f3[2] = a22*delz2 + a12*delz1 + delzUB*forceUB;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_charmm_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_charmm_omp.h
index b24de4a57..77ed6c74d 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_charmm_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(charmm/omp,AngleCharmmOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_CHARMM_OMP_H
+#define LMP_ANGLE_CHARMM_OMP_H
-#include "pair_born.h"
+#include "angle_charmm.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleCharmmOMP : public AngleCharmm, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleCharmmOMP(class LAMMPS *lmp) :
+ AngleCharmm(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_class2_omp.cpp b/src/USER-OMP/angle_class2_omp.cpp
new file mode 100644
index 000000000..eb2cde294
--- /dev/null
+++ b/src/USER-OMP/angle_class2_omp.cpp
@@ -0,0 +1,234 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_class2_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleClass2OMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double dtheta,dtheta2,dtheta3,dtheta4,de_angle;
+ double dr1,dr2,tk1,tk2,aa1,aa2,aa11,aa12,aa21,aa22;
+ double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,b1,b2;
+ double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // force & energy for angle term
+
+ dtheta = acos(c) - theta0[type];
+ dtheta2 = dtheta*dtheta;
+ dtheta3 = dtheta2*dtheta;
+ dtheta4 = dtheta3*dtheta;
+
+ de_angle = 2.0*k2[type]*dtheta + 3.0*k3[type]*dtheta2 +
+ 4.0*k4[type]*dtheta3;
+
+ a = -de_angle*s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ if (EFLAG) eangle = k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4;
+
+ // force & energy for bond-bond term
+
+ dr1 = r1 - bb_r1[type];
+ dr2 = r2 - bb_r2[type];
+ tk1 = bb_k[type] * dr1;
+ tk2 = bb_k[type] * dr2;
+
+ f1[0] -= delx1*tk2/r1;
+ f1[1] -= dely1*tk2/r1;
+ f1[2] -= delz1*tk2/r1;
+
+ f3[0] -= delx2*tk1/r2;
+ f3[1] -= dely2*tk1/r2;
+ f3[2] -= delz2*tk1/r2;
+
+ if (EFLAG) eangle += bb_k[type]*dr1*dr2;
+
+ // force & energy for bond-angle term
+
+ aa1 = s * dr1 * ba_k1[type];
+ aa2 = s * dr2 * ba_k2[type];
+
+ aa11 = aa1 * c / rsq1;
+ aa12 = -aa1 / (r1 * r2);
+ aa21 = aa2 * c / rsq1;
+ aa22 = -aa2 / (r1 * r2);
+
+ vx11 = (aa11 * delx1) + (aa12 * delx2);
+ vx12 = (aa21 * delx1) + (aa22 * delx2);
+ vy11 = (aa11 * dely1) + (aa12 * dely2);
+ vy12 = (aa21 * dely1) + (aa22 * dely2);
+ vz11 = (aa11 * delz1) + (aa12 * delz2);
+ vz12 = (aa21 * delz1) + (aa22 * delz2);
+
+ aa11 = aa1 * c / rsq2;
+ aa21 = aa2 * c / rsq2;
+
+ vx21 = (aa11 * delx2) + (aa12 * delx1);
+ vx22 = (aa21 * delx2) + (aa22 * delx1);
+ vy21 = (aa11 * dely2) + (aa12 * dely1);
+ vy22 = (aa21 * dely2) + (aa22 * dely1);
+ vz21 = (aa11 * delz2) + (aa12 * delz1);
+ vz22 = (aa21 * delz2) + (aa22 * delz1);
+
+ b1 = ba_k1[type] * dtheta / r1;
+ b2 = ba_k2[type] * dtheta / r2;
+
+ f1[0] -= vx11 + b1*delx1 + vx12;
+ f1[1] -= vy11 + b1*dely1 + vy12;
+ f1[2] -= vz11 + b1*delz1 + vz12;
+
+ f3[0] -= vx21 + b2*delx2 + vx22;
+ f3[1] -= vy21 + b2*dely2 + vy22;
+ f3[2] -= vz21 + b2*delz2 + vz22;
+
+ if (EFLAG) eangle += ba_k1[type]*dr1*dtheta + ba_k2[type]*dr2*dtheta;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_class2_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_class2_omp.h
index b24de4a57..039d86b8a 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_class2_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(class2/omp,AngleClass2OMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_CLASS2_OMP_H
+#define LMP_ANGLE_CLASS2_OMP_H
-#include "pair_born.h"
+#include "angle_class2.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleClass2OMP : public AngleClass2, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleClass2OMP(class LAMMPS *lmp) :
+ AngleClass2(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_delta_omp.cpp b/src/USER-OMP/angle_cosine_delta_omp.cpp
new file mode 100644
index 000000000..bcd4d56bf
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_delta_omp.cpp
@@ -0,0 +1,183 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_delta_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosineDeltaOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosineDeltaOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2,theta,dtheta,dcostheta,tk;
+ double eangle,f1[3],f3[3];
+ double rsq1,rsq2,r1,r2,c,a,cot,a11,a12,a22,b11,b12,b22,c0,s0,s;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ theta = acos(c);
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ cot = c/s;
+
+ // force & energy
+
+ dtheta = theta - theta0[type];
+ dcostheta = cos(dtheta);
+ tk = k[type] * (1.0-dcostheta);
+
+ if (EFLAG) eangle = tk;
+
+ a = -k[type];
+
+ // expand dtheta for cos and sin contribution to force
+
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ b11 = -a*c*cot / rsq1;
+ b12 = a*cot / (r1*r2);
+ b22 = -a*c*cot / rsq2;
+
+ c0 = cos(theta0[type]);
+ s0 = sin(theta0[type]);
+
+ f1[0] = (a11*delx1 + a12*delx2)*c0 + (b11*delx1 + b12*delx2)*s0;
+ f1[1] = (a11*dely1 + a12*dely2)*c0 + (b11*dely1 + b12*dely2)*s0;
+ f1[2] = (a11*delz1 + a12*delz2)*c0 + (b11*delz1 + b12*delz2)*s0;
+ f3[0] = (a22*delx2 + a12*delx1)*c0 + (b22*delx2 + b12*delx1)*s0;
+ f3[1] = (a22*dely2 + a12*dely1)*c0 + (b22*dely2 + b12*dely1)*s0;
+ f3[2] = (a22*delz2 + a12*delz1)*c0 + (b22*delz2 + b12*delz1)*s0;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/angle_cosine_delta_omp.h
similarity index 68%
copy from src/USER-OMP/pair_buck_coul_long_omp.h
copy to src/USER-OMP/angle_cosine_delta_omp.h
index 2c87904de..86e96eb90 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-OMP/angle_cosine_delta_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+AngleStyle(cosine/delta/omp,AngleCosineDeltaOMP)
#else
-#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
-#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#ifndef LMP_ANGLE_COSINE_DELTA_OMP_H
+#define LMP_ANGLE_COSINE_DELTA_OMP_H
-#include "pair_buck_coul_long.h"
+#include "angle_cosine_delta.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
+class AngleCosineDeltaOMP : public AngleCosineDelta, public ThrOMP {
public:
- PairBuckCoulLongOMP(class LAMMPS *);
+ AngleCosineDeltaOMP(class LAMMPS *lmp) :
+ AngleCosineDelta(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_omp.cpp b/src/USER-OMP/angle_cosine_omp.cpp
new file mode 100644
index 000000000..e35fa5489
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_omp.cpp
@@ -0,0 +1,160 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosineOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosineOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // c = cosine of angle
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ // force & energy
+
+ if (EFLAG) eangle = k[type]*(1.0+c);
+
+ a = k[type];
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_cosine_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_cosine_omp.h
index b24de4a57..29b3e8b86 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_cosine_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(cosine/omp,AngleCosineOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_COSINE_OMP_H
+#define LMP_ANGLE_COSINE_OMP_H
-#include "pair_born.h"
+#include "angle_cosine.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleCosineOMP : public AngleCosine, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleCosineOMP(class LAMMPS *lmp) :
+ AngleCosine(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_periodic_omp.cpp b/src/USER-OMP/angle_cosine_periodic_omp.cpp
new file mode 100644
index 000000000..d7578cac9
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_periodic_omp.cpp
@@ -0,0 +1,198 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_periodic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosinePeriodicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosinePeriodicOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i,i1,i2,i3,n,m,type,b_factor;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
+ double tn,tn_1,tn_2,un,un_1,un_2;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // c = cosine of angle
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ m = multiplicity[type];
+ b_factor = b[type];
+
+ // cos(n*x) = Tn(cos(x))
+ // Tn(x) = Chebyshev polynomials of the first kind: T_0 = 1, T_1 = x, ...
+ // recurrence relationship:
+ // Tn(x) = 2*x*T[n-1](x) - T[n-2](x) where T[-1](x) = 0
+ // also, dTn(x)/dx = n*U[n-1](x)
+ // where Un(x) = 2*x*U[n-1](x) - U[n-2](x) and U[-1](x) = 0
+ // finally need to handle special case for n = 1
+
+ tn = 1.0;
+ tn_1 = 1.0;
+ tn_2 = 0.0;
+ un = 1.0;
+ un_1 = 2.0;
+ un_2 = 0.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // force & energy
+
+ tn_2 = c;
+ for (i = 1; i <= m; i++) {
+ tn = 2*c*tn_1 - tn_2;
+ tn_2 = tn_1;
+ tn_1 = tn;
+ }
+
+ for (i = 2; i <= m; i++) {
+ un = 2*c*un_1 - un_2;
+ un_2 = un_1;
+ un_1 = un;
+ }
+ tn = b_factor*pow(-1.0,m)*tn;
+ un = b_factor*pow(-1.0,m)*m*un;
+
+ if (EFLAG) eangle = 2*k[type]*(1.0 - tn);
+
+ a = -k[type]*un;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h b/src/USER-OMP/angle_cosine_periodic_omp.h
similarity index 67%
copy from src/USER-OMP/pair_lj_class2_coul_cut_omp.h
copy to src/USER-OMP/angle_cosine_periodic_omp.h
index 5fe489569..63325ff8f 100644
--- a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
+++ b/src/USER-OMP/angle_cosine_periodic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(lj/class2/coul/cut/omp,PairLJClass2CoulCutOMP)
+AngleStyle(cosine/periodic/omp,AngleCosinePeriodicOMP)
#else
-#ifndef LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
-#define LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
+#ifndef LMP_ANGLE_COSINE_PERIODIC_OMP_H
+#define LMP_ANGLE_COSINE_PERIODIC_OMP_H
-#include "pair_lj_class2_coul_cut.h"
+#include "angle_cosine_periodic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJClass2CoulCutOMP : public PairLJClass2CoulCut, public ThrOMP {
+class AngleCosinePeriodicOMP : public AngleCosinePeriodic, public ThrOMP {
public:
- PairLJClass2CoulCutOMP(class LAMMPS *);
+ AngleCosinePeriodicOMP(class LAMMPS *lmp) :
+ AngleCosinePeriodic(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_shift_exp_omp.cpp b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp
new file mode 100644
index 000000000..3959678c9
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp
@@ -0,0 +1,181 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_shift_exp_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosineShiftExpOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosineShiftExpOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3],ff;
+ double rsq1,rsq2,r1,r2,c,s,a11,a12,a22;
+ double exp2,aa,uumin,cccpsss,cssmscc;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // c = cosine of angle
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ // C= sine of angle
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+
+ // force & energy
+
+ aa=a[type];
+ uumin=umin[type];
+
+ cccpsss = c*cost[type]+s*sint[type];
+ cssmscc = c*sint[type]-s*cost[type];
+
+ if (doExpansion[type])
+ { // |a|<0.01 so use expansions relative precision <1e-5
+// std::cout << "Using expansion\n";
+ if (EFLAG) eangle = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
+ ff=0.25*uumin*cssmscc*(2+aa*cccpsss)/s;
+ }
+ else
+ {
+// std::cout << "Not using expansion\n";
+ exp2=exp(0.5*aa*(1+cccpsss));
+ if (EFLAG) eangle = opt1[type]*(1-exp2);
+ ff=0.5*a[type]*opt1[type]*exp2*cssmscc/s;
+ }
+
+ a11 = ff*c/ rsq1;
+ a12 = -ff / (r1*r2);
+ a22 = ff*c/ rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h b/src/USER-OMP/angle_cosine_shift_exp_omp.h
similarity index 67%
copy from src/USER-OMP/pair_lj_class2_coul_cut_omp.h
copy to src/USER-OMP/angle_cosine_shift_exp_omp.h
index 5fe489569..b9adbf104 100644
--- a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
+++ b/src/USER-OMP/angle_cosine_shift_exp_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(lj/class2/coul/cut/omp,PairLJClass2CoulCutOMP)
+AngleStyle(cosine/shift/exp/omp,AngleCosineShiftExpOMP)
#else
-#ifndef LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
-#define LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
+#ifndef LMP_ANGLE_COSINE_SHIFT_EXP_OMP_H
+#define LMP_ANGLE_COSINE_SHIFT_EXP_OMP_H
-#include "pair_lj_class2_coul_cut.h"
+#include "angle_cosine_shift_exp.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJClass2CoulCutOMP : public PairLJClass2CoulCut, public ThrOMP {
+class AngleCosineShiftExpOMP : public AngleCosineShiftExp, public ThrOMP {
public:
- PairLJClass2CoulCutOMP(class LAMMPS *);
+ AngleCosineShiftExpOMP(class LAMMPS *lmp) :
+ AngleCosineShiftExp(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_shift_omp.cpp b/src/USER-OMP/angle_cosine_shift_omp.cpp
new file mode 100644
index 000000000..5cb3e793a
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_shift_omp.cpp
@@ -0,0 +1,165 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_shift_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosineShiftOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosineShiftOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double rsq1,rsq2,r1,r2,c,s,cps,kcos,ksin,a11,a12,a22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // c = cosine of angle
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ // C= sine of angle
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+
+ // force & energy
+ if (EFLAG) eangle = -k[type]-kcos*c-ksin*s;
+
+ kcos=kcost[type];
+ ksin=ksint[type];
+ cps = c/s; // NOTE absorbed one c
+
+ a11 = (-kcos +ksin*cps )*c/ rsq1;
+ a12 = ( kcos -ksin*cps ) / (r1*r2);
+ a22 = (-kcos +ksin*cps )*c/ rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/angle_cosine_shift_omp.h
similarity index 68%
copy from src/USER-OMP/pair_buck_coul_long_omp.h
copy to src/USER-OMP/angle_cosine_shift_omp.h
index 2c87904de..dadbd1cf5 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-OMP/angle_cosine_shift_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+AngleStyle(cosine/shift/omp,AngleCosineShiftOMP)
#else
-#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
-#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#ifndef LMP_ANGLE_COSINE_SHIFT_OMP_H
+#define LMP_ANGLE_COSINE_SHIFT_OMP_H
-#include "pair_buck_coul_long.h"
+#include "angle_cosine_shift.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
+class AngleCosineShiftOMP : public AngleCosineShift, public ThrOMP {
public:
- PairBuckCoulLongOMP(class LAMMPS *);
+ AngleCosineShiftOMP(class LAMMPS *lmp) :
+ AngleCosineShift(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_cosine_squared_omp.cpp b/src/USER-OMP/angle_cosine_squared_omp.cpp
new file mode 100644
index 000000000..8c39d0895
--- /dev/null
+++ b/src/USER-OMP/angle_cosine_squared_omp.cpp
@@ -0,0 +1,165 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_cosine_squared_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleCosineSquaredOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleCosineSquaredOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double dcostheta,tk;
+ double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ // force & energy
+
+ dcostheta = c - cos(theta0[type]);
+ tk = k[type] * dcostheta;
+
+ if (EFLAG) eangle = tk*dcostheta;
+
+ a = 2.0 * tk;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h b/src/USER-OMP/angle_cosine_squared_omp.h
similarity index 67%
copy from src/USER-OMP/pair_lj_cut_coul_debye_omp.h
copy to src/USER-OMP/angle_cosine_squared_omp.h
index 00cf540be..82c7c06e8 100644
--- a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
+++ b/src/USER-OMP/angle_cosine_squared_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(lj/cut/coul/debye/omp,PairLJCutCoulDebyeOMP)
+AngleStyle(cosine/squared/omp,AngleCosineSquaredOMP)
#else
-#ifndef LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
-#define LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
+#ifndef LMP_ANGLE_COSINE_SQUARED_OMP_H
+#define LMP_ANGLE_COSINE_SQUARED_OMP_H
-#include "pair_lj_cut_coul_debye.h"
+#include "angle_cosine_squared.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCutCoulDebyeOMP : public PairLJCutCoulDebye, public ThrOMP {
+class AngleCosineSquaredOMP : public AngleCosineSquared, public ThrOMP {
public:
- PairLJCutCoulDebyeOMP(class LAMMPS *);
+ AngleCosineSquaredOMP(class LAMMPS *lmp) :
+ AngleCosineSquared(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_harmonic_omp.cpp b/src/USER-OMP/angle_harmonic_omp.cpp
new file mode 100644
index 000000000..46f4654e3
--- /dev/null
+++ b/src/USER-OMP/angle_harmonic_omp.cpp
@@ -0,0 +1,169 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_harmonic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleHarmonicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double eangle,f1[3],f3[3];
+ double dtheta,tk;
+ double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // force & energy
+
+ dtheta = acos(c) - theta0[type];
+ tk = k[type] * dtheta;
+
+ if (EFLAG) eangle = tk*dtheta;
+
+ a = -2.0 * tk * s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_harmonic_omp.h
similarity index 69%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_harmonic_omp.h
index b24de4a57..385572619 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_harmonic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(harmonic/omp,AngleHarmonicOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_HARMONIC_OMP_H
+#define LMP_ANGLE_HARMONIC_OMP_H
-#include "pair_born.h"
+#include "angle_harmonic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleHarmonicOMP : public AngleHarmonic, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleHarmonicOMP(class LAMMPS *lmp) :
+ AngleHarmonic(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_sdk_omp.cpp b/src/USER-OMP/angle_sdk_omp.cpp
new file mode 100644
index 000000000..3b6c1fee7
--- /dev/null
+++ b/src/USER-OMP/angle_sdk_omp.cpp
@@ -0,0 +1,225 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_sdk_omp.h"
+#include "atom.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "comm.h"
+#include "force.h"
+#include "math_const.h"
+
+#include <math.h>
+
+#include "lj_sdk_common.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+using namespace LJSDKParms;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleSDKOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleSDKOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
+ double eangle,f1[3],f3[3],e13,f13;
+ double dtheta,tk;
+ double rsq1,rsq2,rsq3,r1,r2,c,s,a,a11,a12,a22;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // 1-3 LJ interaction.
+ // we only want to use the repulsive part,
+ // and it can be scaled (or off).
+ // so this has to be done here and not in the
+ // general non-bonded code.
+
+ if (repflag) {
+
+ delx3 = x[i1][0] - x[i3][0];
+ dely3 = x[i1][1] - x[i3][1];
+ delz3 = x[i1][2] - x[i3][2];
+ domain->minimum_image(delx3,dely3,delz3);
+ rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
+
+ const int type1 = atom->type[i1];
+ const int type3 = atom->type[i3];
+
+ f13=0.0;
+ e13=0.0;
+
+ if (rsq3 < rminsq[type1][type3]) {
+ const int ljt = lj_type[type1][type3];
+ const double r2inv = 1.0/rsq3;
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+
+ f13 = r4inv*(lj1[type1][type3]*r4inv*r4inv - lj2[type1][type3]);
+ if (EFLAG) e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+
+ f13 = r6inv*(lj1[type1][type3]*r3inv - lj2[type1][type3]);
+ if (EFLAG) e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+
+ f13 = r6inv*(lj1[type1][type3]*r6inv - lj2[type1][type3]);
+ if (EFLAG) e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
+ }
+
+ // make sure energy is 0.0 at the cutoff.
+ if (EFLAG) e13 -= emin[type1][type3];
+
+ f13 *= r2inv;
+ }
+ }
+
+ // force & energy
+
+ dtheta = acos(c) - theta0[type];
+ tk = k[type] * dtheta;
+
+ if (EFLAG) eangle = tk*dtheta;
+
+ a = -2.0 * tk * s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of the 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0] + f13*delx3;
+ f[i1][1] += f1[1] + f13*dely3;
+ f[i1][2] += f1[2] + f13*delz3;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0] - f13*delx3;
+ f[i3][1] += f3[1] - f13*dely3;
+ f[i3][2] += f3[2] - f13*delz3;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ if (EVFLAG) ev_tally13_thr(this,i1,i3,nlocal,NEWTON_BOND,
+ e13,f13,delx3,dely3,delz3,thr);
+
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_sdk_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_sdk_omp.h
index b24de4a57..ed9e1bc40 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_sdk_omp.h
@@ -1,48 +1,49 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(sdk/omp,AngleSDKOMP)
+AngleStyle(cg/cmm/omp,AngleSDKOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_SDK_OMP_H
+#define LMP_ANGLE_SDK_OMP_H
-#include "pair_born.h"
+#include "angle_sdk.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleSDKOMP : public AngleSDK, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleSDKOMP(class LAMMPS *lmp) :
+ AngleSDK(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/angle_table_omp.cpp b/src/USER-OMP/angle_table_omp.cpp
new file mode 100644
index 000000000..ef37c0043
--- /dev/null
+++ b/src/USER-OMP/angle_table_omp.cpp
@@ -0,0 +1,169 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "angle_table_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include "math_const.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void AngleTableOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nanglelist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void AngleTableOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,n,type;
+ double eangle,f1[3],f3[3];
+ double delx1,dely1,delz1,delx2,dely2,delz2;
+ double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
+ double theta,u,mdu; //mdu: minus du, -du/dx=f
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const anglelist = neighbor->anglelist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = anglelist[n][0];
+ i2 = anglelist[n][1];
+ i3 = anglelist[n][2];
+ type = anglelist[n][3];
+
+ // 1st bond
+
+ delx1 = x[i1][0] - x[i2][0];
+ dely1 = x[i1][1] - x[i2][1];
+ delz1 = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx1,dely1,delz1);
+
+ rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
+ r1 = sqrt(rsq1);
+
+ // 2nd bond
+
+ delx2 = x[i3][0] - x[i2][0];
+ dely2 = x[i3][1] - x[i2][1];
+ delz2 = x[i3][2] - x[i2][2];
+ domain->minimum_image(delx2,dely2,delz2);
+
+ rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
+ r2 = sqrt(rsq2);
+
+ // angle (cos and sin)
+
+ c = delx1*delx2 + dely1*dely2 + delz1*delz2;
+ c /= r1*r2;
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ s = 1.0/s;
+
+ // tabulated force & energy
+
+ theta = acos(c);
+ uf_lookup(type,theta,u,mdu);
+
+ if (EFLAG) eangle = u;
+
+ a = mdu * s;
+ a11 = a*c / rsq1;
+ a12 = -a / (r1*r2);
+ a22 = a*c / rsq2;
+
+ f1[0] = a11*delx1 + a12*delx2;
+ f1[1] = a11*dely1 + a12*dely2;
+ f1[2] = a11*delz1 + a12*delz2;
+ f3[0] = a22*delx2 + a12*delx1;
+ f3[1] = a22*dely2 + a12*dely1;
+ f3[2] = a22*delz2 + a12*delz1;
+
+ // apply force to each of 3 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= f1[0] + f3[0];
+ f[i2][1] -= f1[1] + f3[1];
+ f[i2][2] -= f1[2] + f3[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
+ delx1,dely1,delz1,delx2,dely2,delz2,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/angle_table_omp.h
similarity index 71%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/angle_table_omp.h
index b24de4a57..b0bb9c711 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/angle_table_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef ANGLE_CLASS
-PairStyle(born/omp,PairBornOMP)
+AngleStyle(table/omp,AngleTableOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_ANGLE_TABLE_OMP_H
+#define LMP_ANGLE_TABLE_OMP_H
-#include "pair_born.h"
+#include "angle_table.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class AngleTableOMP : public AngleTable, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ AngleTableOMP(class LAMMPS *lmp) :
+ AngleTable(lmp), ThrOMP(lmp,THR_ANGLE) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_class2_omp.cpp b/src/USER-OMP/bond_class2_omp.cpp
new file mode 100644
index 000000000..93c1dae04
--- /dev/null
+++ b/src/USER-OMP/bond_class2_omp.cpp
@@ -0,0 +1,124 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_class2_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondClass2OMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,dr2,dr3,dr4,de_bond;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+ dr = r - r0[type];
+ dr2 = dr*dr;
+ dr3 = dr2*dr;
+ dr4 = dr3*dr;
+
+ // force & energy
+
+ de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3;
+ if (r > 0.0) fbond = -de_bond/r;
+ else fbond = 0.0;
+
+ if (EFLAG) ebond = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_class2_omp.h
similarity index 71%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_class2_omp.h
index b24de4a57..181ed4a44 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_class2_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(class2/omp,BondClass2OMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_CLASS2_OMP_H
+#define LMP_BOND_CLASS2_OMP_H
-#include "pair_born.h"
+#include "bond_class2.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondClass2OMP : public BondClass2, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondClass2OMP(class LAMMPS *lmp) :
+ BondClass2(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_fene_expand_omp.cpp b/src/USER-OMP/bond_fene_expand_omp.cpp
new file mode 100644
index 000000000..f77e11d1d
--- /dev/null
+++ b/src/USER-OMP/bond_fene_expand_omp.cpp
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_fene_expand_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "error.h"
+#include "update.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondFENEExpandOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondFENEExpandOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r0sq,rlogarg,sr2,sr6;
+ double r,rshift,rshiftsq;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+ rshift = r - shift[type];
+ rshiftsq = rshift*rshift;
+ r0sq = r0[type] * r0[type];
+ rlogarg = 1.0 - rshiftsq/r0sq;
+
+ // if r -> r0, then rlogarg < 0.0 which is an error
+ // issue a warning and reset rlogarg = epsilon
+ // if r > 2*r0 something serious is wrong, abort
+
+ if (rlogarg < 0.1) {
+ char str[128];
+ sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g",
+ update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
+ error->warning(FLERR,str,0);
+ if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
+ rlogarg = 0.1;
+ }
+
+ fbond = -k[type]*rshift/rlogarg/r;
+
+ // force from LJ term
+
+ if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) {
+ sr2 = sigma[type]*sigma[type]/rshiftsq;
+ sr6 = sr2*sr2*sr2;
+ fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r;
+ }
+
+ // energy
+
+ if (EFLAG) {
+ ebond = -0.5 * k[type]*r0sq*log(rlogarg);
+ if (rshiftsq < TWO_1_3*sigma[type]*sigma[type])
+ ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
+ }
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_dpd_omp.h b/src/USER-OMP/bond_fene_expand_omp.h
similarity index 69%
copy from src/USER-OMP/pair_dpd_omp.h
copy to src/USER-OMP/bond_fene_expand_omp.h
index 9385e5444..fd7fe4b04 100644
--- a/src/USER-OMP/pair_dpd_omp.h
+++ b/src/USER-OMP/bond_fene_expand_omp.h
@@ -1,52 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(dpd/omp,PairDPDOMP)
+BondStyle(fene/expand/omp,BondFENEExpandOMP)
#else
-#ifndef LMP_PAIR_DPD_OMP_H
-#define LMP_PAIR_DPD_OMP_H
+#ifndef LMP_BOND_FENE_EXPAND_OMP_H
+#define LMP_BOND_FENE_EXPAND_OMP_H
-#include "pair_dpd.h"
+#include "bond_fene_expand.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairDPDOMP : public PairDPD, public ThrOMP {
+class BondFENEExpandOMP : public BondFENEExpand, public ThrOMP {
public:
- PairDPDOMP(class LAMMPS *);
- virtual ~PairDPDOMP();
+ BondFENEExpandOMP(class LAMMPS *lmp) :
+ BondFENEExpand(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
-
- protected:
- class RanMars **random_thr;
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_fene_omp.cpp b/src/USER-OMP/bond_fene_omp.cpp
new file mode 100644
index 000000000..2758ed9e9
--- /dev/null
+++ b/src/USER-OMP/bond_fene_omp.cpp
@@ -0,0 +1,146 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_fene_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "error.h"
+#include "update.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondFENEOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondFENEOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r0sq,rlogarg,sr2,sr6;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r0sq = r0[type] * r0[type];
+ rlogarg = 1.0 - rsq/r0sq;
+
+ // if r -> r0, then rlogarg < 0.0 which is an error
+ // issue a warning and reset rlogarg = epsilon
+ // if r > 2*r0 something serious is wrong, abort
+
+ if (rlogarg < 0.1) {
+ char str[128];
+ sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g",
+ update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
+ error->warning(FLERR,str,0);
+ if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
+ rlogarg = 0.1;
+ }
+
+ fbond = -k[type]/rlogarg;
+
+ // force from LJ term
+
+ if (rsq < TWO_1_3*sigma[type]*sigma[type]) {
+ sr2 = sigma[type]*sigma[type]/rsq;
+ sr6 = sr2*sr2*sr2;
+ fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq;
+ }
+
+ // energy
+
+ if (EFLAG) {
+ ebond = -0.5 * k[type]*r0sq*log(rlogarg);
+ if (rsq < TWO_1_3*sigma[type]*sigma[type])
+ ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
+ }
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_fene_omp.h
similarity index 72%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_fene_omp.h
index b24de4a57..b617aa136 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_fene_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(fene/omp,BondFENEOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_FENE_OMP_H
+#define LMP_BOND_FENE_OMP_H
-#include "pair_born.h"
+#include "bond_fene.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondFENEOMP : public BondFENE, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondFENEOMP(class LAMMPS *lmp) :
+ BondFENE(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_harmonic_omp.cpp b/src/USER-OMP/bond_harmonic_omp.cpp
new file mode 100644
index 000000000..d29cce234
--- /dev/null
+++ b/src/USER-OMP/bond_harmonic_omp.cpp
@@ -0,0 +1,121 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_harmonic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondHarmonicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,rk;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+ dr = r - r0[type];
+ rk = k[type] * dr;
+
+ // force & energy
+
+ if (r > 0.0) fbond = -2.0*rk/r;
+ else fbond = 0.0;
+
+ if (EFLAG) ebond = rk*dr;
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_harmonic_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_harmonic_omp.h
index b24de4a57..79c12aa12 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_harmonic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(harmonic/omp,BondHarmonicOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_HARMONIC_OMP_H
+#define LMP_BOND_HARMONIC_OMP_H
-#include "pair_born.h"
+#include "bond_harmonic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondHarmonicOMP : public BondHarmonic, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondHarmonicOMP(class LAMMPS *lmp) :
+ BondHarmonic(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp
new file mode 100644
index 000000000..05f49ac6f
--- /dev/null
+++ b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp
@@ -0,0 +1,124 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_harmonic_shift_cut_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondHarmonicShiftCutOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondHarmonicShiftCutOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,rk;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+
+ if (r>r1[type]) continue;
+
+ dr = r - r0[type];
+ rk = k[type] * dr;
+
+ // force & energy
+
+ if (r > 0.0) fbond = -2.0*rk/r;
+ else fbond = 0.0;
+
+ if (EFLAG) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.h b/src/USER-OMP/bond_harmonic_shift_cut_omp.h
similarity index 67%
copy from src/USER-OMP/pair_gran_hertz_history_omp.h
copy to src/USER-OMP/bond_harmonic_shift_cut_omp.h
index 66d7bc0fa..e324da73a 100644
--- a/src/USER-OMP/pair_gran_hertz_history_omp.h
+++ b/src/USER-OMP/bond_harmonic_shift_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(gran/hertz/history/omp,PairGranHertzHistoryOMP)
+BondStyle(harmonic/shift/cut/omp,BondHarmonicShiftCutOMP)
#else
-#ifndef LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
-#define LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
+#ifndef LMP_BOND_HARMONIC_SHIFT_CUT_OMP_H
+#define LMP_BOND_HARMONIC_SHIFT_CUT_OMP_H
-#include "pair_gran_hertz_history.h"
+#include "bond_harmonic_shift_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairGranHertzHistoryOMP : public PairGranHertzHistory, public ThrOMP {
+class BondHarmonicShiftCutOMP : public BondHarmonicShiftCut, public ThrOMP {
public:
- PairGranHertzHistoryOMP(class LAMMPS *);
+ BondHarmonicShiftCutOMP(class LAMMPS *lmp) :
+ BondHarmonicShiftCut(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int SHEARUPDATE>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_harmonic_shift_omp.cpp b/src/USER-OMP/bond_harmonic_shift_omp.cpp
new file mode 100644
index 000000000..917fff30b
--- /dev/null
+++ b/src/USER-OMP/bond_harmonic_shift_omp.cpp
@@ -0,0 +1,121 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_harmonic_shift_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondHarmonicShiftOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondHarmonicShiftOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,rk;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+ dr = r - r0[type];
+ rk = k[type] * dr;
+
+ // force & energy
+
+ if (r > 0.0) fbond = -2.0*rk/r;
+ else fbond = 0.0;
+
+ if (EFLAG) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/bond_harmonic_shift_omp.h
similarity index 68%
copy from src/USER-OMP/pair_lj_cut_coul_long_omp.h
copy to src/USER-OMP/bond_harmonic_shift_omp.h
index ac408ba88..d5a45472a 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.h
+++ b/src/USER-OMP/bond_harmonic_shift_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP)
+BondStyle(harmonic/shift/omp,BondHarmonicShiftOMP)
#else
-#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
-#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
+#ifndef LMP_BOND_HARMONIC_SHIFT_OMP_H
+#define LMP_BOND_HARMONIC_SHIFT_OMP_H
-#include "pair_lj_cut_coul_long.h"
+#include "bond_harmonic_shift.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP {
+class BondHarmonicShiftOMP : public BondHarmonicShift, public ThrOMP {
public:
- PairLJCutCoulLongOMP(class LAMMPS *);
+ BondHarmonicShiftOMP(class LAMMPS *lmp) :
+ BondHarmonicShift(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_morse_omp.cpp b/src/USER-OMP/bond_morse_omp.cpp
new file mode 100644
index 000000000..6b89507a6
--- /dev/null
+++ b/src/USER-OMP/bond_morse_omp.cpp
@@ -0,0 +1,122 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_morse_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondMorseOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondMorseOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,ralpha;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+
+ dr = r - r0[type];
+ ralpha = exp(-alpha[type]*dr);
+
+ // force & energy
+
+ if (r > 0.0) fbond = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r;
+ else fbond = 0.0;
+
+ if (EFLAG) ebond = d0[type]*(1-ralpha)*(1-ralpha);
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_morse_omp.h
similarity index 71%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_morse_omp.h
index b24de4a57..0deb731e2 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_morse_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(morse/omp,BondMorseOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_MORSE_OMP_H
+#define LMP_BOND_MORSE_OMP_H
-#include "pair_born.h"
+#include "bond_morse.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondMorseOMP : public BondMorse, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondMorseOMP(class LAMMPS *lmp) :
+ BondMorse(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_nonlinear_omp.cpp b/src/USER-OMP/bond_nonlinear_omp.cpp
new file mode 100644
index 000000000..574022d86
--- /dev/null
+++ b/src/USER-OMP/bond_nonlinear_omp.cpp
@@ -0,0 +1,122 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_nonlinear_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondNonlinearOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondNonlinearOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r,dr,drsq,lamdasq,denom,denomsq;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+ dr = r - r0[type];
+ drsq = dr*dr;
+ lamdasq = lamda[type]*lamda[type];
+ denom = lamdasq - drsq;
+ denomsq = denom*denom;
+
+ // force & energy
+
+ fbond = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq;
+ if (EFLAG) ebond = epsilon[type] * drsq / denom;
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_nonlinear_omp.h
similarity index 69%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_nonlinear_omp.h
index b24de4a57..a104a9af4 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_nonlinear_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(nonlinear/omp,BondNonlinearOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_NONLINEAR_OMP_H
+#define LMP_BOND_NONLINEAR_OMP_H
-#include "pair_born.h"
+#include "bond_nonlinear.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondNonlinearOMP : public BondNonlinear, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondNonlinearOMP(class LAMMPS *lmp) :
+ BondNonlinear(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_quartic_omp.cpp b/src/USER-OMP/bond_quartic_omp.cpp
new file mode 100644
index 000000000..23b3bc3fb
--- /dev/null
+++ b/src/USER-OMP/bond_quartic_omp.cpp
@@ -0,0 +1,190 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_quartic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "pair.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondQuarticOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ // insure pair->ev_tally() will use 1-4 virial contribution
+
+ if (vflag_global == 2)
+ force->pair->vflag_either = force->pair->vflag_global = 1;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondQuarticOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,m,type,itype,jtype;
+ double delx,dely,delz,ebond,fbond,evdwl,fpair;
+ double r,rsq,dr,r2,ra,rb,sr2,sr6;
+
+ ebond = evdwl = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ int * const * const bondlist = neighbor->bondlist;
+ const double * const * const cutsq = force->pair->cutsq;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+
+ // skip bond if already broken
+
+ if (bondlist[n][2] <= 0) continue;
+
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ // if bond breaks, set type to 0
+ // both in temporary bondlist and permanent bond_type
+ // if this proc owns both atoms,
+ // negate bond_type twice if other atom stores it
+ // if other proc owns 2nd atom, other proc will also break bond
+
+ if (rsq > rc[type]*rc[type]) {
+ bondlist[n][2] = 0;
+ for (m = 0; m < atom->num_bond[i1]; m++)
+ if (atom->bond_atom[i1][m] == atom->tag[i2])
+ atom->bond_type[i1][m] = 0;
+ if (i2 < atom->nlocal)
+ for (m = 0; m < atom->num_bond[i2]; m++)
+ if (atom->bond_atom[i2][m] == atom->tag[i1])
+ atom->bond_type[i2][m] = 0;
+ continue;
+ }
+
+ // quartic bond
+ // 1st portion is from quartic term
+ // 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0
+
+ r = sqrt(rsq);
+ dr = r - rc[type];
+ r2 = dr*dr;
+ ra = dr - b1[type];
+ rb = dr - b2[type];
+ fbond = -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb);
+
+ if (rsq < TWO_1_3) {
+ sr2 = 1.0/rsq;
+ sr6 = sr2*sr2*sr2;
+ fbond += 48.0*sr6*(sr6-0.5)/rsq;
+ }
+
+ if (EFLAG) {
+ ebond = k[type]*r2*ra*rb + u0[type];
+ if (rsq < TWO_1_3) ebond += 4.0*sr6*(sr6-1.0) + 1.0;
+ }
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,ebond,fbond,delx,dely,delz,thr);
+
+ // subtract out pairwise contribution from 2 atoms via pair->single()
+ // required since special_bond = 1,1,1
+ // tally energy/virial in pair, using newton_bond as newton flag
+
+ itype = atom->type[i1];
+ jtype = atom->type[i2];
+
+ if (rsq < cutsq[itype][jtype]) {
+ evdwl = -force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,fpair);
+ fpair = -fpair;
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fpair;
+ f[i1][1] += dely*fpair;
+ f[i1][2] += delz*fpair;
+ }
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fpair;
+ f[i2][1] -= dely*fpair;
+ f[i2][2] -= delz*fpair;
+ }
+
+ if (EVFLAG) ev_tally_thr(force->pair,i1,i2,nlocal,NEWTON_BOND,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_quartic_omp.h
similarity index 70%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_quartic_omp.h
index b24de4a57..f2dcec833 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_quartic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(quartic/omp,BondQuarticOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_QUARTIC_OMP_H
+#define LMP_BOND_QUARTIC_OMP_H
-#include "pair_born.h"
+#include "bond_quartic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondQuarticOMP : public BondQuartic, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondQuarticOMP(class LAMMPS *lmp) :
+ BondQuartic(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/bond_table_omp.cpp b/src/USER-OMP/bond_table_omp.cpp
new file mode 100644
index 000000000..f822f01fa
--- /dev/null
+++ b/src/USER-OMP/bond_table_omp.cpp
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "bond_table_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "domain.h"
+
+#include <math.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void BondTableOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nbondlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void BondTableOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,n,type;
+ double delx,dely,delz,ebond,fbond;
+ double rsq,r;
+ double u,mdu;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const bondlist = neighbor->bondlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = bondlist[n][0];
+ i2 = bondlist[n][1];
+ type = bondlist[n][2];
+
+ delx = x[i1][0] - x[i2][0];
+ dely = x[i1][1] - x[i2][1];
+ delz = x[i1][2] - x[i2][2];
+ domain->minimum_image(delx,dely,delz);
+
+ rsq = delx*delx + dely*dely + delz*delz;
+ r = sqrt(rsq);
+
+ // force & energy
+
+ uf_lookup(type,r,u,mdu);
+ fbond = mdu/r;
+ ebond = u;
+
+ // apply force to each of 2 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += delx*fbond;
+ f[i1][1] += dely*fbond;
+ f[i1][2] += delz*fbond;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] -= delx*fbond;
+ f[i2][1] -= dely*fbond;
+ f[i2][2] -= delz*fbond;
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i1,i2,nlocal,NEWTON_BOND,
+ ebond,fbond,delx,dely,delz,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/bond_table_omp.h
similarity index 71%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/bond_table_omp.h
index b24de4a57..3cf802222 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/bond_table_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef BOND_CLASS
-PairStyle(born/omp,PairBornOMP)
+BondStyle(table/omp,BondTableOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_BOND_TABLE_OMP_H
+#define LMP_BOND_TABLE_OMP_H
-#include "pair_born.h"
+#include "bond_table.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class BondTableOMP : public BondTable, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ BondTableOMP(class LAMMPS *lmp) :
+ BondTable(lmp), ThrOMP(lmp,THR_BOND) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_charmm_omp.cpp b/src/USER-OMP/dihedral_charmm_omp.cpp
index 63bfc4327..b4d7e2e4a 100644
--- a/src/USER-OMP/dihedral_charmm_omp.cpp
+++ b/src/USER-OMP/dihedral_charmm_omp.cpp
@@ -1,328 +1,319 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_charmm_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "pair.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
void DihedralCharmmOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
// insure pair->ev_tally() will use 1-4 virial contribution
if (weightflag && vflag_global == 2)
force->pair->vflag_either = force->pair->vflag_global = 1;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
-
- // reduce contributions to non-bonded energy terms
- for (int n = 0; n < nthreads; ++n) {
- force->pair->eng_vdwl += eng_vdwl_thr[n];
- force->pair->eng_coul += eng_coul_thr[n];
- }
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralCharmmOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralCharmmOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,i,m,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,p,sx2,sy2,sz2;
int itype,jtype;
double delx,dely,delz,rsq,r2inv,r6inv;
double forcecoul,forcelj,fpair,ecoul,evdwl;
edihedral = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *atomtype = atom->type;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const atomtype = atom->type;
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const double qqrd2e = force->qqrd2e;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c,s calculation
ax = vb1y*vb2zm - vb1z*vb2ym;
ay = vb1z*vb2xm - vb1x*vb2zm;
az = vb1x*vb2ym - vb1y*vb2xm;
bx = vb3y*vb2zm - vb3z*vb2ym;
by = vb3z*vb2xm - vb3x*vb2zm;
bz = vb3x*vb2ym - vb3y*vb2xm;
rasq = ax*ax + ay*ay + az*az;
rbsq = bx*bx + by*by + bz*bz;
rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
rg = sqrt(rgsq);
rginv = ra2inv = rb2inv = 0.0;
if (rg > 0) rginv = 1.0/rg;
if (rasq > 0) ra2inv = 1.0/rasq;
if (rbsq > 0) rb2inv = 1.0/rbsq;
rabinv = sqrt(ra2inv*rb2inv);
c = (ax*bx + ay*by + az*bz)*rabinv;
s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
m = multiplicity[type];
p = 1.0;
df1 = 0.0;
for (i = 0; i < m; i++) {
ddf1 = p*c - df1*s;
df1 = p*s + df1*c;
p = ddf1;
}
p = p*cos_shift[type] + df1*sin_shift[type];
df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
df1 *= -m;
p += 1.0;
if (m == 0) {
p = 1.0 + cos_shift[type];
df1 = 0.0;
}
if (EFLAG) edihedral = k[type] * p;
fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
fga = fg*ra2inv*rginv;
hgb = hg*rb2inv*rginv;
gaa = -ra2inv*rg;
gbb = rb2inv*rg;
dtfx = gaa*ax;
dtfy = gaa*ay;
dtfz = gaa*az;
dtgx = fga*ax - hgb*bx;
dtgy = fga*ay - hgb*by;
dtgz = fga*az - hgb*bz;
dthx = gbb*bx;
dthy = gbb*by;
dthz = gbb*bz;
df = -k[type] * df1;
sx2 = df*dtgx;
sy2 = df*dtgy;
sz2 = df*dtgz;
f1[0] = df*dtfx;
f1[1] = df*dtfy;
f1[2] = df*dtfz;
f2[0] = sx2 - f1[0];
f2[1] = sy2 - f1[1];
f2[2] = sz2 - f1[2];
f4[0] = df*dthx;
f4[1] = df*dthy;
f4[2] = df*dthz;
f3[0] = -sx2 - f4[0];
f3[1] = -sy2 - f4[1];
f3[2] = -sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
// 1-4 LJ and Coulomb interactions
// tally energy/virial in pair, using newton_bond as newton flag
if (weight[type] > 0.0) {
itype = atomtype[i1];
jtype = atomtype[i4];
delx = x[i1][0] - x[i4][0];
dely = x[i1][1] - x[i4][1];
delz = x[i1][2] - x[i4][2];
domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv;
else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv);
forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]);
fpair = weight[type] * (forcelj+forcecoul)*r2inv;
if (EFLAG) {
ecoul = weight[type] * forcecoul;
evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]);
evdwl *= weight[type];
}
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += delx*fpair;
f[i1][1] += dely*fpair;
f[i1][2] += delz*fpair;
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] -= delx*fpair;
f[i4][1] -= dely*fpair;
f[i4][2] -= delz*fpair;
}
if (EVFLAG) ev_tally_thr(force->pair,i1,i4,nlocal,NEWTON_BOND,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
}
diff --git a/src/USER-OMP/dihedral_charmm_omp.h b/src/USER-OMP/dihedral_charmm_omp.h
index a39ad83f7..75ba6410d 100644
--- a/src/USER-OMP/dihedral_charmm_omp.h
+++ b/src/USER-OMP/dihedral_charmm_omp.h
@@ -1,48 +1,48 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(charmm/omp,DihedralCharmmOMP)
#else
#ifndef LMP_DIHEDRAL_CHARMM_OMP_H
#define LMP_DIHEDRAL_CHARMM_OMP_H
#include "dihedral_charmm.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralCharmmOMP : public DihedralCharmm, public ThrOMP {
public:
DihedralCharmmOMP(class LAMMPS *lmp) :
- DihedralCharmm(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralCharmm(lmp), ThrOMP(lmp,THR_DIHEDRAL|THR_CHARMM) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_class2_omp.cpp b/src/USER-OMP/dihedral_class2_omp.cpp
index 734829664..07e0fba6e 100644
--- a/src/USER-OMP/dihedral_class2_omp.cpp
+++ b/src/USER-OMP/dihedral_class2_omp.cpp
@@ -1,532 +1,529 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.0000001
/* ---------------------------------------------------------------------- */
void DihedralClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralClass2OMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,i,j,k,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral;
double r1mag2,r1,r2mag2,r2,r3mag2,r3;
double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1;
double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c;
double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2;
double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3;
double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2;
double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0;
double r3_0,dr1,dr2,tk1,tk2,s12,sin2;
double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3];
double fabcd[4][3];
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// distances
r1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
r1 = sqrt(r1mag2);
r2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
r2 = sqrt(r2mag2);
r3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
r3 = sqrt(r3mag2);
sb1 = 1.0/r1mag2;
rb1 = 1.0/r1;
sb2 = 1.0/r2mag2;
rb2 = 1.0/r2;
sb3 = 1.0/r3mag2;
rb3 = 1.0/r3;
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// angles
r12c1 = rb1*rb2;
r12c2 = rb2*rb3;
costh12 = (vb1x*vb2x + vb1y*vb2y + vb1z*vb2z) * r12c1;
costh13 = c0;
costh23 = (vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z) * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - costh12*costh12,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - costh23*costh23,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
-
+
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + costh12*costh23) * s12;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
- int me;
- MPI_Comm_rank(world,&me);
+ int me = comm->me;
+
if (screen) {
char str[128];
- sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
- me,update->ntimestep,
+ sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
cosphi = c;
phi = acos(c);
sinphi = sqrt(1.0 - c*c);
sinphi = MAX(sinphi,SMALL);
a11 = -c*sb1*s1;
a22 = sb2 * (2.0*costh13*s12 - c*(s1+s2));
a33 = -c*sb3*s2;
a12 = r12c1 * (costh12*c*s1 + costh23*s12);
a13 = rb1*rb3*s12;
a23 = r12c2 * (-costh23*c*s2 - costh12*s12);
sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
// set up d(cos(phi))/d(r) and dphi/dr arrays
dcosphidr[0][0] = -sx1;
dcosphidr[0][1] = -sy1;
dcosphidr[0][2] = -sz1;
dcosphidr[1][0] = sx2 + sx1;
dcosphidr[1][1] = sy2 + sy1;
dcosphidr[1][2] = sz2 + sz1;
dcosphidr[2][0] = sx12 - sx2;
dcosphidr[2][1] = sy12 - sy2;
dcosphidr[2][2] = sz12 - sz2;
dcosphidr[3][0] = -sx12;
dcosphidr[3][1] = -sy12;
dcosphidr[3][2] = -sz12;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
dphidr[i][j] = -dcosphidr[i][j] / sinphi;
// energy
dphi1 = phi - phi1[type];
dphi2 = 2.0*phi - phi2[type];
dphi3 = 3.0*phi - phi3[type];
if (EFLAG) edihedral = k1[type]*(1.0 - cos(dphi1)) +
k2[type]*(1.0 - cos(dphi2)) +
k3[type]*(1.0 - cos(dphi3));
de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) +
3.0*k3[type]*sin(dphi3);
// torsion forces on all 4 atoms
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] = de_dihedral*dphidr[i][j];
// set up d(bond)/d(r) array
// dbonddr(i,j,k) = bond i, atom j, coordinate k
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 3; k++)
dbonddr[i][j][k] = 0.0;
// bond1
dbonddr[0][0][0] = vb1x / r1;
dbonddr[0][0][1] = vb1y / r1;
dbonddr[0][0][2] = vb1z / r1;
dbonddr[0][1][0] = -vb1x / r1;
dbonddr[0][1][1] = -vb1y / r1;
dbonddr[0][1][2] = -vb1z / r1;
// bond2
dbonddr[1][1][0] = vb2x / r2;
dbonddr[1][1][1] = vb2y / r2;
dbonddr[1][1][2] = vb2z / r2;
dbonddr[1][2][0] = -vb2x / r2;
dbonddr[1][2][1] = -vb2y / r2;
dbonddr[1][2][2] = -vb2z / r2;
// bond3
dbonddr[2][2][0] = vb3x / r3;
dbonddr[2][2][1] = vb3y / r3;
dbonddr[2][2][2] = vb3z / r3;
dbonddr[2][3][0] = -vb3x / r3;
dbonddr[2][3][1] = -vb3y / r3;
dbonddr[2][3][2] = -vb3z / r3;
// set up d(theta)/d(r) array
// dthetadr(i,j,k) = angle i, atom j, coordinate k
for (i = 0; i < 2; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 3; k++)
dthetadr[i][j][k] = 0.0;
t1 = costh12 / r1mag2;
t2 = costh23 / r2mag2;
t3 = costh12 / r2mag2;
t4 = costh23 / r3mag2;
// angle12
dthetadr[0][0][0] = sc1 * ((t1 * vb1x) - (vb2x * r12c1));
dthetadr[0][0][1] = sc1 * ((t1 * vb1y) - (vb2y * r12c1));
dthetadr[0][0][2] = sc1 * ((t1 * vb1z) - (vb2z * r12c1));
dthetadr[0][1][0] = sc1 * ((-t1 * vb1x) + (vb2x * r12c1) +
(-t3 * vb2x) + (vb1x * r12c1));
dthetadr[0][1][1] = sc1 * ((-t1 * vb1y) + (vb2y * r12c1) +
(-t3 * vb2y) + (vb1y * r12c1));
dthetadr[0][1][2] = sc1 * ((-t1 * vb1z) + (vb2z * r12c1) +
(-t3 * vb2z) + (vb1z * r12c1));
dthetadr[0][2][0] = sc1 * ((t3 * vb2x) - (vb1x * r12c1));
dthetadr[0][2][1] = sc1 * ((t3 * vb2y) - (vb1y * r12c1));
dthetadr[0][2][2] = sc1 * ((t3 * vb2z) - (vb1z * r12c1));
// angle23
dthetadr[1][1][0] = sc2 * ((t2 * vb2x) + (vb3x * r12c2));
dthetadr[1][1][1] = sc2 * ((t2 * vb2y) + (vb3y * r12c2));
dthetadr[1][1][2] = sc2 * ((t2 * vb2z) + (vb3z * r12c2));
dthetadr[1][2][0] = sc2 * ((-t2 * vb2x) - (vb3x * r12c2) +
(t4 * vb3x) + (vb2x * r12c2));
dthetadr[1][2][1] = sc2 * ((-t2 * vb2y) - (vb3y * r12c2) +
(t4 * vb3y) + (vb2y * r12c2));
dthetadr[1][2][2] = sc2 * ((-t2 * vb2z) - (vb3z * r12c2) +
(t4 * vb3z) + (vb2z * r12c2));
dthetadr[1][3][0] = -sc2 * ((t4 * vb3x) + (vb2x * r12c2));
dthetadr[1][3][1] = -sc2 * ((t4 * vb3y) + (vb2y * r12c2));
dthetadr[1][3][2] = -sc2 * ((t4 * vb3z) + (vb2z * r12c2));
// mid-bond/torsion coupling
// energy on bond2 (middle bond)
cos2phi = cos(2.0*phi);
cos3phi = cos(3.0*phi);
bt1 = mbt_f1[type] * cosphi;
bt2 = mbt_f2[type] * cos2phi;
bt3 = mbt_f3[type] * cos3phi;
sumbte = bt1 + bt2 + bt3;
db = r2 - mbt_r0[type];
if (EFLAG) edihedral += db * sumbte;
// force on bond2
bt1 = -mbt_f1[type] * sinphi;
bt2 = -2.0 * mbt_f2[type] * sin(2.0*phi);
bt3 = -3.0 * mbt_f3[type] * sin(3.0*phi);
sumbtf = bt1 + bt2 + bt3;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[1][i][j];
// end-bond/torsion coupling
// energy on bond1 (first bond)
bt1 = ebt_f1_1[type] * cosphi;
bt2 = ebt_f2_1[type] * cos2phi;
bt3 = ebt_f3_1[type] * cos3phi;
sumbte = bt1 + bt2 + bt3;
db = r1 - ebt_r0_1[type];
if (EFLAG) edihedral += db * (bt1+bt2+bt3);
// force on bond1
bt1 = ebt_f1_1[type] * sinphi;
bt2 = 2.0 * ebt_f2_1[type] * sin(2.0*phi);
bt3 = 3.0 * ebt_f3_1[type] * sin(3.0*phi);
sumbtf = bt1 + bt2 + bt3;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] -= db*sumbtf*dphidr[i][j] + sumbte*dbonddr[0][i][j];
// end-bond/torsion coupling
// energy on bond3 (last bond)
bt1 = ebt_f1_2[type] * cosphi;
bt2 = ebt_f2_2[type] * cos2phi;
bt3 = ebt_f3_2[type] * cos3phi;
sumbte = bt1 + bt2 + bt3;
db = r3 - ebt_r0_2[type];
if (EFLAG) edihedral += db * (bt1+bt2+bt3);
// force on bond3
bt1 = -ebt_f1_2[type] * sinphi;
bt2 = -2.0 * ebt_f2_2[type] * sin(2.0*phi);
bt3 = -3.0 * ebt_f3_2[type] * sin(3.0*phi);
sumbtf = bt1 + bt2 + bt3;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[2][i][j];
// angle/torsion coupling
// energy on angle1
at1 = at_f1_1[type] * cosphi;
at2 = at_f2_1[type] * cos2phi;
at3 = at_f3_1[type] * cos3phi;
sumbte = at1 + at2 + at3;
da = acos(costh12) - at_theta0_1[type];
if (EFLAG) edihedral += da * (at1+at2+at3);
// force on angle1
bt1 = at_f1_1[type] * sinphi;
bt2 = 2.0 * at_f2_1[type] * sin(2.0*phi);
bt3 = 3.0 * at_f3_1[type] * sin(3.0*phi);
sumbtf = bt1 + bt2 + bt3;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] -= da*sumbtf*dphidr[i][j] + sumbte*dthetadr[0][i][j];
// energy on angle2
at1 = at_f1_2[type] * cosphi;
at2 = at_f2_2[type] * cos2phi;
at3 = at_f3_2[type] * cos3phi;
sumbte = at1 + at2 + at3;
da = acos(costh23) - at_theta0_2[type];
if (EFLAG) edihedral += da * (at1+at2+at3);
// force on angle2
bt1 = -at_f1_2[type] * sinphi;
bt2 = -2.0 * at_f2_2[type] * sin(2.0*phi);
bt3 = -3.0 * at_f3_2[type] * sin(3.0*phi);
sumbtf = bt1 + bt2 + bt3;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] += da*sumbtf*dphidr[i][j] + sumbte*dthetadr[1][i][j];
// angle/angle/torsion coupling
da1 = acos(costh12) - aat_theta0_1[type];
da2 = acos(costh23) - aat_theta0_2[type];
if (EFLAG) edihedral += aat_k[type]*da1*da2*cosphi;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
fabcd[i][j] -= aat_k[type] *
(cosphi * (da2*dthetadr[0][i][j] - da1*dthetadr[1][i][j]) +
sinphi * da1*da2*dphidr[i][j]);
// bond1/bond3 coupling
if (fabs(bb13t_k[type]) > SMALL) {
r1_0 = bb13t_r10[type];
r3_0 = bb13t_r30[type];
dr1 = r1 - r1_0;
dr2 = r3 - r3_0;
tk1 = -bb13t_k[type] * dr1 / r3;
tk2 = -bb13t_k[type] * dr2 / r1;
if (EFLAG) edihedral += bb13t_k[type]*dr1*dr2;
fabcd[0][0] += tk2 * vb1x;
fabcd[0][1] += tk2 * vb1y;
fabcd[0][2] += tk2 * vb1z;
fabcd[1][0] -= tk2 * vb1x;
fabcd[1][1] -= tk2 * vb1y;
fabcd[1][2] -= tk2 * vb1z;
fabcd[2][0] -= tk1 * vb3x;
fabcd[2][1] -= tk1 * vb3y;
fabcd[2][2] -= tk1 * vb3z;
fabcd[3][0] += tk1 * vb3x;
fabcd[3][1] += tk1 * vb3y;
fabcd[3][2] += tk1 * vb3z;
}
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += fabcd[0][0];
f[i1][1] += fabcd[0][1];
f[i1][2] += fabcd[0][2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += fabcd[1][0];
f[i2][1] += fabcd[1][1];
f[i2][2] += fabcd[1][2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += fabcd[2][0];
f[i3][1] += fabcd[2][1];
f[i3][2] += fabcd[2][2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += fabcd[3][0];
f[i4][1] += fabcd[3][1];
f[i4][2] += fabcd[3][2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,
fabcd[0],fabcd[2],fabcd[3],
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_class2_omp.h b/src/USER-OMP/dihedral_class2_omp.h
index d26f2f871..14a6c40ed 100644
--- a/src/USER-OMP/dihedral_class2_omp.h
+++ b/src/USER-OMP/dihedral_class2_omp.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(class2/omp,DihedralClass2OMP)
#else
#ifndef LMP_DIHEDRAL_CLASS2_OMP_H
#define LMP_DIHEDRAL_CLASS2_OMP_H
#include "dihedral_class2.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralClass2OMP : public DihedralClass2, public ThrOMP {
public:
DihedralClass2OMP(class LAMMPS *lmp) :
- DihedralClass2(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralClass2(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
index a6c027e92..1a80e8a7c 100644
--- a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
+++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
@@ -1,263 +1,260 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_cosine_shift_exp_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
void DihedralCosineShiftExpOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralCosineShiftExpOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralCosineShiftExpOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,sx2,sy2,sz2;
double cccpsss,cssmscc,exp2;
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c,s calculation
ax = vb1y*vb2zm - vb1z*vb2ym;
ay = vb1z*vb2xm - vb1x*vb2zm;
az = vb1x*vb2ym - vb1y*vb2xm;
bx = vb3y*vb2zm - vb3z*vb2ym;
by = vb3z*vb2xm - vb3x*vb2zm;
bz = vb3x*vb2ym - vb3y*vb2xm;
rasq = ax*ax + ay*ay + az*az;
rbsq = bx*bx + by*by + bz*bz;
rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
rg = sqrt(rgsq);
rginv = ra2inv = rb2inv = 0.0;
if (rg > 0) rginv = 1.0/rg;
if (rasq > 0) ra2inv = 1.0/rasq;
if (rbsq > 0) rb2inv = 1.0/rbsq;
rabinv = sqrt(ra2inv*rb2inv);
c = (ax*bx + ay*by + az*bz)*rabinv;
s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
-
+
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double aa=a[type];
double uumin=umin[type];
cccpsss = c*cost[type]+s*sint[type];
cssmscc = c*sint[type]-s*cost[type];
if (doExpansion[type]) {
// |a|<0.001 so use expansions relative precision <1e-5
if (EFLAG) edihedral = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
df=0.5*uumin*( cssmscc + 0.5*aa*cccpsss);
} else {
exp2=exp(0.5*aa*(1+cccpsss));
if (EFLAG) edihedral = opt1[type]*(1-exp2);
df= 0.5*opt1[type]*aa* ( exp2*cssmscc );
}
fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
fga = fg*ra2inv*rginv;
hgb = hg*rb2inv*rginv;
gaa = -ra2inv*rg;
gbb = rb2inv*rg;
dtfx = gaa*ax;
dtfy = gaa*ay;
dtfz = gaa*az;
dtgx = fga*ax - hgb*bx;
dtgy = fga*ay - hgb*by;
dtgz = fga*az - hgb*bz;
dthx = gbb*bx;
dthy = gbb*by;
dthz = gbb*bz;
sx2 = df*dtgx;
sy2 = df*dtgy;
sz2 = df*dtgz;
f1[0] = df*dtfx;
f1[1] = df*dtfy;
f1[2] = df*dtfz;
f2[0] = sx2 - f1[0];
f2[1] = sy2 - f1[1];
f2[2] = sz2 - f1[2];
f4[0] = df*dthx;
f4[1] = df*dthy;
f4[2] = df*dthz;
f3[0] = -sx2 - f4[0];
f3[1] = -sy2 - f4[1];
f3[2] = -sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.h b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h
index eb906ab95..54627c169 100644
--- a/src/USER-OMP/dihedral_cosine_shift_exp_omp.h
+++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(cosine/shift/exp/omp,DihedralCosineShiftExpOMP)
#else
#ifndef LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H
#define LMP_DIHEDRAL_COSINE_SHIFT_EXP_OMP_H
#include "dihedral_cosine_shift_exp.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralCosineShiftExpOMP : public DihedralCosineShiftExp, public ThrOMP {
public:
DihedralCosineShiftExpOMP(class LAMMPS *lmp) :
- DihedralCosineShiftExp(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralCosineShiftExp(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_harmonic_omp.cpp b/src/USER-OMP/dihedral_harmonic_omp.cpp
index 0fa24090a..cdad9b6ab 100644
--- a/src/USER-OMP/dihedral_harmonic_omp.cpp
+++ b/src/USER-OMP/dihedral_harmonic_omp.cpp
@@ -1,270 +1,266 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
void DihedralHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralHarmonicOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,i,m,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,p,sx2,sy2,sz2;
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c,s calculation
ax = vb1y*vb2zm - vb1z*vb2ym;
ay = vb1z*vb2xm - vb1x*vb2zm;
az = vb1x*vb2ym - vb1y*vb2xm;
bx = vb3y*vb2zm - vb3z*vb2ym;
by = vb3z*vb2xm - vb3x*vb2zm;
bz = vb3x*vb2ym - vb3y*vb2xm;
rasq = ax*ax + ay*ay + az*az;
rbsq = bx*bx + by*by + bz*bz;
rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
rg = sqrt(rgsq);
rginv = ra2inv = rb2inv = 0.0;
if (rg > 0) rginv = 1.0/rg;
if (rasq > 0) ra2inv = 1.0/rasq;
if (rbsq > 0) rb2inv = 1.0/rbsq;
rabinv = sqrt(ra2inv*rb2inv);
c = (ax*bx + ay*by + az*bz)*rabinv;
s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
m = multiplicity[type];
p = 1.0;
df1 = 0.0;
for (i = 0; i < m; i++) {
ddf1 = p*c - df1*s;
df1 = p*s + df1*c;
p = ddf1;
}
p = p*cos_shift[type] + df1*sin_shift[type];
df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
df1 *= -m;
p += 1.0;
if (m == 0) {
p = 1.0 + cos_shift[type];
df1 = 0.0;
}
if (EFLAG) edihedral = k[type] * p;
fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
fga = fg*ra2inv*rginv;
hgb = hg*rb2inv*rginv;
gaa = -ra2inv*rg;
gbb = rb2inv*rg;
dtfx = gaa*ax;
dtfy = gaa*ay;
dtfz = gaa*az;
dtgx = fga*ax - hgb*bx;
dtgy = fga*ay - hgb*by;
dtgz = fga*az - hgb*bz;
dthx = gbb*bx;
dthy = gbb*by;
dthz = gbb*bz;
df = -k[type] * df1;
sx2 = df*dtgx;
sy2 = df*dtgy;
sz2 = df*dtgz;
f1[0] = df*dtfx;
f1[1] = df*dtfy;
f1[2] = df*dtfz;
f2[0] = sx2 - f1[0];
f2[1] = sy2 - f1[1];
f2[2] = sz2 - f1[2];
f4[0] = df*dthx;
f4[1] = df*dthy;
f4[2] = df*dthz;
f3[0] = -sx2 - f4[0];
f3[1] = -sy2 - f4[1];
f3[2] = -sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
-
diff --git a/src/USER-OMP/dihedral_harmonic_omp.h b/src/USER-OMP/dihedral_harmonic_omp.h
index 2d7bae64e..8b8562ad9 100644
--- a/src/USER-OMP/dihedral_harmonic_omp.h
+++ b/src/USER-OMP/dihedral_harmonic_omp.h
@@ -1,48 +1,48 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(harmonic/omp,DihedralHarmonicOMP)
#else
#ifndef LMP_DIHEDRAL_HARMONIC_OMP_H
#define LMP_DIHEDRAL_HARMONIC_OMP_H
#include "dihedral_harmonic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralHarmonicOMP : public DihedralHarmonic, public ThrOMP {
public:
DihedralHarmonicOMP(class LAMMPS *lmp) :
- DihedralHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralHarmonic(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp
index 4ec701a0c..b9b61982f 100644
--- a/src/USER-OMP/dihedral_helix_omp.cpp
+++ b/src/USER-OMP/dihedral_helix_omp.cpp
@@ -1,282 +1,279 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_helix_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
void DihedralHelixOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralHelixOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralHelixOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
double a33,a12,a13,a23,sx2,sy2,sz2;
double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c0 calculation
-
+
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
-
+
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
-
+
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
-
+
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
cx = vb1y*vb2z - vb1z*vb2y;
cy = vb1z*vb2x - vb1x*vb2z;
cz = vb1x*vb2y - vb1y*vb2x;
cmag = sqrt(cx*cx + cy*cy + cz*cz);
dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
-
+
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
+
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
-
+
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
phi = acos(c);
if (dx < 0.0) phi *= -1.0;
si = sin(phi);
if (fabs(si) < SMALLER) si = SMALLER;
siinv = 1.0/si;
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
cphi[type]*sin(phi + MY_PI4)*siinv;
if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) +
cphi[type]*(1.0 + cos(phi + MY_PI4));
-;
a = pd;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_helix_omp.h b/src/USER-OMP/dihedral_helix_omp.h
index 792319741..e932045cf 100644
--- a/src/USER-OMP/dihedral_helix_omp.h
+++ b/src/USER-OMP/dihedral_helix_omp.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(helix/omp,DihedralHelixOMP)
#else
#ifndef LMP_DIHEDRAL_HELIX_OMP_H
#define LMP_DIHEDRAL_HELIX_OMP_H
#include "dihedral_helix.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralHelixOMP : public DihedralHelix, public ThrOMP {
public:
DihedralHelixOMP(class LAMMPS *lmp) :
- DihedralHelix(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralHelix(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
index bde958984..822ddb796 100644
--- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
@@ -1,269 +1,266 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_multi_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
void DihedralMultiHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralMultiHarmonicOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralMultiHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
double a33,a12,a13,a23,sx2,sy2,sz2;
double s2,sin2;
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
// p = sum (i=1,5) a_i * c**(i-1)
// pd = dp/dc
pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
if (EFLAG)
edihedral = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
a = pd;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.h b/src/USER-OMP/dihedral_multi_harmonic_omp.h
index da2322f03..628ad2a6a 100644
--- a/src/USER-OMP/dihedral_multi_harmonic_omp.h
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(multi/harmonic/omp,DihedralMultiHarmonicOMP)
#else
#ifndef LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H
#define LMP_DIHEDRAL_MULTI_HARMONIC_OMP_H
#include "dihedral_multi_harmonic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralMultiHarmonicOMP : public DihedralMultiHarmonic, public ThrOMP {
public:
DihedralMultiHarmonicOMP(class LAMMPS *lmp) :
- DihedralMultiHarmonic(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralMultiHarmonic(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_opls_omp.cpp b/src/USER-OMP/dihedral_opls_omp.cpp
index 9f59e26d2..6e46575f3 100644
--- a/src/USER-OMP/dihedral_opls_omp.cpp
+++ b/src/USER-OMP/dihedral_opls_omp.cpp
@@ -1,286 +1,283 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_opls_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
void DihedralOPLSOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralOPLSOMP::eval(double **f, int nfrom, int nto, int tid)
+void DihedralOPLSOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,i4,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double edihedral,f1[3],f2[3],f3[3],f4[3];
double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
double a33,a12,a13,a23,sx2,sy2,sz2;
double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
edihedral = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const dihedrallist = neighbor->dihedrallist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3];
type = dihedrallist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
cx = vb1y*vb2z - vb1z*vb2y;
cy = vb1z*vb2x - vb1x*vb2z;
cz = vb1x*vb2y - vb1y*vb2x;
cmag = sqrt(cx*cx + cy*cy + cz*cz);
dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
-
+
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
// p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) )
// pd = dp/dc
phi = acos(c);
if (dx < 0.0) phi *= -1.0;
si = sin(phi);
if (fabs(si) < SMALLER) si = SMALLER;
siinv = 1.0/si;
pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv +
3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv;
if (EFLAG) edihedral = k1[type]*(1.0 + c) + k2[type]*(1.0 - cos(2.0*phi))
+ k3[type]*(1.0 + cos(3.0*phi)) + k4[type]*(1.0 - cos(4.0*phi));
a = pd;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_opls_omp.h b/src/USER-OMP/dihedral_opls_omp.h
index 58b992053..44c76bb2a 100644
--- a/src/USER-OMP/dihedral_opls_omp.h
+++ b/src/USER-OMP/dihedral_opls_omp.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef DIHEDRAL_CLASS
DihedralStyle(opls/omp,DihedralOPLSOMP)
#else
#ifndef LMP_DIHEDRAL_OPLS_OMP_H
#define LMP_DIHEDRAL_OPLS_OMP_H
#include "dihedral_opls.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class DihedralOPLSOMP : public DihedralOPLS, public ThrOMP {
public:
DihedralOPLSOMP(class LAMMPS *lmp) :
- DihedralOPLS(lmp), ThrOMP(lmp,DIHEDRAL) {};
+ DihedralOPLS(lmp), ThrOMP(lmp,THR_DIHEDRAL) {};
virtual void compute(int, int);
private:
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/ewald_omp.cpp b/src/USER-OMP/ewald_omp.cpp
new file mode 100644
index 000000000..ea2c33d5d
--- /dev/null
+++ b/src/USER-OMP/ewald_omp.cpp
@@ -0,0 +1,386 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Roy Pollock (LLNL), Paul Crozier (SNL)
+------------------------------------------------------------------------- */
+
+#include "mpi.h"
+#include "ewald_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+
+#include <math.h>
+
+#include "math_const.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+#define SMALL 0.00001
+
+/* ---------------------------------------------------------------------- */
+
+EwaldOMP::EwaldOMP(LAMMPS *lmp, int narg, char **arg)
+ : Ewald(lmp, narg, arg), ThrOMP(lmp, THR_KSPACE)
+{ }
+
+/* ---------------------------------------------------------------------- */
+void EwaldOMP::allocate()
+{
+ Ewald::allocate();
+
+ // always re-allocate for simplicity.
+ delete[] sfacrl;
+ delete[] sfacim;
+
+ sfacrl = new double[kmax3d*comm->nthreads];
+ sfacim = new double[kmax3d*comm->nthreads];
+}
+
+/* ----------------------------------------------------------------------
+ compute the Ewald long-range force, energy, virial
+------------------------------------------------------------------------- */
+
+void EwaldOMP::compute(int eflag, int vflag)
+{
+ // clear out global energy/virial
+
+ energy = 0.0;
+ if (vflag) for (int n = 0; n < 6; n++) virial[n] = 0.0;
+
+ // extend size of per-atom arrays if necessary
+
+ if (atom->nlocal > nmax) {
+ memory->destroy(ek);
+ memory->destroy3d_offset(cs,-kmax_created);
+ memory->destroy3d_offset(sn,-kmax_created);
+ nmax = atom->nmax;
+ memory->create(ek,nmax,3,"ewald:ek");
+ memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs");
+ memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn");
+ kmax_created = kmax;
+ }
+
+ // partial structure factors on each processor
+ // total structure factor by summing over procs
+
+ eik_dot_r();
+ MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world);
+ MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world);
+
+ // K-space portion of electric field
+ // double loop over K-vectors and local atoms
+
+ double * const * const f = atom->f;
+ const double * const q = atom->q;
+ const int nthreads = comm->nthreads;
+ const int nlocal = atom->nlocal;
+ const double qscale = force->qqrd2e * scale;
+
+ double eng_tmp = 0.0;
+ double v0,v1,v2,v3,v4,v5;
+ v0=v1=v2=v3=v4=v5=0.0;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag) reduction(+:eng_tmp,v0,v1,v2,v3,v4,v5)
+#endif
+ {
+
+ int i,k,ifrom,ito,tid;
+ int kx,ky,kz;
+ double cypz,sypz,exprl,expim,partial;
+
+ loop_setup_thr(ifrom, ito, tid, nlocal, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, 0, NULL, NULL, thr);
+
+ for (i = ifrom; i < ito; i++) {
+ ek[i][0] = 0.0;
+ ek[i][1] = 0.0;
+ ek[i][2] = 0.0;
+ }
+
+ for (k = 0; k < kcount; k++) {
+ kx = kxvecs[k];
+ ky = kyvecs[k];
+ kz = kzvecs[k];
+
+ for (i = ifrom; i < ito; i++) {
+ cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i];
+ sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i];
+ exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz;
+ expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz;
+ partial = expim*sfacrl_all[k] - exprl*sfacim_all[k];
+ ek[i][0] += partial*eg[k][0];
+ ek[i][1] += partial*eg[k][1];
+ ek[i][2] += partial*eg[k][2];
+ }
+ }
+
+ // convert E-field to force
+
+ for (i = ifrom; i < ito; i++) {
+ const double fac = qscale*q[i];
+ f[i][0] += fac*ek[i][0];
+ f[i][1] += fac*ek[i][1];
+ f[i][2] += fac*ek[i][2];
+ }
+
+ // energy if requested
+
+ if (eflag) {
+#if defined(_OPENMP)
+#pragma omp for private(k)
+#endif
+ for (k = 0; k < kcount; k++)
+ eng_tmp += ug[k] * (sfacrl_all[k]*sfacrl_all[k] +
+ sfacim_all[k]*sfacim_all[k]);
+ }
+
+ // virial if requested
+
+ if (vflag) {
+#if defined(_OPENMP)
+#pragma omp for private(k)
+#endif
+ for (k = 0; k < kcount; k++) {
+ double uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]);
+ v0 += uk*vg[k][0];
+ v1 += uk*vg[k][1];
+ v2 += uk*vg[k][2];
+ v3 += uk*vg[k][3];
+ v4 += uk*vg[k][4];
+ v5 += uk*vg[k][5];
+ }
+ }
+
+ reduce_thr(this, eflag,vflag,thr);
+ } // end of omp parallel region
+
+ if (eflag) {
+ eng_tmp -= g_ewald*qsqsum/MY_PIS +
+ MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
+ energy = eng_tmp * qscale;
+ }
+
+ if (vflag) {
+ virial[0] = v0 * qscale;
+ virial[1] = v1 * qscale;
+ virial[2] = v2 * qscale;
+ virial[3] = v3 * qscale;
+ virial[4] = v4 * qscale;
+ virial[5] = v5 * qscale;
+ }
+
+ if (slabflag) slabcorr(eflag);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void EwaldOMP::eik_dot_r()
+{
+ const double * const * const x = atom->x;
+ const double * const q = atom->q;
+ const int nlocal = atom->nlocal;
+ const int nthreads = comm->nthreads;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+ int i,ifrom,ito,k,l,m,n,ic,tid;
+ double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4;
+ double sqk,clpm,slpm;
+
+ loop_setup_thr(ifrom, ito, tid, nlocal, nthreads);
+
+ double * const sfacrl_thr = sfacrl + tid*kmax3d;
+ double * const sfacim_thr = sfacim + tid*kmax3d;
+
+ n = 0;
+
+ // (k,0,0), (0,l,0), (0,0,m)
+
+ for (ic = 0; ic < 3; ic++) {
+ sqk = unitk[ic]*unitk[ic];
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ cs[0][ic][i] = 1.0;
+ sn[0][ic][i] = 0.0;
+ cs[1][ic][i] = cos(unitk[ic]*x[i][ic]);
+ sn[1][ic][i] = sin(unitk[ic]*x[i][ic]);
+ cs[-1][ic][i] = cs[1][ic][i];
+ sn[-1][ic][i] = -sn[1][ic][i];
+ cstr1 += q[i]*cs[1][ic][i];
+ sstr1 += q[i]*sn[1][ic][i];
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ }
+ }
+
+ for (m = 2; m <= kmax; m++) {
+ for (ic = 0; ic < 3; ic++) {
+ sqk = m*unitk[ic] * m*unitk[ic];
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] -
+ sn[m-1][ic][i]*sn[1][ic][i];
+ sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] +
+ cs[m-1][ic][i]*sn[1][ic][i];
+ cs[-m][ic][i] = cs[m][ic][i];
+ sn[-m][ic][i] = -sn[m][ic][i];
+ cstr1 += q[i]*cs[m][ic][i];
+ sstr1 += q[i]*sn[m][ic][i];
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ }
+ }
+ }
+
+ // 1 = (k,l,0), 2 = (k,-l,0)
+
+ for (k = 1; k <= kmax; k++) {
+ for (l = 1; l <= kmax; l++) {
+ sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]);
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ cstr2 = 0.0;
+ sstr2 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ cstr1 += q[i]*(cs[k][0][i]*cs[l][1][i] - sn[k][0][i]*sn[l][1][i]);
+ sstr1 += q[i]*(sn[k][0][i]*cs[l][1][i] + cs[k][0][i]*sn[l][1][i]);
+ cstr2 += q[i]*(cs[k][0][i]*cs[l][1][i] + sn[k][0][i]*sn[l][1][i]);
+ sstr2 += q[i]*(sn[k][0][i]*cs[l][1][i] - cs[k][0][i]*sn[l][1][i]);
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ sfacrl_thr[n] = cstr2;
+ sfacim_thr[n++] = sstr2;
+ }
+ }
+ }
+
+ // 1 = (0,l,m), 2 = (0,l,-m)
+
+ for (l = 1; l <= kmax; l++) {
+ for (m = 1; m <= kmax; m++) {
+ sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]);
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ cstr2 = 0.0;
+ sstr2 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ cstr1 += q[i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]);
+ sstr1 += q[i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]);
+ cstr2 += q[i]*(cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]);
+ sstr2 += q[i]*(sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]);
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ sfacrl_thr[n] = cstr2;
+ sfacim_thr[n++] = sstr2;
+ }
+ }
+ }
+
+ // 1 = (k,0,m), 2 = (k,0,-m)
+
+ for (k = 1; k <= kmax; k++) {
+ for (m = 1; m <= kmax; m++) {
+ sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]);
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ cstr2 = 0.0;
+ sstr2 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ cstr1 += q[i]*(cs[k][0][i]*cs[m][2][i] - sn[k][0][i]*sn[m][2][i]);
+ sstr1 += q[i]*(sn[k][0][i]*cs[m][2][i] + cs[k][0][i]*sn[m][2][i]);
+ cstr2 += q[i]*(cs[k][0][i]*cs[m][2][i] + sn[k][0][i]*sn[m][2][i]);
+ sstr2 += q[i]*(sn[k][0][i]*cs[m][2][i] - cs[k][0][i]*sn[m][2][i]);
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ sfacrl_thr[n] = cstr2;
+ sfacim_thr[n++] = sstr2;
+ }
+ }
+ }
+
+ // 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m)
+
+ for (k = 1; k <= kmax; k++) {
+ for (l = 1; l <= kmax; l++) {
+ for (m = 1; m <= kmax; m++) {
+ sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) +
+ (m*unitk[2] * m*unitk[2]);
+ if (sqk <= gsqmx) {
+ cstr1 = 0.0;
+ sstr1 = 0.0;
+ cstr2 = 0.0;
+ sstr2 = 0.0;
+ cstr3 = 0.0;
+ sstr3 = 0.0;
+ cstr4 = 0.0;
+ sstr4 = 0.0;
+ for (i = ifrom; i < ito; i++) {
+ clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
+ slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
+ cstr1 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
+ sstr1 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
+
+ clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
+ slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
+ cstr2 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
+ sstr2 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
+
+ clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
+ slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
+ cstr3 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
+ sstr3 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
+
+ clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
+ slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
+ cstr4 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
+ sstr4 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
+ }
+ sfacrl_thr[n] = cstr1;
+ sfacim_thr[n++] = sstr1;
+ sfacrl_thr[n] = cstr2;
+ sfacim_thr[n++] = sstr2;
+ sfacrl_thr[n] = cstr3;
+ sfacim_thr[n++] = sstr3;
+ sfacrl_thr[n] = cstr4;
+ sfacim_thr[n++] = sstr4;
+ }
+ }
+ }
+ }
+
+ sync_threads();
+ data_reduce_thr(sfacrl,kmax3d,nthreads,1,tid);
+ data_reduce_thr(sfacim,kmax3d,nthreads,1,tid);
+
+ } // end of parallel region
+}
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/USER-OMP/ewald_omp.h
similarity index 62%
copy from src/GRANULAR/pair_gran_hooke.h
copy to src/USER-OMP/ewald_omp.h
index d5cff796f..515a74ed3 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/USER-OMP/ewald_omp.h
@@ -1,36 +1,42 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef KSPACE_CLASS
-PairStyle(gran/hooke,PairGranHooke)
+KSpaceStyle(ewald/omp,EwaldOMP)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_H
-#define LMP_PAIR_GRAN_HOOKE_H
+#ifndef LMP_EWALD_OMP_H
+#define LMP_EWALD_OMP_H
-#include "pair_gran_hooke_history.h"
+#include "ewald.h"
+#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairGranHooke : public PairGranHookeHistory {
+ class EwaldOMP : public Ewald, public ThrOMP {
public:
- PairGranHooke(class LAMMPS *);
+ EwaldOMP(class LAMMPS *, int, char **);
+ virtual ~EwaldOMP() { };
+ virtual void allocate();
virtual void compute(int, int);
+
+ protected:
+ virtual void eik_dot_r();
};
}
#endif
#endif
diff --git a/src/USER-OMP/fix_nve_sphere_omp.cpp b/src/USER-OMP/fix_nve_sphere_omp.cpp
index a642b21f2..93af055f8 100644
--- a/src/USER-OMP/fix_nve_sphere_omp.cpp
+++ b/src/USER-OMP/fix_nve_sphere_omp.cpp
@@ -1,140 +1,136 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "fix_nve_sphere_omp.h"
#include "atom.h"
#include "atom_vec.h"
#include "update.h"
#include "respa.h"
#include "force.h"
#include "error.h"
using namespace LAMMPS_NS;
#define INERTIA 0.4 // moment of inertia prefactor for sphere
enum{NONE,DIPOLE};
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void FixNVESphereOMP::initial_integrate(int vflag)
{
- double **x = atom->x;
- double **v = atom->v;
- double **f = atom->f;
- double **omega = atom->omega;
- double **torque = atom->torque;
- double *radius = atom->radius;
- double *rmass = atom->rmass;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
+ double * const * const x = atom->x;
+ double * const * const v = atom->v;
+ const double * const * const f = atom->f;
+ double * const * const omega = atom->omega;
+ const double * const * const torque = atom->torque;
+ const double * const radius = atom->radius;
+ const double * const rmass = atom->rmass;
+ const int * const mask = atom->mask;
+ const int nlocal = (igroup == atom->firstgroup) ? atom->nfirst : atom->nlocal;
int i;
- if (igroup == atom->firstgroup) nlocal = atom->nfirst;
-
// set timestep here since dt may have changed or come via rRESPA
const double dtfrotate = dtf / INERTIA;
// update v,x,omega for all particles
// d_omega/dt = torque / inertia
#if defined(_OPENMP)
-#pragma omp parallel for private(i) default(shared)
+#pragma omp parallel for private(i) default(none)
#endif
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
const double dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]);
omega[i][0] += dtirotate * torque[i][0];
omega[i][1] += dtirotate * torque[i][1];
omega[i][2] += dtirotate * torque[i][2];
}
}
// update mu for dipoles
// d_mu/dt = omega cross mu
// renormalize mu to dipole length
if (extra == DIPOLE) {
- double **mu = atom->mu;
+ double * const * const mu = atom->mu;
#if defined(_OPENMP)
-#pragma omp parallel for private(i) default(shared)
+#pragma omp parallel for private(i) default(none)
#endif
for (i = 0; i < nlocal; i++) {
double g0,g1,g2,msq,scale;
if (mask[i] & groupbit) {
if (mu[i][3] > 0.0) {
g0 = mu[i][0] + dtv * (omega[i][1]*mu[i][2]-omega[i][2]*mu[i][1]);
g1 = mu[i][1] + dtv * (omega[i][2]*mu[i][0]-omega[i][0]*mu[i][2]);
g2 = mu[i][2] + dtv * (omega[i][0]*mu[i][1]-omega[i][1]*mu[i][0]);
msq = g0*g0 + g1*g1 + g2*g2;
scale = mu[i][3]/sqrt(msq);
mu[i][0] = g0*scale;
mu[i][1] = g1*scale;
mu[i][2] = g2*scale;
}
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixNVESphereOMP::final_integrate()
{
- double **v = atom->v;
- double **f = atom->f;
- double **omega = atom->omega;
- double **torque = atom->torque;
- double *rmass = atom->rmass;
- double *radius = atom->radius;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
+ double * const * const v = atom->v;
+ const double * const * const f = atom->f;
+ double * const * const omega = atom->omega;
+ const double * const * const torque = atom->torque;
+ const double * const rmass = atom->rmass;
+ const double * const radius = atom->radius;
+ const int * const mask = atom->mask;
+ const int nlocal = (igroup == atom->firstgroup) ? atom->nfirst : atom->nlocal;
int i;
- if (igroup == atom->firstgroup) nlocal = atom->nfirst;
-
// set timestep here since dt may have changed or come via rRESPA
const double dtfrotate = dtf / INERTIA;
// update v,omega for all particles
// d_omega/dt = torque / inertia
#if defined(_OPENMP)
-#pragma omp parallel for private(i) default(shared)
+#pragma omp parallel for private(i) default(none)
#endif
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
const double dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
v[i][1] += dtfm * f[i][1];
v[i][2] += dtfm * f[i][2];
const double dtirotate = dtfrotate / (radius[i]*radius[i]*rmass[i]);
omega[i][0] += dtirotate * torque[i][0];
omega[i][1] += dtirotate * torque[i][1];
omega[i][2] += dtirotate * torque[i][2];
}
}
diff --git a/src/USER-OMP/fix_omp.cpp b/src/USER-OMP/fix_omp.cpp
new file mode 100644
index 000000000..29c577c48
--- /dev/null
+++ b/src/USER-OMP/fix_omp.cpp
@@ -0,0 +1,279 @@
+/* ----------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ OpenMP based threading support for LAMMPS
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_request.h"
+#include "update.h"
+#include "integrate.h"
+#include "min.h"
+
+#include "fix_omp.h"
+#include "thr_data.h"
+#include "thr_omp.h"
+
+#include "pair_hybrid.h"
+#include "bond_hybrid.h"
+#include "angle_hybrid.h"
+#include "dihedral_hybrid.h"
+#include "improper_hybrid.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace LAMMPS_NS;
+
+static int get_tid()
+{
+ int tid = 0;
+#if defined(_OPENMP)
+ tid = omp_get_thread_num();
+#endif
+ return tid;
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixOMP::FixOMP(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg),
+ thr(NULL), last_omp_style(NULL), _nthr(-1), _neighbor(true), _newton(false)
+{
+ if ((narg < 4) || (narg > 6)) error->all(FLERR,"Illegal fix OMP command");
+ if (strcmp(arg[1],"all") != 0) error->all(FLERR,"Illegal fix OMP command");
+
+ int nthreads = 1;
+ if (narg > 3) {
+#if defined(_OPENMP)
+ if (strcmp(arg[3],"*") == 0)
+#pragma omp parallel default(none) shared(nthreads)
+ nthreads = omp_get_num_threads();
+ else
+ nthreads = atoi(arg[3]);
+#endif
+ }
+
+ if (nthreads < 1)
+ error->all(FLERR,"Illegal number of threads requested.");
+
+ if (nthreads != comm->nthreads) {
+#if defined(_OPENMP)
+ omp_set_num_threads(nthreads);
+#endif
+ comm->nthreads = nthreads;
+ if (comm->me == 0) {
+ if (screen)
+ fprintf(screen," reset %d OpenMP thread(s) per MPI task\n", nthreads);
+ if (logfile)
+ fprintf(logfile," reset %d OpenMP thread(s) per MPI task\n", nthreads);
+ }
+ }
+
+ if (narg > 4) {
+ if (strcmp(arg[4],"force/neigh") == 0)
+ _neighbor = true;
+ else if (strcmp(arg[4],"force") == 0)
+ _neighbor = false;
+ else
+ error->all(FLERR,"Illegal fix omp mode requested.");
+
+ if (comm->me == 0) {
+ const char * const mode = _neighbor ? "OpenMP capable" : "serial";
+
+ if (screen)
+ fprintf(screen," using %s neighbor list subroutines\n", mode);
+ if (logfile)
+ fprintf(logfile," using %s neighbor list subroutines\n", mode);
+ }
+ }
+
+#if 0 /* to be enabled when we can switch between half and full neighbor lists */
+ if (narg > 5) {
+ if (strcmp(arg[5],"neigh/half") == 0)
+ _newton = true;
+ else if (strcmp(arg[5],"neigh/full") == 0)
+ _newton = false;
+ else
+ error->all(FLERR,"Illegal fix OMP command");
+
+ if (comm->me == 0) {
+ const char * const mode = _newton ? "half" : "full";
+
+ if (screen)
+ fprintf(screen," using /omp styles with %s neighbor list builds\n", mode);
+ if (logfile)
+ fprintf(logfile," using /omp styles with %s neighbor list builds\n", mode);
+ }
+ }
+#endif
+
+ // allocate list for per thread accumulator manager class instances
+ // and then have each thread create an instance of this class to
+ // encourage the OS to use storage that is "close" to each thread's CPU.
+ thr = new ThrData *[nthreads];
+ _nthr = nthreads;
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+ const int tid = get_tid();
+ thr[tid] = new ThrData(tid);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixOMP::~FixOMP()
+{
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+ const int tid = get_tid();
+ delete thr[tid];
+ }
+ delete[] thr;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixOMP::setmask()
+{
+ int mask = 0;
+ mask |= PRE_FORCE;
+ mask |= PRE_FORCE_RESPA;
+ mask |= MIN_PRE_FORCE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixOMP::init()
+{
+ if (strstr(update->integrate_style,"respa") != NULL)
+ error->all(FLERR,"Cannot use r-RESPA with /omp styles");
+
+ int check_hybrid;
+ last_omp_style = NULL;
+ char *last_omp_name = NULL;
+
+// determine which is the last force style with OpenMP
+// support as this is the one that has to reduce the forces
+
+#define CheckStyleForOMP(name) \
+ check_hybrid = 0; \
+ if (force->name) { \
+ if ( (strcmp(force->name ## _style,"hybrid") == 0) || \
+ (strcmp(force->name ## _style,"hybrid/overlay") == 0) ) \
+ check_hybrid=1; \
+ int len = strlen(force->name ## _style); \
+ char *suffix = force->name ## _style + len - 4; \
+ if (strcmp(suffix,"/omp") == 0) { \
+ last_omp_name = force->name ## _style; \
+ last_omp_style = (void *) force->name; \
+ } \
+ }
+
+#define CheckHybridForOMP(name,Class) \
+ if (check_hybrid) { \
+ Class ## Hybrid *style = (Class ## Hybrid *) force->name; \
+ for (int i=0; i < style->nstyles; i++) { \
+ int len = strlen(style->keywords[i]); \
+ char *suffix = style->keywords[i] + len - 4; \
+ if (strcmp(suffix,"/omp") == 0) { \
+ last_omp_name = force->name ## _style; \
+ last_omp_style = (void *) force->name; \
+ } \
+ } \
+ }
+
+ CheckStyleForOMP(pair);
+ CheckHybridForOMP(pair,Pair);
+
+ CheckStyleForOMP(bond);
+ CheckHybridForOMP(bond,Bond);
+
+ CheckStyleForOMP(angle);
+ CheckHybridForOMP(angle,Angle);
+
+ CheckStyleForOMP(dihedral);
+ CheckHybridForOMP(dihedral,Dihedral);
+
+ CheckStyleForOMP(improper);
+ CheckHybridForOMP(improper,Improper);
+
+ CheckStyleForOMP(kspace);
+
+#undef CheckStyleForOMP
+#undef CheckHybridForOMP
+
+ set_neighbor_omp();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixOMP::set_neighbor_omp()
+{
+ // select or deselect multi-threaded neighbor
+ // list build depending on setting in package omp.
+ // NOTE: since we are at the top of the list of
+ // fixes, we cannot adjust neighbor lists from
+ // other fixes. those have to be re-implemented
+ // as /omp fix styles. :-(
+
+ const int neigh_omp = _neighbor ? 1 : 0;
+ const int nrequest = neighbor->nrequest;
+
+ for (int i = 0; i < nrequest; ++i)
+ neighbor->requests[i]->omp = neigh_omp;
+}
+
+/* ---------------------------------------------------------------------- */
+
+// adjust size and clear out per thread accumulator arrays
+void FixOMP::pre_force(int)
+{
+ const int nall = atom->nlocal + atom->nghost;
+
+ double **f = atom->f;
+ double **torque = atom->torque;
+ double *erforce = atom->erforce;
+ double *de = atom->de;
+ double *drho = atom->drho;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(f,torque,erforce,de,drho)
+#endif
+ {
+ const int tid = get_tid();
+ thr[tid]->check_tid(tid);
+ thr[tid]->init_force(nall,f,torque,erforce,de,drho);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double FixOMP::memory_usage()
+{
+ double bytes = comm->nthreads * (sizeof(ThrData *) + sizeof(ThrData));
+ bytes += comm->nthreads * thr[0]->memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/fix_omp.h b/src/USER-OMP/fix_omp.h
new file mode 100644
index 000000000..2167c281e
--- /dev/null
+++ b/src/USER-OMP/fix_omp.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(OMP,FixOMP)
+
+#else
+
+#ifndef LMP_FIX_OMP_H
+#define LMP_FIX_OMP_H
+
+#include "fix.h"
+
+
+namespace LAMMPS_NS {
+
+class ThrData;
+
+class FixOMP : public Fix {
+ friend class ThrOMP;
+
+ public:
+ FixOMP(class LAMMPS *, int, char **);
+ virtual ~FixOMP();
+ virtual int setmask();
+ virtual void init();
+ virtual void pre_force(int);
+
+ virtual void setup_pre_force(int vflag) { pre_force(vflag); };
+ virtual void min_setup_pre_force(int vflag) { pre_force(vflag); };
+ virtual void min_pre_force(int vflag) { pre_force(vflag); };
+ virtual void setup_pre_force_respa(int vflag,int) { pre_force(vflag); };
+ virtual void pre_force_respa(int vflag,int,int) { pre_force(vflag); };
+
+ virtual double memory_usage();
+
+ ThrData *get_thr(int tid) { return thr[tid]; };
+ int get_nthr() const { return _nthr; }
+
+ protected:
+ ThrData **thr;
+ void *last_omp_style; // pointer to the style that needs
+ // to do the force reduction
+
+ public:
+ bool get_neighbor() const {return _neighbor;};
+ bool get_newton() const {return _newton;};
+
+ private:
+ int _nthr; // number of currently active ThrData object
+ bool _neighbor; // en/disable threads for neighbor list construction
+ bool _newton; // en/disable newton's 3rd law for local atoms.
+
+ void set_neighbor_omp();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_peri_neigh_omp.cpp b/src/USER-OMP/fix_peri_neigh_omp.cpp
new file mode 100644
index 000000000..b8e07403a
--- /dev/null
+++ b/src/USER-OMP/fix_peri_neigh_omp.cpp
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------
+ 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: Mike Parks (SNL)
+------------------------------------------------------------------------- */
+
+#include "fix_peri_neigh_omp.h"
+#include "fix_omp.h"
+#include "modify.h"
+#include "neighbor.h"
+#include "neigh_request.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void FixPeriNeighOMP::init()
+{
+ if (!first) return;
+
+ // determine status of neighbor flag of the omp package command
+ int ifix = modify->find_fix("package_omp");
+ int use_omp = 0;
+ if (ifix >=0) {
+ FixOMP * fix = static_cast<FixOMP *>(lmp->modify->fix[ifix]);
+ if (fix->get_neighbor()) use_omp = 1;
+ }
+
+ // need a full neighbor list once
+
+ int irequest = neighbor->request((void *) this);
+ neighbor->requests[irequest]->pair = 0;
+ neighbor->requests[irequest]->fix = 1;
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->full = 1;
+ neighbor->requests[irequest]->omp = use_omp;
+ neighbor->requests[irequest]->occasional = 1;
+}
+
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/USER-OMP/fix_peri_neigh_omp.h
similarity index 68%
copy from src/GRANULAR/pair_gran_hooke.h
copy to src/USER-OMP/fix_peri_neigh_omp.h
index d5cff796f..11a383a2f 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/USER-OMP/fix_peri_neigh_omp.h
@@ -1,36 +1,38 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef FIX_CLASS
-PairStyle(gran/hooke,PairGranHooke)
+FixStyle(PERI_NEIGH_OMP,FixPeriNeighOMP)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_H
-#define LMP_PAIR_GRAN_HOOKE_H
+#ifndef LMP_FIX_PERI_NEIGH_OMP_H
+#define LMP_FIX_PERI_NEIGH_OMP_H
-#include "pair_gran_hooke_history.h"
+#include "fix_peri_neigh.h"
namespace LAMMPS_NS {
-class PairGranHooke : public PairGranHookeHistory {
+class FixPeriNeighOMP : public FixPeriNeigh {
+
public:
- PairGranHooke(class LAMMPS *);
- virtual void compute(int, int);
+ FixPeriNeighOMP(class LAMMPS *lmp, int narg, char **argv) :
+ FixPeriNeigh(lmp,narg,argv) {};
+ virtual void init();
};
}
#endif
#endif
diff --git a/src/USER-OMP/fix_qeq_comb_omp.cpp b/src/USER-OMP/fix_qeq_comb_omp.cpp
new file mode 100644
index 000000000..f0a477fef
--- /dev/null
+++ b/src/USER-OMP/fix_qeq_comb_omp.cpp
@@ -0,0 +1,160 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include <math.h>
+#include "fix_qeq_comb_omp.h"
+#include "atom.h"
+#include "force.h"
+#include "group.h"
+#include "memory.h"
+#include "error.h"
+#include "respa.h"
+#include "update.h"
+#include "pair_comb_omp.h"
+
+#include <string.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+FixQEQCombOMP::FixQEQCombOMP(LAMMPS *lmp, int narg, char **arg)
+ : FixQEQComb(lmp, narg, arg)
+{
+ if (narg < 5) error->all(FLERR,"Illegal fix qeq/comb/omp command");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixQEQCombOMP::init()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Fix qeq/comb/omp requires atom attribute q");
+
+ comb = (PairComb *) force->pair_match("comb/omp",1);
+ if (comb == NULL)
+ comb = (PairComb *) force->pair_match("comb",1);
+ if (comb == NULL) error->all(FLERR,"Must use pair_style comb or comb/omp with fix qeq/comb");
+
+ if (strstr(update->integrate_style,"respa"))
+ nlevels_respa = ((Respa *) update->integrate)->nlevels;
+
+ ngroup = group->count(igroup);
+ if (ngroup == 0) error->all(FLERR,"Fix qeq/comb group has no atoms");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixQEQCombOMP::post_force(int vflag)
+{
+ int i,iloop,loopmax;
+ double heatpq,qmass,dtq,dtq2;
+ double enegchkall,enegmaxall;
+
+ if (update->ntimestep % nevery) return;
+
+ // reallocate work arrays if necessary
+ // qf = charge force
+ // q1 = charge displacement
+ // q2 = tmp storage of charge force for next iteration
+
+ if (atom->nmax > nmax) {
+ memory->destroy(qf);
+ memory->destroy(q1);
+ memory->destroy(q2);
+ nmax = atom->nmax;
+ memory->create(qf,nmax,"qeq:qf");
+ memory->create(q1,nmax,"qeq:q1");
+ memory->create(q2,nmax,"qeq:q2");
+ vector_atom = qf;
+ }
+
+ // more loops for first-time charge equilibrium
+
+ iloop = 0;
+ if (firstflag) loopmax = 5000;
+ else loopmax = 2000;
+
+ // charge-equilibration loop
+
+ if (me == 0 && fp)
+ fprintf(fp,"Charge equilibration on step " BIGINT_FORMAT "\n",
+ update->ntimestep);
+
+ heatpq = 0.05;
+ qmass = 0.000548580;
+ dtq = 0.0006;
+ dtq2 = 0.5*dtq*dtq/qmass;
+
+ double enegchk = 0.0;
+ double enegtot = 0.0;
+ double enegmax = 0.0;
+
+ double *q = atom->q;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (i = 0; i < nlocal; i++)
+ q1[i] = q2[i] = qf[i] = 0.0;
+
+ for (iloop = 0; iloop < loopmax; iloop ++ ) {
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ q1[i] += qf[i]*dtq2 - heatpq*q1[i];
+ q[i] += q1[i];
+ }
+
+ enegtot = comb->yasu_char(qf,igroup);
+ enegtot /= ngroup;
+ enegchk = enegmax = 0.0;
+
+ for (i = 0; i < nlocal ; i++)
+ if (mask[i] & groupbit) {
+ q2[i] = enegtot-qf[i];
+ enegmax = MAX(enegmax,fabs(q2[i]));
+ enegchk += fabs(q2[i]);
+ qf[i] = q2[i];
+ }
+
+ MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world);
+ enegchk = enegchkall/ngroup;
+ MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world);
+ enegmax = enegmaxall;
+
+ if (enegchk <= precision && enegmax <= 100.0*precision) break;
+
+ if (me == 0 && fp)
+ fprintf(fp," iteration: %d, enegtot %.6g, "
+ "enegmax %.6g, fq deviation: %.6g\n",
+ iloop,enegtot,enegmax,enegchk);
+
+ for (i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit)
+ q1[i] += qf[i]*dtq2 - heatpq*q1[i];
+ }
+
+ if (me == 0 && fp) {
+ if (iloop == loopmax)
+ fprintf(fp,"Charges did not converge in %d iterations\n",iloop);
+ else
+ fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n",
+ iloop,enegchk);
+ }
+}
+
diff --git a/src/USER-OMP/fix_qeq_comb_omp.h b/src/USER-OMP/fix_qeq_comb_omp.h
new file mode 100644
index 000000000..0febe6b0a
--- /dev/null
+++ b/src/USER-OMP/fix_qeq_comb_omp.h
@@ -0,0 +1,32 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(qeq/comb/omp,FixQEQCombOMP)
+
+#else
+
+#ifndef LMP_FIX_QEQ_COMB_OMP_H
+#define LMP_FIX_QEQ_COMB_OMP_H
+
+#include "fix_qeq_comb.h"
+
+namespace LAMMPS_NS {
+
+class FixQEQCombOMP : public FixQEQComb {
+ public:
+ FixQEQCombOMP(class LAMMPS *, int, char **);
+ virtual void init();
+ virtual void post_force(int);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/fix_shear_history_omp.cpp b/src/USER-OMP/fix_shear_history_omp.cpp
index 40781cb40..4655dd1af 100644
--- a/src/USER-OMP/fix_shear_history_omp.cpp
+++ b/src/USER-OMP/fix_shear_history_omp.cpp
@@ -1,150 +1,150 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "string.h"
#include "stdio.h"
#include "fix_shear_history_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "force.h"
#include "pair.h"
#include "update.h"
#include "modify.h"
#include "error.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
using namespace LAMMPS_NS;
#define MAXTOUCH 15
/* ----------------------------------------------------------------------
copy shear partner info from neighbor lists to atom arrays
so can be exchanged with atoms
------------------------------------------------------------------------- */
void FixShearHistoryOMP::pre_exchange()
{
const int nlocal = atom->nlocal;
const int nghost = atom->nghost;
const int nall = nlocal + nghost;
const int nthreads = comm->nthreads;
int flag = 0;
#if defined(_OPENMP)
-#pragma omp parallel shared(flag)
+#pragma omp parallel default(none) shared(flag)
#endif
{
#if defined(_OPENMP)
const int tid = omp_get_thread_num();
#else
const int tid = 0;
#endif
// each thread works on a fixed chunk of local and ghost atoms.
const int ldelta = 1 + nlocal/nthreads;
const int lfrom = tid*ldelta;
const int lmax = lfrom +ldelta;
const int lto = (lmax > nlocal) ? nlocal : lmax;
const int gdelta = 1 + nghost/nthreads;
const int gfrom = nlocal + tid*gdelta;
const int gmax = gfrom + gdelta;
const int gto = (gmax > nall) ? nall : gmax;
int i,j,ii,jj,m,inum,jnum;
int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch;
double *shear,*allshear,**firstshear;
// zero npartners for all current atoms
for (i = lfrom; i < lto; i++) npartner[i] = 0;
// copy shear info from neighbor list atoms to atom arrays
int *tag = atom->tag;
NeighList *list = pair->list;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
firsttouch = list->listgranhistory->firstneigh;
firstshear = list->listgranhistory->firstdouble;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
jlist = firstneigh[i];
allshear = firstshear[i];
jnum = numneigh[i];
touch = firsttouch[i];
for (jj = 0; jj < jnum; jj++) {
if (touch[jj]) {
j = jlist[jj];
j &= NEIGHMASK;
shear = &allshear[3*jj];
if ((i >= lfrom) && (i < lto)) {
if (npartner[i] < MAXTOUCH) {
m = npartner[i];
partner[i][m] = tag[j];
shearpartner[i][m][0] = shear[0];
shearpartner[i][m][1] = shear[1];
shearpartner[i][m][2] = shear[2];
}
npartner[i]++;
}
if ((j >= lfrom) && (j < lto)) {
if (npartner[j] < MAXTOUCH) {
m = npartner[j];
partner[j][m] = tag[i];
shearpartner[j][m][0] = -shear[0];
shearpartner[j][m][1] = -shear[1];
shearpartner[j][m][2] = -shear[2];
}
npartner[j]++;
}
if ((j >= gfrom) && (j < gto)) {
npartner[j]++;
}
}
}
}
// test for too many touching neighbors
int myflag = 0;
for (i = lfrom; i < lto; i++)
if (npartner[i] >= MAXTOUCH) myflag = 1;
if (myflag)
#if defined(_OPENMP)
#pragma omp atomic
#endif
++flag;
}
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all) error->all(FLERR,"Too many touching neighbors - boost MAXTOUCH");
}
diff --git a/src/USER-OMP/fix_wall_gran_omp.cpp b/src/USER-OMP/fix_wall_gran_omp.cpp
new file mode 100644
index 000000000..5857c921a
--- /dev/null
+++ b/src/USER-OMP/fix_wall_gran_omp.cpp
@@ -0,0 +1,152 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "fix_wall_gran_omp.h"
+#include "atom.h"
+#include "update.h"
+
+using namespace LAMMPS_NS;
+
+
+enum{XPLANE,YPLANE,ZPLANE,ZCYLINDER}; // XYZ PLANE need to be 0,1,2
+enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY};
+
+#define BIG 1.0e20
+
+/* ---------------------------------------------------------------------- */
+
+FixWallGranOMP::FixWallGranOMP(LAMMPS *lmp, int narg, char **arg) :
+ FixWallGran(lmp, narg, arg) { }
+
+/* ---------------------------------------------------------------------- */
+
+void FixWallGranOMP::post_force(int vflag)
+{
+ double vwall[3];
+
+ // set position of wall to initial settings and velocity to 0.0
+ // if wiggle or shear, set wall position and velocity accordingly
+
+ double wlo = lo;
+ double whi = hi;
+ vwall[0] = vwall[1] = vwall[2] = 0.0;
+ if (wiggle) {
+ double arg = omega * (update->ntimestep - time_origin) * dt;
+ if (wallstyle == axis) {
+ wlo = lo + amplitude - amplitude*cos(arg);
+ whi = hi + amplitude - amplitude*cos(arg);
+ }
+ vwall[axis] = amplitude*omega*sin(arg);
+ } else if (wshear) vwall[axis] = vshear;
+
+ // loop over all my atoms
+ // rsq = distance from wall
+ // dx,dy,dz = signed distance from wall
+ // for rotating cylinder, reset vwall based on particle position
+ // skip atom if not close enough to wall
+ // if wall was set to NULL, it's skipped since lo/hi are infinity
+ // compute force and torque on atom if close enough to wall
+ // via wall potential matched to pair potential
+ // set shear if pair potential stores history
+
+ double * const * const x = atom->x;
+ double * const * const v = atom->v;
+ double * const * const f = atom->f;
+ double * const * const omega = atom->omega;
+ double * const * const torque = atom->torque;
+ double * const radius = atom->radius;
+ double * const rmass = atom->rmass;
+ const int * const mask = atom->mask;
+ const int nlocal = atom->nlocal;
+
+ if (update->ntimestep > laststep) shearupdate = 1;
+ else shearupdate = 0;
+
+ int i;
+#if defined(_OPENMP)
+#pragma omp parallel for private(i) default(none) firstprivate(vwall,wlo,whi)
+#endif
+ for (i = 0; i < nlocal; i++) {
+
+ if (mask[i] & groupbit) {
+ double dx,dy,dz,del1,del2,delxy,delr,rsq;
+
+ dx = dy = dz = 0.0;
+
+ if (wallstyle == XPLANE) {
+ del1 = x[i][0] - wlo;
+ del2 = whi - x[i][0];
+ if (del1 < del2) dx = del1;
+ else dx = -del2;
+ } else if (wallstyle == YPLANE) {
+ del1 = x[i][1] - wlo;
+ del2 = whi - x[i][1];
+ if (del1 < del2) dy = del1;
+ else dy = -del2;
+ } else if (wallstyle == ZPLANE) {
+ del1 = x[i][2] - wlo;
+ del2 = whi - x[i][2];
+ if (del1 < del2) dz = del1;
+ else dz = -del2;
+ } else if (wallstyle == ZCYLINDER) {
+ delxy = sqrt(x[i][0]*x[i][0] + x[i][1]*x[i][1]);
+ delr = cylradius - delxy;
+ if (delr > radius[i]) dz = cylradius;
+ else {
+ dx = -delr/delxy * x[i][0];
+ dy = -delr/delxy * x[i][1];
+ if (wshear && axis != 2) {
+ vwall[0] = vshear * x[i][1]/delxy;
+ vwall[1] = -vshear * x[i][0]/delxy;
+ vwall[2] = 0.0;
+ }
+ }
+ }
+
+ rsq = dx*dx + dy*dy + dz*dz;
+
+ if (rsq > radius[i]*radius[i]) {
+ if (pairstyle != HOOKE) {
+ shear[i][0] = 0.0;
+ shear[i][1] = 0.0;
+ shear[i][2] = 0.0;
+ }
+ } else {
+ if (pairstyle == HOOKE)
+ hooke(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i],
+ radius[i],rmass[i]);
+ else if (pairstyle == HOOKE_HISTORY)
+ hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i],
+ radius[i],rmass[i],shear[i]);
+ else if (pairstyle == HERTZ_HISTORY)
+ hertz_history(rsq,dx,dy,dz,vwall,v[i],f[i],omega[i],torque[i],
+ radius[i],rmass[i],shear[i]);
+ }
+ }
+ }
+
+ laststep = update->ntimestep;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixWallGranOMP::post_force_respa(int vflag, int ilevel, int iloop)
+{
+ if (ilevel == nlevels_respa-1) post_force(vflag);
+}
+
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/USER-OMP/fix_wall_gran_omp.h
similarity index 62%
copy from src/GRANULAR/pair_gran_hooke.h
copy to src/USER-OMP/fix_wall_gran_omp.h
index d5cff796f..cfdfb9c75 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/USER-OMP/fix_wall_gran_omp.h
@@ -1,36 +1,38 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef FIX_CLASS
-PairStyle(gran/hooke,PairGranHooke)
+FixStyle(wall/gran/omp,FixWallGranOMP)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_H
-#define LMP_PAIR_GRAN_HOOKE_H
+#ifndef LMP_FIX_WALL_GRAN_OMP_H
+#define LMP_FIX_WALL_GRAN_OMP_H
-#include "pair_gran_hooke_history.h"
+#include "fix_wall_gran.h"
namespace LAMMPS_NS {
-class PairGranHooke : public PairGranHookeHistory {
+class FixWallGranOMP : public FixWallGran {
+
public:
- PairGranHooke(class LAMMPS *);
- virtual void compute(int, int);
+ FixWallGranOMP(class LAMMPS *, int, char **);
+ virtual void post_force(int);
+ virtual void post_force_respa(int, int, int);
};
}
#endif
#endif
diff --git a/src/USER-OMP/hack_openmp_for_pgi.sh b/src/USER-OMP/hack_openmp_for_pgi.sh
new file mode 100644
index 000000000..a076fd1fc
--- /dev/null
+++ b/src/USER-OMP/hack_openmp_for_pgi.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+for f in *.h *.cpp
+do \
+ sed -e '/#pragma omp/s/^\(.*default\)(none)\(.*\)$/\1(shared)\2/' \
+ -e '/#pragma omp/s/shared([a-z0-9,_]\+)//' \
+ -i.bak $f
+done
diff --git a/src/USER-OMP/improper_class2_omp.cpp b/src/USER-OMP/improper_class2_omp.cpp
new file mode 100644
index 000000000..cfadde435
--- /dev/null
+++ b/src/USER-OMP/improper_class2_omp.cpp
@@ -0,0 +1,697 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "improper_class2_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void ImproperClass2OMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nimproperlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <const int EVFLAG, const int EFLAG, const int NEWTON_BOND>
+void ImproperClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,i4,i,j,k,n,type;
+ double eimproper;
+ double delr[3][3],rmag[3],rinvmag[3],rmag2[3];
+ double theta[3],costheta[3],sintheta[3];
+ double cossqtheta[3],sinsqtheta[3],invstheta[3];
+ double rABxrCB[3],rDBxrAB[3],rCBxrDB[3];
+ double ddelr[3][4],dr[3][4][3],dinvr[3][4][3];
+ double dthetadr[3][4][3],dinvsth[3][4][3];
+ double dinv3r[4][3],dinvs3r[3][4][3];
+ double drCBxrDB[3],rCBxdrDB[3],drDBxrAB[3],rDBxdrAB[3];
+ double drABxrCB[3],rABxdrCB[3];
+ double dot1,dot2,dd[3];
+ double fdot[3][4][3],ftmp,invs3r[3],inv3r;
+ double t,tt1,tt3,sc1;
+ double dotCBDBAB,dotDBABCB,dotABCBDB;
+ double chi,deltachi,d2chi,cossin2;
+ double drAB[3][4][3],drCB[3][4][3],drDB[3][4][3];
+ double dchi[3][4][3],dtotalchi[4][3];
+ double schiABCD,chiABCD,schiCBDA,chiCBDA,schiDBAC,chiDBAC;
+ double fabcd[4][3];
+
+ eimproper = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const improperlist = neighbor->improperlist;
+ const int nlocal = atom->nlocal;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++) {
+ dthetadr[i][j][k] = 0.0;
+ drAB[i][j][k] = 0.0;
+ drCB[i][j][k] = 0.0;
+ drDB[i][j][k] = 0.0;
+ }
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = improperlist[n][0];
+ i2 = improperlist[n][1];
+ i3 = improperlist[n][2];
+ i4 = improperlist[n][3];
+ type = improperlist[n][4];
+
+ if (k0[type] == 0.0) continue;
+
+ // difference vectors
+
+ delr[0][0] = x[i1][0] - x[i2][0];
+ delr[0][1] = x[i1][1] - x[i2][1];
+ delr[0][2] = x[i1][2] - x[i2][2];
+ domain->minimum_image(delr[0]);
+
+ delr[1][0] = x[i3][0] - x[i2][0];
+ delr[1][1] = x[i3][1] - x[i2][1];
+ delr[1][2] = x[i3][2] - x[i2][2];
+ domain->minimum_image(delr[1]);
+
+ delr[2][0] = x[i4][0] - x[i2][0];
+ delr[2][1] = x[i4][1] - x[i2][1];
+ delr[2][2] = x[i4][2] - x[i2][2];
+ domain->minimum_image(delr[2]);
+
+ // bond lengths and associated values
+
+ for (i = 0; i < 3; i++) {
+ rmag2[i] = delr[i][0]*delr[i][0] + delr[i][1]*delr[i][1] +
+ delr[i][2]*delr[i][2];
+ rmag[i] = sqrt(rmag2[i]);
+ rinvmag[i] = 1.0/rmag[i];
+ }
+
+ // angle ABC, CBD, ABD
+
+ costheta[0] = (delr[0][0]*delr[1][0] + delr[0][1]*delr[1][1] +
+ delr[0][2]*delr[1][2]) / (rmag[0]*rmag[1]);
+ costheta[1] = (delr[1][0]*delr[2][0] + delr[1][1]*delr[2][1] +
+ delr[1][2]*delr[2][2]) / (rmag[1]*rmag[2]);
+ costheta[2] = (delr[0][0]*delr[2][0] + delr[0][1]*delr[2][1] +
+ delr[0][2]*delr[2][2]) / (rmag[0]*rmag[2]);
+
+ // angle error check
+
+ for (i = 0; i < 3; i++) {
+ if (costheta[i] == -1.0) {
+ int me = comm->me;
+ if (screen) {
+ char str[128];
+ sprintf(str,
+ "Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me, thr->get_tid(),update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ fprintf(screen," 1st atom: %d %g %g %g\n",
+ me,x[i1][0],x[i1][1],x[i1][2]);
+ fprintf(screen," 2nd atom: %d %g %g %g\n",
+ me,x[i2][0],x[i2][1],x[i2][2]);
+ fprintf(screen," 3rd atom: %d %g %g %g\n",
+ me,x[i3][0],x[i3][1],x[i3][2]);
+ fprintf(screen," 4th atom: %d %g %g %g\n",
+ me,x[i4][0],x[i4][1],x[i4][2]);
+ }
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (costheta[i] > 1.0) costheta[i] = 1.0;
+ if (costheta[i] < -1.0) costheta[i] = -1.0;
+ theta[i] = acos(costheta[i]);
+ cossqtheta[i] = costheta[i]*costheta[i];
+ sintheta[i] = sin(theta[i]);
+ invstheta[i] = 1.0/sintheta[i];
+ sinsqtheta[i] = sintheta[i]*sintheta[i];
+ }
+
+ // cross & dot products
+
+ cross(delr[0],delr[1],rABxrCB);
+ cross(delr[2],delr[0],rDBxrAB);
+ cross(delr[1],delr[2],rCBxrDB);
+
+ dotCBDBAB = dot(rCBxrDB,delr[0]);
+ dotDBABCB = dot(rDBxrAB,delr[1]);
+ dotABCBDB = dot(rABxrCB,delr[2]);
+
+ t = rmag[0] * rmag[1] * rmag[2];
+ inv3r = 1.0/t;
+ invs3r[0] = invstheta[1] * inv3r;
+ invs3r[1] = invstheta[2] * inv3r;
+ invs3r[2] = invstheta[0] * inv3r;
+
+ // chi ABCD, CBDA, DBAC
+ // final chi is average of three
+
+ schiABCD = dotCBDBAB * invs3r[0];
+ chiABCD = asin(schiABCD);
+ schiCBDA = dotDBABCB * invs3r[1];
+ chiCBDA = asin(schiCBDA);
+ schiDBAC = dotABCBDB * invs3r[2];
+ chiDBAC = asin(schiDBAC);
+
+ chi = (chiABCD + chiCBDA + chiDBAC) / 3.0;
+ deltachi = chi - chi0[type];
+ d2chi = deltachi * deltachi;
+
+ // energy
+
+ if (EFLAG) eimproper = k0[type]*d2chi;
+
+ // forces
+ // define d(delr)
+ // i = bond AB/CB/DB, j = atom A/B/C/D
+
+ ddelr[0][0] = 1.0;
+ ddelr[0][1] = -1.0;
+ ddelr[0][2] = 0.0;
+ ddelr[0][3] = 0.0;
+ ddelr[1][0] = 0.0;
+ ddelr[1][1] = -1.0;
+ ddelr[1][2] = 1.0;
+ ddelr[1][3] = 0.0;
+ ddelr[2][0] = 0.0;
+ ddelr[2][1] = -1.0;
+ ddelr[2][2] = 0.0;
+ ddelr[2][3] = 1.0;
+
+ // compute d(|r|)/dr and d(1/|r|)/dr for each direction, bond and atom
+ // define d(r) for each r
+ // i = bond AB/CB/DB, j = atom A/B/C/D, k = X/Y/Z
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++) {
+ dr[i][j][k] = delr[i][k] * ddelr[i][j] / rmag[i];
+ dinvr[i][j][k] = -dr[i][j][k] / rmag2[i];
+ }
+
+ // compute d(1 / (|r_AB| * |r_CB| * |r_DB|) / dr
+ // i = atom A/B/C/D, j = X/Y/Z
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ dinv3r[i][j] = rinvmag[1] * (rinvmag[2] * dinvr[0][i][j] +
+ rinvmag[0] * dinvr[2][i][j]) +
+ rinvmag[2] * rinvmag[0] * dinvr[1][i][j];
+
+ // compute d(theta)/d(r) for 3 angles
+ // angleABC
+
+ tt1 = costheta[0] / rmag2[0];
+ tt3 = costheta[0] / rmag2[1];
+ sc1 = 1.0 / sqrt(1.0 - cossqtheta[0]);
+
+ dthetadr[0][0][0] = sc1 * ((tt1 * delr[0][0]) -
+ (delr[1][0] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][0][1] = sc1 * ((tt1 * delr[0][1]) -
+ (delr[1][1] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][0][2] = sc1 * ((tt1 * delr[0][2]) -
+ (delr[1][2] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][1][0] = -sc1 * ((tt1 * delr[0][0]) -
+ (delr[1][0] * rinvmag[0] * rinvmag[1]) +
+ (tt3 * delr[1][0]) -
+ (delr[0][0] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][1][1] = -sc1 * ((tt1 * delr[0][1]) -
+ (delr[1][1] * rinvmag[0] * rinvmag[1]) +
+ (tt3 * delr[1][1]) -
+ (delr[0][1] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][1][2] = -sc1 * ((tt1 * delr[0][2]) -
+ (delr[1][2] * rinvmag[0] * rinvmag[1]) +
+ (tt3 * delr[1][2]) -
+ (delr[0][2] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][2][0] = sc1 * ((tt3 * delr[1][0]) -
+ (delr[0][0] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][2][1] = sc1 * ((tt3 * delr[1][1]) -
+ (delr[0][1] * rinvmag[0] * rinvmag[1]));
+ dthetadr[0][2][2] = sc1 * ((tt3 * delr[1][2]) -
+ (delr[0][2] * rinvmag[0] * rinvmag[1]));
+
+ // angleCBD
+
+ tt1 = costheta[1] / rmag2[1];
+ tt3 = costheta[1] / rmag2[2];
+ sc1 = 1.0 / sqrt(1.0 - cossqtheta[1]);
+
+ dthetadr[1][2][0] = sc1 * ((tt1 * delr[1][0]) -
+ (delr[2][0] * rinvmag[1] * rinvmag[2]));
+ dthetadr[1][2][1] = sc1 * ((tt1 * delr[1][1]) -
+ (delr[2][1] * rinvmag[1] * rinvmag[2]));
+ dthetadr[1][2][2] = sc1 * ((tt1 * delr[1][2]) -
+ (delr[2][2] * rinvmag[1] * rinvmag[2]));
+ dthetadr[1][1][0] = -sc1 * ((tt1 * delr[1][0]) -
+ (delr[2][0] * rinvmag[1] * rinvmag[2]) +
+ (tt3 * delr[2][0]) -
+ (delr[1][0] * rinvmag[2] * rinvmag[1]));
+ dthetadr[1][1][1] = -sc1 * ((tt1 * delr[1][1]) -
+ (delr[2][1] * rinvmag[1] * rinvmag[2]) +
+ (tt3 * delr[2][1]) -
+ (delr[1][1] * rinvmag[2] * rinvmag[1]));
+ dthetadr[1][1][2] = -sc1 * ((tt1 * delr[1][2]) -
+ (delr[2][2] * rinvmag[1] * rinvmag[2]) +
+ (tt3 * delr[2][2]) -
+ (delr[1][2] * rinvmag[2] * rinvmag[1]));
+ dthetadr[1][3][0] = sc1 * ((tt3 * delr[2][0]) -
+ (delr[1][0] * rinvmag[2] * rinvmag[1]));
+ dthetadr[1][3][1] = sc1 * ((tt3 * delr[2][1]) -
+ (delr[1][1] * rinvmag[2] * rinvmag[1]));
+ dthetadr[1][3][2] = sc1 * ((tt3 * delr[2][2]) -
+ (delr[1][2] * rinvmag[2] * rinvmag[1]));
+
+ // angleABD
+
+ tt1 = costheta[2] / rmag2[0];
+ tt3 = costheta[2] / rmag2[2];
+ sc1 = 1.0 / sqrt(1.0 - cossqtheta[2]);
+
+ dthetadr[2][0][0] = sc1 * ((tt1 * delr[0][0]) -
+ (delr[2][0] * rinvmag[0] * rinvmag[2]));
+ dthetadr[2][0][1] = sc1 * ((tt1 * delr[0][1]) -
+ (delr[2][1] * rinvmag[0] * rinvmag[2]));
+ dthetadr[2][0][2] = sc1 * ((tt1 * delr[0][2]) -
+ (delr[2][2] * rinvmag[0] * rinvmag[2]));
+ dthetadr[2][1][0] = -sc1 * ((tt1 * delr[0][0]) -
+ (delr[2][0] * rinvmag[0] * rinvmag[2]) +
+ (tt3 * delr[2][0]) -
+ (delr[0][0] * rinvmag[2] * rinvmag[0]));
+ dthetadr[2][1][1] = -sc1 * ((tt1 * delr[0][1]) -
+ (delr[2][1] * rinvmag[0] * rinvmag[2]) +
+ (tt3 * delr[2][1]) -
+ (delr[0][1] * rinvmag[2] * rinvmag[0]));
+ dthetadr[2][1][2] = -sc1 * ((tt1 * delr[0][2]) -
+ (delr[2][2] * rinvmag[0] * rinvmag[2]) +
+ (tt3 * delr[2][2]) -
+ (delr[0][2] * rinvmag[2] * rinvmag[0]));
+ dthetadr[2][3][0] = sc1 * ((tt3 * delr[2][0]) -
+ (delr[0][0] * rinvmag[2] * rinvmag[0]));
+ dthetadr[2][3][1] = sc1 * ((tt3 * delr[2][1]) -
+ (delr[0][1] * rinvmag[2] * rinvmag[0]));
+ dthetadr[2][3][2] = sc1 * ((tt3 * delr[2][2]) -
+ (delr[0][2] * rinvmag[2] * rinvmag[0]));
+
+ // compute d( 1 / sin(theta))/dr
+ // i = angle, j = atom, k = direction
+
+ for (i = 0; i < 3; i++) {
+ cossin2 = -costheta[i] / sinsqtheta[i];
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++)
+ dinvsth[i][j][k] = cossin2 * dthetadr[i][j][k];
+ }
+
+ // compute d(1 / sin(theta) * |r_AB| * |r_CB| * |r_DB|)/dr
+ // i = angle, j = atom
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++) {
+ dinvs3r[0][i][j] = (invstheta[1] * dinv3r[i][j]) +
+ (inv3r * dinvsth[1][i][j]);
+ dinvs3r[1][i][j] = (invstheta[2] * dinv3r[i][j]) +
+ (inv3r * dinvsth[2][i][j]);
+ dinvs3r[2][i][j] = (invstheta[0] * dinv3r[i][j]) +
+ (inv3r * dinvsth[0][i][j]);
+ }
+
+ // drCB(i,j,k), etc
+ // i = vector X'/Y'/Z', j = atom A/B/C/D, k = direction X/Y/Z
+
+ for (i = 0; i < 3; i++) {
+ drCB[i][1][i] = -1.0;
+ drAB[i][1][i] = -1.0;
+ drDB[i][1][i] = -1.0;
+ drDB[i][3][i] = 1.0;
+ drCB[i][2][i] = 1.0;
+ drAB[i][0][i] = 1.0;
+ }
+
+ // d((r_CB x r_DB) dot r_AB)
+ // r_CB x d(r_DB)
+ // d(r_CB) x r_DB
+ // (r_CB x d(r_DB)) + (d(r_CB) x r_DB)
+ // (r_CB x d(r_DB)) + (d(r_CB) x r_DB) dot r_AB
+ // d(r_AB) dot (r_CB x r_DB)
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++) {
+ cross(delr[1],drDB[i][j],rCBxdrDB);
+ cross(drCB[i][j],delr[2],drCBxrDB);
+ for (k = 0; k < 3; k++) dd[k] = rCBxdrDB[k] + drCBxrDB[k];
+ dot1 = dot(dd,delr[0]);
+ dot2 = dot(rCBxrDB,drAB[i][j]);
+ fdot[0][j][i] = dot1 + dot2;
+ }
+
+ // d((r_DB x r_AB) dot r_CB)
+ // r_DB x d(r_AB)
+ // d(r_DB) x r_AB
+ // (r_DB x d(r_AB)) + (d(r_DB) x r_AB)
+ // (r_DB x d(r_AB)) + (d(r_DB) x r_AB) dot r_CB
+ // d(r_CB) dot (r_DB x r_AB)
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++) {
+ cross(delr[2],drAB[i][j],rDBxdrAB);
+ cross(drDB[i][j],delr[0],drDBxrAB);
+ for (k = 0; k < 3; k++) dd[k] = rDBxdrAB[k] + drDBxrAB[k];
+ dot1 = dot(dd,delr[1]);
+ dot2 = dot(rDBxrAB,drCB[i][j]);
+ fdot[1][j][i] = dot1 + dot2;
+ }
+
+ // d((r_AB x r_CB) dot r_DB)
+ // r_AB x d(r_CB)
+ // d(r_AB) x r_CB
+ // (r_AB x d(r_CB)) + (d(r_AB) x r_CB)
+ // (r_AB x d(r_CB)) + (d(r_AB) x r_CB) dot r_DB
+ // d(r_DB) dot (r_AB x r_CB)
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++) {
+ cross(delr[0],drCB[i][j],rABxdrCB);
+ cross(drAB[i][j],delr[1],drABxrCB);
+ for (k = 0; k < 3; k++) dd[k] = rABxdrCB[k] + drABxrCB[k];
+ dot1 = dot(dd,delr[2]);
+ dot2 = dot(rABxrCB,drDB[i][j]);
+ fdot[2][j][i] = dot1 + dot2;
+ }
+
+ // force on each atom
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++) {
+ ftmp = (fdot[0][i][j] * invs3r[0]) +
+ (dinvs3r[0][i][j] * dotCBDBAB);
+ dchi[0][i][j] = ftmp / cos(chiABCD);
+ ftmp = (fdot[1][i][j] * invs3r[1]) +
+ (dinvs3r[1][i][j] * dotDBABCB);
+ dchi[1][i][j] = ftmp / cos(chiCBDA);
+ ftmp = (fdot[2][i][j] * invs3r[2]) +
+ (dinvs3r[2][i][j] * dotABCBDB);
+ dchi[2][i][j] = ftmp / cos(chiDBAC);
+ dtotalchi[i][j] = (dchi[0][i][j]+dchi[1][i][j]+dchi[2][i][j]) / 3.0;
+ }
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] = -2.0*k0[type] * deltachi*dtotalchi[i][j];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += fabcd[0][0];
+ f[i1][1] += fabcd[0][1];
+ f[i1][2] += fabcd[0][2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += fabcd[1][0];
+ f[i2][1] += fabcd[1][1];
+ f[i2][2] += fabcd[1][2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += fabcd[2][0];
+ f[i3][1] += fabcd[2][1];
+ f[i3][2] += fabcd[2][2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += fabcd[3][0];
+ f[i4][1] += fabcd[3][1];
+ f[i4][2] += fabcd[3][2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,
+ fabcd[0],fabcd[2],fabcd[3],
+ delr[0][0],delr[0][1],delr[0][2],
+ delr[1][0],delr[1][1],delr[1][2],
+ delr[2][0]-delr[1][0],delr[2][1]-delr[1][1],
+ delr[2][2]-delr[1][2],thr);
+ }
+
+ // compute angle-angle interactions
+ angleangle_thr<EVFLAG, EFLAG, NEWTON_BOND>(nfrom,nto,thr);
+}
+
+/* ----------------------------------------------------------------------
+ angle-angle interactions within improper
+------------------------------------------------------------------------- */
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void ImproperClass2OMP::angleangle_thr(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,i4,i,j,k,n,type;
+ double eimproper;
+ double delxAB,delyAB,delzAB,rABmag2,rAB;
+ double delxBC,delyBC,delzBC,rBCmag2,rBC;
+ double delxBD,delyBD,delzBD,rBDmag2,rBD;
+ double costhABC,thetaABC,costhABD;
+ double thetaABD,costhCBD,thetaCBD,dthABC,dthCBD,dthABD;
+ double sc1,t1,t3,r12;
+ double dthetadr[3][4][3],fabcd[4][3];
+
+ eimproper = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const improperlist = neighbor->improperlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = improperlist[n][0];
+ i2 = improperlist[n][1];
+ i3 = improperlist[n][2];
+ i4 = improperlist[n][3];
+ type = improperlist[n][4];
+
+ // difference vectors
+
+ delxAB = x[i1][0] - x[i2][0];
+ delyAB = x[i1][1] - x[i2][1];
+ delzAB = x[i1][2] - x[i2][2];
+ domain->minimum_image(delxAB,delyAB,delzAB);
+
+ delxBC = x[i3][0] - x[i2][0];
+ delyBC = x[i3][1] - x[i2][1];
+ delzBC = x[i3][2] - x[i2][2];
+ domain->minimum_image(delxBC,delyBC,delzBC);
+
+ delxBD = x[i4][0] - x[i2][0];
+ delyBD = x[i4][1] - x[i2][1];
+ delzBD = x[i4][2] - x[i2][2];
+ domain->minimum_image(delxBD,delyBD,delzBD);
+
+ // bond lengths
+
+ rABmag2 = delxAB*delxAB + delyAB*delyAB + delzAB*delzAB;
+ rAB = sqrt(rABmag2);
+ rBCmag2 = delxBC*delxBC + delyBC*delyBC + delzBC*delzBC;
+ rBC = sqrt(rBCmag2);
+ rBDmag2 = delxBD*delxBD + delyBD*delyBD + delzBD*delzBD;
+ rBD = sqrt(rBDmag2);
+
+ // angle ABC, ABD, CBD
+
+ costhABC = (delxAB*delxBC + delyAB*delyBC + delzAB*delzBC) / (rAB * rBC);
+ if (costhABC > 1.0) costhABC = 1.0;
+ if (costhABC < -1.0) costhABC = -1.0;
+ thetaABC = acos(costhABC);
+
+ costhABD = (delxAB*delxBD + delyAB*delyBD + delzAB*delzBD) / (rAB * rBD);
+ if (costhABD > 1.0) costhABD = 1.0;
+ if (costhABD < -1.0) costhABD = -1.0;
+ thetaABD = acos(costhABD);
+
+ costhCBD = (delxBC*delxBD + delyBC*delyBD + delzBC*delzBD) /(rBC * rBD);
+ if (costhCBD > 1.0) costhCBD = 1.0;
+ if (costhCBD < -1.0) costhCBD = -1.0;
+ thetaCBD = acos(costhCBD);
+
+ dthABC = thetaABC - aa_theta0_1[type];
+ dthABD = thetaABD - aa_theta0_2[type];
+ dthCBD = thetaCBD - aa_theta0_3[type];
+
+ // energy
+
+ if (EFLAG) eimproper = aa_k2[type] * dthABC * dthABD +
+ aa_k1[type] * dthABC * dthCBD +
+ aa_k3[type] * dthABD * dthCBD;
+
+ // d(theta)/d(r) array
+ // angle i, atom j, coordinate k
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++)
+ dthetadr[i][j][k] = 0.0;
+
+ // angle ABC
+
+ sc1 = sqrt(1.0/(1.0 - costhABC*costhABC));
+ t1 = costhABC / rABmag2;
+ t3 = costhABC / rBCmag2;
+ r12 = 1.0 / (rAB * rBC);
+
+ dthetadr[0][0][0] = sc1 * ((t1 * delxAB) - (delxBC * r12));
+ dthetadr[0][0][1] = sc1 * ((t1 * delyAB) - (delyBC * r12));
+ dthetadr[0][0][2] = sc1 * ((t1 * delzAB) - (delzBC * r12));
+ dthetadr[0][1][0] = sc1 * ((-t1 * delxAB) + (delxBC * r12) +
+ (-t3 * delxBC) + (delxAB * r12));
+ dthetadr[0][1][1] = sc1 * ((-t1 * delyAB) + (delyBC * r12) +
+ (-t3 * delyBC) + (delyAB * r12));
+ dthetadr[0][1][2] = sc1 * ((-t1 * delzAB) + (delzBC * r12) +
+ (-t3 * delzBC) + (delzAB * r12));
+ dthetadr[0][2][0] = sc1 * ((t3 * delxBC) - (delxAB * r12));
+ dthetadr[0][2][1] = sc1 * ((t3 * delyBC) - (delyAB * r12));
+ dthetadr[0][2][2] = sc1 * ((t3 * delzBC) - (delzAB * r12));
+
+ // angle CBD
+
+ sc1 = sqrt(1.0/(1.0 - costhCBD*costhCBD));
+ t1 = costhCBD / rBCmag2;
+ t3 = costhCBD / rBDmag2;
+ r12 = 1.0 / (rBC * rBD);
+
+ dthetadr[1][2][0] = sc1 * ((t1 * delxBC) - (delxBD * r12));
+ dthetadr[1][2][1] = sc1 * ((t1 * delyBC) - (delyBD * r12));
+ dthetadr[1][2][2] = sc1 * ((t1 * delzBC) - (delzBD * r12));
+ dthetadr[1][1][0] = sc1 * ((-t1 * delxBC) + (delxBD * r12) +
+ (-t3 * delxBD) + (delxBC * r12));
+ dthetadr[1][1][1] = sc1 * ((-t1 * delyBC) + (delyBD * r12) +
+ (-t3 * delyBD) + (delyBC * r12));
+ dthetadr[1][1][2] = sc1 * ((-t1 * delzBC) + (delzBD * r12) +
+ (-t3 * delzBD) + (delzBC * r12));
+ dthetadr[1][3][0] = sc1 * ((t3 * delxBD) - (delxBC * r12));
+ dthetadr[1][3][1] = sc1 * ((t3 * delyBD) - (delyBC * r12));
+ dthetadr[1][3][2] = sc1 * ((t3 * delzBD) - (delzBC * r12));
+
+ // angle ABD
+
+ sc1 = sqrt(1.0/(1.0 - costhABD*costhABD));
+ t1 = costhABD / rABmag2;
+ t3 = costhABD / rBDmag2;
+ r12 = 1.0 / (rAB * rBD);
+
+ dthetadr[2][0][0] = sc1 * ((t1 * delxAB) - (delxBD * r12));
+ dthetadr[2][0][1] = sc1 * ((t1 * delyAB) - (delyBD * r12));
+ dthetadr[2][0][2] = sc1 * ((t1 * delzAB) - (delzBD * r12));
+ dthetadr[2][1][0] = sc1 * ((-t1 * delxAB) + (delxBD * r12) +
+ (-t3 * delxBD) + (delxAB * r12));
+ dthetadr[2][1][1] = sc1 * ((-t1 * delyAB) + (delyBD * r12) +
+ (-t3 * delyBD) + (delyAB * r12));
+ dthetadr[2][1][2] = sc1 * ((-t1 * delzAB) + (delzBD * r12) +
+ (-t3 * delzBD) + (delzAB * r12));
+ dthetadr[2][3][0] = sc1 * ((t3 * delxBD) - (delxAB * r12));
+ dthetadr[2][3][1] = sc1 * ((t3 * delyBD) - (delyAB * r12));
+ dthetadr[2][3][2] = sc1 * ((t3 * delzBD) - (delzAB * r12));
+
+ // angleangle forces
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 3; j++)
+ fabcd[i][j] = -
+ ((aa_k1[type] *
+ (dthABC*dthetadr[1][i][j] + dthCBD*dthetadr[0][i][j])) +
+ (aa_k2[type] *
+ (dthABC*dthetadr[2][i][j] + dthABD*dthetadr[0][i][j])) +
+ (aa_k3[type] *
+ (dthABD*dthetadr[1][i][j] + dthCBD*dthetadr[2][i][j])));
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += fabcd[0][0];
+ f[i1][1] += fabcd[0][1];
+ f[i1][2] += fabcd[0][2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += fabcd[1][0];
+ f[i2][1] += fabcd[1][1];
+ f[i2][2] += fabcd[1][2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += fabcd[2][0];
+ f[i3][1] += fabcd[2][1];
+ f[i3][2] += fabcd[2][2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += fabcd[3][0];
+ f[i4][1] += fabcd[3][1];
+ f[i4][2] += fabcd[3][2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,
+ fabcd[0],fabcd[2],fabcd[3],delxAB,delyAB,delzAB,
+ delxBC,delyBC,delzBC,delxBD,delyBD,delzBD,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_peri_lps_omp.h b/src/USER-OMP/improper_class2_omp.h
similarity index 64%
copy from src/USER-OMP/pair_peri_lps_omp.h
copy to src/USER-OMP/improper_class2_omp.h
index 2068830ca..130a680d0 100644
--- a/src/USER-OMP/pair_peri_lps_omp.h
+++ b/src/USER-OMP/improper_class2_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef IMPROPER_CLASS
-PairStyle(peri/lps/omp,PairPeriLPSOMP)
+ImproperStyle(class2/omp,ImproperClass2OMP)
#else
-#ifndef LMP_PAIR_PERI_LPS_OMP_H
-#define LMP_PAIR_PERI_LPS_OMP_H
+#ifndef LMP_IMPROPER_CLASS2_OMP_H
+#define LMP_IMPROPER_CLASS2_OMP_H
-#include "pair_peri_lps.h"
+#include "improper_class2.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairPeriLPSOMP : public PairPeriLPS, public ThrOMP {
+class ImproperClass2OMP : public ImproperClass2, public ThrOMP {
public:
- PairPeriLPSOMP(class LAMMPS *);
+ ImproperClass2OMP(class LAMMPS *lmp) :
+ ImproperClass2(lmp), ThrOMP(lmp,THR_IMPROPER) {};
virtual void compute(int, int);
- virtual double memory_usage();
-
- protected:
- void compute_dilatation_thr(int ifrom, int ito);
-
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
+
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void angleangle_thr(int, int, ThrData * const thr);
+
};
}
#endif
#endif
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/improper_cvff_omp.cpp
similarity index 68%
copy from src/USER-OMP/dihedral_multi_harmonic_omp.cpp
copy to src/USER-OMP/improper_cvff_omp.cpp
index bde958984..06f3186e0 100644
--- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
+++ b/src/USER-OMP/improper_cvff_omp.cpp
@@ -1,269 +1,295 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
-#include "dihedral_multi_harmonic_omp.h"
+#include "improper_cvff_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
-void DihedralMultiHarmonicOMP::compute(int eflag, int vflag)
+void ImproperCvffOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
- const int inum = neighbor->ndihedrallist;
+ const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_bond) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_bond) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_bond) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
-void DihedralMultiHarmonicOMP::eval(double **f, int nfrom, int nto, int tid)
+void ImproperCvffOMP::eval(int nfrom, int nto, ThrData * const thr)
{
-
- int i1,i2,i3,i4,n,type;
+ int i1,i2,i3,i4,m,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
- double edihedral,f1[3],f2[3],f3[3],f4[3];
+ double eimproper,f1[3],f2[3],f3[3],f4[3];
double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
- double c2mag,sc1,sc2,s1,s12,c,pd,a,a11,a22;
+ double c2mag,sc1,sc2,s1,s2,s12,c,p,pd,rc2,a,a11,a22;
double a33,a12,a13,a23,sx2,sy2,sz2;
- double s2,sin2;
- edihedral = 0.0;
+ eimproper = 0.0;
- double **x = atom->x;
- int **dihedrallist = neighbor->dihedrallist;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const improperlist = neighbor->improperlist;
+ const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
- i1 = dihedrallist[n][0];
- i2 = dihedrallist[n][1];
- i3 = dihedrallist[n][2];
- i4 = dihedrallist[n][3];
- type = dihedrallist[n][4];
+ i1 = improperlist[n][0];
+ i2 = improperlist[n][1];
+ i3 = improperlist[n][2];
+ i4 = improperlist[n][3];
+ type = improperlist[n][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(vb2x,vb2y,vb2z);
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(vb3x,vb3y,vb3z);
-
+
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
- sin2 = MAX(1.0 - c1mag*c1mag,0.0);
- sc1 = sqrt(sin2);
+ sc1 = sqrt(1.0 - c1mag*c1mag);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
- sin2 = MAX(1.0 - c2mag*c2mag,0.0);
- sc2 = sqrt(sin2);
+ sc2 = sqrt(1.0 - c2mag*c2mag);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
int me = comm->me;
+
if (screen) {
char str[128];
- sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
- me,tid,update->ntimestep,
+ sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
fprintf(screen," 3rd atom: %d %g %g %g\n",
me,x[i3][0],x[i3][1],x[i3][2]);
fprintf(screen," 4th atom: %d %g %g %g\n",
me,x[i4][0],x[i4][1],x[i4][2]);
}
}
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
- // p = sum (i=1,5) a_i * c**(i-1)
- // pd = dp/dc
-
- pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
+ // p = 1 + cos(n*phi) for d = 1
+ // p = 1 - cos(n*phi) for d = -1
+ // pd = dp/dc / 2
+
+ m = multiplicity[type];
+
+ if (m == 2) {
+ p = 2.0*c*c;
+ pd = 2.0*c;
+ } else if (m == 3) {
+ rc2 = c*c;
+ p = (4.0*rc2-3.0)*c + 1.0;
+ pd = 6.0*rc2 - 1.5;
+ } else if (m == 4) {
+ rc2 = c*c;
+ p = 8.0*(rc2-1)*rc2 + 2.0;
+ pd = (16.0*rc2-8.0)*c;
+ } else if (m == 6) {
+ rc2 = c*c;
+ p = ((32.0*rc2-48.0)*rc2 + 18.0)*rc2;
+ pd = (96.0*(rc2-1.0)*rc2 + 18.0)*c;
+ } else if (m == 1) {
+ p = c + 1.0;
+ pd = 0.5;
+ } else if (m == 5) {
+ rc2 = c*c;
+ p = ((16.0*rc2-20.0)*rc2 + 5.0)*c + 1.0;
+ pd = (40.0*rc2-30.0)*rc2 + 2.5;
+ } else if (m == 0) {
+ p = 2.0;
+ pd = 0.0;
+ }
+
+ if (sign[type] == -1) {
+ p = 2.0 - p;
+ pd = -pd;
+ }
- if (EFLAG)
- edihedral = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
+ if (EFLAG) eimproper = k[type]*p;
- a = pd;
+ a = 2.0 * k[type] * pd;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
- a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
+ a22 = -sb2*(2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0];
f[i1][1] += f1[1];
f[i1][2] += f1[2];
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] += f2[0];
f[i2][1] += f2[1];
f[i2][2] += f2[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (NEWTON_BOND || i4 < nlocal) {
f[i4][0] += f4[0];
f[i4][1] += f4[1];
f[i4][2] += f4[2];
}
if (EVFLAG)
- ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
- vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,tid);
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/pair_morse_omp.h b/src/USER-OMP/improper_cvff_omp.h
similarity index 71%
copy from src/USER-OMP/pair_morse_omp.h
copy to src/USER-OMP/improper_cvff_omp.h
index a966e6f11..f058b10ee 100644
--- a/src/USER-OMP/pair_morse_omp.h
+++ b/src/USER-OMP/improper_cvff_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef IMPROPER_CLASS
-PairStyle(morse/omp,PairMorseOMP)
+ImproperStyle(cvff/omp,ImproperCvffOMP)
#else
-#ifndef LMP_PAIR_MORSE_OMP_H
-#define LMP_PAIR_MORSE_OMP_H
+#ifndef LMP_IMPROPER_CVFF_OMP_H
+#define LMP_IMPROPER_CVFF_OMP_H
-#include "pair_morse.h"
+#include "improper_cvff.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairMorseOMP : public PairMorse, public ThrOMP {
+class ImproperCvffOMP : public ImproperCvff, public ThrOMP {
public:
- PairMorseOMP(class LAMMPS *);
+ ImproperCvffOMP(class LAMMPS *lmp) :
+ ImproperCvff(lmp), ThrOMP(lmp,THR_IMPROPER) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/improper_harmonic_omp.cpp b/src/USER-OMP/improper_harmonic_omp.cpp
new file mode 100644
index 000000000..44e45a977
--- /dev/null
+++ b/src/USER-OMP/improper_harmonic_omp.cpp
@@ -0,0 +1,236 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "improper_harmonic_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void ImproperHarmonicOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nimproperlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void ImproperHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,i4,n,type;
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
+ double eimproper,f1[3],f2[3],f3[3],f4[3];
+ double ss1,ss2,ss3,r1,r2,r3,c0,c1,c2,s1,s2;
+ double s12,c,s,domega,a,a11,a22,a33,a12,a13,a23;
+ double sx2,sy2,sz2;
+
+ eimproper = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const improperlist = neighbor->improperlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = improperlist[n][0];
+ i2 = improperlist[n][1];
+ i3 = improperlist[n][2];
+ i4 = improperlist[n][3];
+ type = improperlist[n][4];
+
+ // geometry of 4-body
+
+ vb1x = x[i1][0] - x[i2][0];
+ vb1y = x[i1][1] - x[i2][1];
+ vb1z = x[i1][2] - x[i2][2];
+ domain->minimum_image(vb1x,vb1y,vb1z);
+
+ vb2x = x[i3][0] - x[i2][0];
+ vb2y = x[i3][1] - x[i2][1];
+ vb2z = x[i3][2] - x[i2][2];
+ domain->minimum_image(vb2x,vb2y,vb2z);
+
+ vb3x = x[i4][0] - x[i3][0];
+ vb3y = x[i4][1] - x[i3][1];
+ vb3z = x[i4][2] - x[i3][2];
+ domain->minimum_image(vb3x,vb3y,vb3z);
+
+ ss1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
+ ss2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
+ ss3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
+
+ r1 = sqrt(ss1);
+ r2 = sqrt(ss2);
+ r3 = sqrt(ss3);
+
+ // sin and cos of angle
+
+ c0 = (vb1x * vb3x + vb1y * vb3y + vb1z * vb3z) * r1 * r3;
+ c1 = (vb1x * vb2x + vb1y * vb2y + vb1z * vb2z) * r1 * r2;
+ c2 = -(vb3x * vb2x + vb3y * vb2y + vb3z * vb2z) * r3 * r2;
+
+ s1 = 1.0 - c1*c1;
+ if (s1 < SMALL) s1 = SMALL;
+ s1 = 1.0 / s1;
+
+ s2 = 1.0 - c2*c2;
+ if (s2 < SMALL) s2 = SMALL;
+ s2 = 1.0 / s2;
+
+ s12 = sqrt(s1*s2);
+ c = (c1*c2 + c0) * s12;
+
+ // error check
+
+ if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
+ int me = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,thr->get_tid(),update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ fprintf(screen," 1st atom: %d %g %g %g\n",
+ me,x[i1][0],x[i1][1],x[i1][2]);
+ fprintf(screen," 2nd atom: %d %g %g %g\n",
+ me,x[i2][0],x[i2][1],x[i2][2]);
+ fprintf(screen," 3rd atom: %d %g %g %g\n",
+ me,x[i3][0],x[i3][1],x[i3][2]);
+ fprintf(screen," 4th atom: %d %g %g %g\n",
+ me,x[i4][0],x[i4][1],x[i4][2]);
+ }
+ }
+
+ if (c > 1.0) c = 1.0;
+ if (c < -1.0) c = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+
+ // force & energy
+
+ domega = acos(c) - chi[type];
+ a = k[type] * domega;
+
+ if (EFLAG) eimproper = a*domega;
+
+ a = -a * 2.0/s;
+ c = c * a;
+ s12 = s12 * a;
+ a11 = c*ss1*s1;
+ a22 = -ss2 * (2.0*c0*s12 - c*(s1+s2));
+ a33 = c*ss3*s2;
+ a12 = -r1*r2*(c1*c*s1 + c2*s12);
+ a13 = -r1*r3*s12;
+ a23 = r2*r3*(c2*c*s2 + c1*s12);
+
+ sx2 = a22*vb2x + a23*vb3x + a12*vb1x;
+ sy2 = a22*vb2y + a23*vb3y + a12*vb1y;
+ sz2 = a22*vb2z + a23*vb3z + a12*vb1z;
+
+ f1[0] = a12*vb2x + a13*vb3x + a11*vb1x;
+ f1[1] = a12*vb2y + a13*vb3y + a11*vb1y;
+ f1[2] = a12*vb2z + a13*vb3z + a11*vb1z;
+
+ f2[0] = -sx2 - f1[0];
+ f2[1] = -sy2 - f1[1];
+ f2[2] = -sz2 - f1[2];
+
+ f4[0] = a23*vb2x + a33*vb3x + a13*vb1x;
+ f4[1] = a23*vb2y + a33*vb3y + a13*vb1y;
+ f4[2] = a23*vb2z + a33*vb3z + a13*vb1z;
+
+ f3[0] = sx2 - f4[0];
+ f3[1] = sy2 - f4[1];
+ f3[2] = sz2 - f4[2];
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0];
+ f[i1][1] += f1[1];
+ f[i1][2] += f1[2];
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f2[0];
+ f[i2][1] += f2[1];
+ f[i2][2] += f2[2];
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f3[0];
+ f[i3][1] += f3[1];
+ f[i3][2] += f3[2];
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0];
+ f[i4][1] += f4[1];
+ f[i4][2] += f4[2];
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/improper_harmonic_omp.h
similarity index 68%
copy from src/USER-OMP/pair_buck_coul_long_omp.h
copy to src/USER-OMP/improper_harmonic_omp.h
index 2c87904de..a2a6a0a03 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-OMP/improper_harmonic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef IMPROPER_CLASS
-PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+ImproperStyle(harmonic/omp,ImproperHarmonicOMP)
#else
-#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
-#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#ifndef LMP_IMPROPER_HARMONIC_OMP_H
+#define LMP_IMPROPER_HARMONIC_OMP_H
-#include "pair_buck_coul_long.h"
+#include "improper_harmonic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
+class ImproperHarmonicOMP : public ImproperHarmonic, public ThrOMP {
public:
- PairBuckCoulLongOMP(class LAMMPS *);
+ ImproperHarmonicOMP(class LAMMPS *lmp) :
+ ImproperHarmonic(lmp), ThrOMP(lmp,THR_IMPROPER) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/improper_umbrella_omp.cpp b/src/USER-OMP/improper_umbrella_omp.cpp
new file mode 100644
index 000000000..1fb1d86be
--- /dev/null
+++ b/src/USER-OMP/improper_umbrella_omp.cpp
@@ -0,0 +1,252 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "lmptype.h"
+#include "mpi.h"
+#include "math.h"
+#include "improper_umbrella_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "domain.h"
+#include "force.h"
+#include "update.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define TOLERANCE 0.05
+#define SMALL 0.001
+
+/* ---------------------------------------------------------------------- */
+
+void ImproperUmbrellaOMP::compute(int eflag, int vflag)
+{
+
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = neighbor->nimproperlist;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+void ImproperUmbrellaOMP::eval(int nfrom, int nto, ThrData * const thr)
+{
+ int i1,i2,i3,i4,n,type;
+ double eimproper,f1[3],f2[3],f3[3],f4[3];
+ double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
+ double domega,c,a,s,projhfg,dhax,dhay,dhaz,dahx,dahy,dahz,cotphi;
+ double ax,ay,az,ra2,rh2,ra,rh,rar,rhr,arx,ary,arz,hrx,hry,hrz;
+
+ eimproper = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const * const improperlist = neighbor->improperlist;
+ const int nlocal = atom->nlocal;
+
+ for (n = nfrom; n < nto; n++) {
+ i1 = improperlist[n][0];
+ i2 = improperlist[n][1];
+ i3 = improperlist[n][2];
+ i4 = improperlist[n][3];
+ type = improperlist[n][4];
+
+ // 1st bond
+
+ vb1x = x[i2][0] - x[i1][0];
+ vb1y = x[i2][1] - x[i1][1];
+ vb1z = x[i2][2] - x[i1][2];
+ domain->minimum_image(vb1x,vb1y,vb1z);
+
+ // 2nd bond
+
+ vb2x = x[i3][0] - x[i1][0];
+ vb2y = x[i3][1] - x[i1][1];
+ vb2z = x[i3][2] - x[i1][2];
+ domain->minimum_image(vb2x,vb2y,vb2z);
+
+ // 3rd bond
+
+ vb3x = x[i4][0] - x[i1][0];
+ vb3y = x[i4][1] - x[i1][1];
+ vb3z = x[i4][2] - x[i1][2];
+ domain->minimum_image(vb3x,vb3y,vb3z);
+
+ // c0 calculation
+ // A = vb1 X vb2 is perpendicular to IJK plane
+
+ ax = vb1y*vb2z-vb1z*vb2y;
+ ay = vb1z*vb2x-vb1x*vb2z;
+ az = vb1x*vb2y-vb1y*vb2x;
+ ra2 = ax*ax+ay*ay+az*az;
+ rh2 = vb3x*vb3x+vb3y*vb3y+vb3z*vb3z;
+ ra = sqrt(ra2);
+ rh = sqrt(rh2);
+ if (ra < SMALL) ra = SMALL;
+ if (rh < SMALL) rh = SMALL;
+
+ rar = 1/ra;
+ rhr = 1/rh;
+ arx = ax*rar;
+ ary = ay*rar;
+ arz = az*rar;
+ hrx = vb3x*rhr;
+ hry = vb3y*rhr;
+ hrz = vb3z*rhr;
+
+ c = arx*hrx+ary*hry+arz*hrz;
+
+ // error check
+
+ if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
+ int me = comm->me;
+
+ if (screen) {
+ char str[128];
+ sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
+ me,thr->get_tid(),update->ntimestep,
+ atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+ error->warning(FLERR,str,0);
+ fprintf(screen," 1st atom: %d %g %g %g\n",
+ me,x[i1][0],x[i1][1],x[i1][2]);
+ fprintf(screen," 2nd atom: %d %g %g %g\n",
+ me,x[i2][0],x[i2][1],x[i2][2]);
+ fprintf(screen," 3rd atom: %d %g %g %g\n",
+ me,x[i3][0],x[i3][1],x[i3][2]);
+ fprintf(screen," 4th atom: %d %g %g %g\n",
+ me,x[i4][0],x[i4][1],x[i4][2]);
+ }
+ }
+
+ if (c > 1.0) s = 1.0;
+ if (c < -1.0) s = -1.0;
+
+ s = sqrt(1.0 - c*c);
+ if (s < SMALL) s = SMALL;
+ cotphi = c/s;
+
+ projhfg = (vb3x*vb1x+vb3y*vb1y+vb3z*vb1z) /
+ sqrt(vb1x*vb1x+vb1y*vb1y+vb1z*vb1z);
+ projhfg += (vb3x*vb2x+vb3y*vb2y+vb3z*vb2z) /
+ sqrt(vb2x*vb2x+vb2y*vb2y+vb2z*vb2z);
+ if (projhfg > 0.0) {
+ s *= -1.0;
+ cotphi *= -1.0;
+ }
+
+ // force and energy
+ // if w0 = 0: E = k * (1 - cos w)
+ // if w0 != 0: E = 0.5 * C (cos w - cos w0)^2, C = k/(sin(w0)^2
+
+ if (w0[type] == 0.0) {
+ if (EFLAG) eimproper = kw[type] * (1.0-s);
+ a = -kw[type];
+ } else {
+ domega = s - cos(w0[type]);
+ a = 0.5 * C[type] * domega;
+ if (EFLAG) eimproper = a * domega;
+ a *= 2.0;
+ }
+
+ // dhax = diffrence between H and A in X direction, etc
+
+ a = a*cotphi;
+ dhax = hrx-c*arx;
+ dhay = hry-c*ary;
+ dhaz = hrz-c*arz;
+
+ dahx = arx-c*hrx;
+ dahy = ary-c*hry;
+ dahz = arz-c*hrz;
+
+ f2[0] = (dhay*vb1z - dhaz*vb1y)*rar;
+ f2[1] = (dhaz*vb1x - dhax*vb1z)*rar;
+ f2[2] = (dhax*vb1y - dhay*vb1x)*rar;
+
+ f3[0] = (-dhay*vb2z + dhaz*vb2y)*rar;
+ f3[1] = (-dhaz*vb2x + dhax*vb2z)*rar;
+ f3[2] = (-dhax*vb2y + dhay*vb2x)*rar;
+
+ f4[0] = dahx*rhr;
+ f4[1] = dahy*rhr;
+ f4[2] = dahz*rhr;
+
+ f1[0] = -(f2[0] + f3[0] + f4[0]);
+ f1[1] = -(f2[1] + f3[1] + f4[1]);
+ f1[2] = -(f2[2] + f3[2] + f4[2]);
+
+ // apply force to each of 4 atoms
+
+ if (NEWTON_BOND || i1 < nlocal) {
+ f[i1][0] += f1[0]*a;
+ f[i1][1] += f1[1]*a;
+ f[i1][2] += f1[2]*a;
+ }
+
+ if (NEWTON_BOND || i2 < nlocal) {
+ f[i2][0] += f3[0]*a;
+ f[i2][1] += f3[1]*a;
+ f[i2][2] += f3[2]*a;
+ }
+
+ if (NEWTON_BOND || i3 < nlocal) {
+ f[i3][0] += f2[0]*a;
+ f[i3][1] += f2[1]*a;
+ f[i3][2] += f2[2]*a;
+ }
+
+ if (NEWTON_BOND || i4 < nlocal) {
+ f[i4][0] += f4[0]*a;
+ f[i4][1] += f4[1]*a;
+ f[i4][2] += f4[2]*a;
+ }
+
+ if (EVFLAG)
+ ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
+ vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
+ }
+}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/improper_umbrella_omp.h
similarity index 68%
copy from src/USER-OMP/pair_buck_coul_long_omp.h
copy to src/USER-OMP/improper_umbrella_omp.h
index 2c87904de..757089212 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-OMP/improper_umbrella_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef IMPROPER_CLASS
-PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
+ImproperStyle(umbrella/omp,ImproperUmbrellaOMP)
#else
-#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
-#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
+#ifndef LMP_IMPROPER_UMBRELLA_OMP_H
+#define LMP_IMPROPER_UMBRELLA_OMP_H
-#include "pair_buck_coul_long.h"
+#include "improper_umbrella.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
+class ImproperUmbrellaOMP : public ImproperUmbrella, public ThrOMP {
public:
- PairBuckCoulLongOMP(class LAMMPS *);
+ ImproperUmbrellaOMP(class LAMMPS *lmp) :
+ ImproperUmbrella(lmp), ThrOMP(lmp,THR_IMPROPER) {};
virtual void compute(int, int);
- virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_BOND>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/neigh_derive_omp.cpp b/src/USER-OMP/neigh_derive_omp.cpp
new file mode 100644
index 000000000..3b8fd79a2
--- /dev/null
+++ b/src/USER-OMP/neigh_derive_omp.cpp
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ build half list from full list
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+ works if full list is a skip list
+------------------------------------------------------------------------- */
+
+void Neighbor::half_from_full_no_newton_omp(NeighList *list)
+{
+ const int inum_full = list->listfull->inum;
+
+ NEIGH_OMP_INIT;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(inum_full);
+
+ int i,j,ii,jj,n,jnum,joriginal;
+ int *neighptr,*jlist;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *ilist_full = list->listfull->ilist;
+ int *numneigh_full = list->listfull->numneigh;
+ int **firstneigh_full = list->listfull->firstneigh;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over atoms in full list
+
+ for (ii = ifrom; ii < ito; ii++) {
+
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ // only one thread at a time may check whether we
+ // need new neighbor list pages and then add to them.
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ // loop over parent full list
+
+ i = ilist_full[ii];
+ jlist = firstneigh_full[i];
+ jnum = numneigh_full[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ joriginal = jlist[jj];
+ j = joriginal & NEIGHMASK;
+ if (j > i) neighptr[n++] = joriginal;
+ }
+
+ ilist[ii] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = inum_full;
+}
+
+/* ----------------------------------------------------------------------
+ build half list from full list
+ pair stored once if i,j are both owned and i < j
+ if j is ghost, only store if j coords are "above and to the right" of i
+ works if full list is a skip list
+------------------------------------------------------------------------- */
+
+void Neighbor::half_from_full_newton_omp(NeighList *list)
+{
+ const int inum_full = list->listfull->inum;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(inum_full);
+
+ int i,j,ii,jj,n,jnum,joriginal;
+ int *neighptr,*jlist;
+ double xtmp,ytmp,ztmp;
+
+ double **x = atom->x;
+ int nlocal = atom->nlocal;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *ilist_full = list->listfull->ilist;
+ int *numneigh_full = list->listfull->numneigh;
+ int **firstneigh_full = list->listfull->firstneigh;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over parent full list
+
+ for (ii = ifrom; ii < ito; ii++) {
+
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ // only one thread at a time may check whether we
+ // need new neighbor list pages and then add to them.
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ i = ilist_full[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over full neighbor list
+
+ jlist = firstneigh_full[i];
+ jnum = numneigh_full[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ joriginal = jlist[jj];
+ j = joriginal & NEIGHMASK;
+ if (j < nlocal) {
+ if (i > j) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+ neighptr[n++] = joriginal;
+ }
+
+ ilist[ii] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = inum_full;
+}
+
diff --git a/src/USER-OMP/neigh_full_omp.cpp b/src/USER-OMP/neigh_full_omp.cpp
new file mode 100644
index 000000000..5f3ebd4d9
--- /dev/null
+++ b/src/USER-OMP/neigh_full_omp.cpp
@@ -0,0 +1,564 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ N^2 search for all neighbors
+ every neighbor pair appears in list of both atoms i and j
+------------------------------------------------------------------------- */
+
+void Neighbor::full_nsq_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itype,jtype,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over owned atoms, storing neighbors
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms, owned and ghost
+ // skip i = j
+
+ for (j = 0; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+ if (i == j) continue;
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ list->gnum = 0;
+}
+
+/* ----------------------------------------------------------------------
+ N^2 search for all neighbors
+ include neighbors of ghost atoms (no "special neighbors" for ghosts)
+ every neighbor pair appears in list of both atoms i and j
+------------------------------------------------------------------------- */
+
+void Neighbor::full_nsq_ghost_omp(NeighList *list)
+{
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nall);
+
+ int i,j,n,itype,jtype,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over owned & ghost atoms, storing neighbors
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms, owned and ghost
+ // skip i = j
+
+ if (i < nlocal) {
+ for (j = 0; j < nall; j++) {
+ if (i == j) continue;
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ } else {
+ for (j = 0; j < nall; j++) {
+ if (i == j) continue;
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighghostsq[itype][jtype])
+ neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ list->gnum = nall - nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction for all neighbors
+ every neighbor pair appears in list of both atoms i and j
+------------------------------------------------------------------------- */
+
+void Neighbor::full_bin_omp(NeighList *list)
+{
+ // bin owned & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over owned atoms, storing neighbors
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in surrounding bins in stencil including self
+ // skip i = j
+
+ ibin = coord2bin(x[i]);
+
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (i == j) continue;
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ list->gnum = 0;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction for all neighbors
+ include neighbors of ghost atoms (no "special neighbors" for ghosts)
+ every neighbor pair appears in list of both atoms i and j
+------------------------------------------------------------------------- */
+
+void Neighbor::full_bin_ghost_omp(NeighList *list)
+{
+ // bin owned & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nall);
+
+ int i,j,k,n,itype,jtype,ibin,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int xbin,ybin,zbin,xbin2,ybin2,zbin2;
+ int *neighptr;
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+ int **stencilxyz = list->stencilxyz;
+
+ int npage = tid;
+ int npnt = 0;
+
+ // loop over owned & ghost atoms, storing neighbors
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in surrounding bins in stencil including self
+ // when i is a ghost atom, must check if stencil bin is out of bounds
+ // skip i = j
+
+ if (i < nlocal) {
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (i == j) continue;
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ } else {
+ ibin = coord2bin(x[i],xbin,ybin,zbin);
+ for (k = 0; k < nstencil; k++) {
+ xbin2 = xbin + stencilxyz[k][0];
+ ybin2 = ybin + stencilxyz[k][1];
+ zbin2 = zbin + stencilxyz[k][2];
+ if (xbin2 < 0 || xbin2 >= mbinx ||
+ ybin2 < 0 || ybin2 >= mbiny ||
+ zbin2 < 0 || zbin2 >= mbinz) continue;
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (i == j) continue;
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighghostsq[itype][jtype])
+ neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ list->gnum = nall - nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction for all neighbors
+ multi-type stencil is itype dependent and is distance checked
+ every neighbor pair appears in list of both atoms i and j
+------------------------------------------------------------------------- */
+
+void Neighbor::full_multi_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,ns;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*s;
+ double *cutsq,*distsq;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *nstencil_multi = list->nstencil_multi;
+ int **stencil_multi = list->stencil_multi;
+ double **distsq_multi = list->distsq_multi;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in other bins in stencil, including self
+ // skip if i,j neighbor cutoff is less than bin distance
+ // skip i = j
+
+ ibin = coord2bin(x[i]);
+ s = stencil_multi[itype];
+ distsq = distsq_multi[itype];
+ cutsq = cutneighsq[itype];
+ ns = nstencil_multi[itype];
+ for (k = 0; k < ns; k++) {
+ for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
+ jtype = type[j];
+ if (cutsq[jtype] < distsq[k]) continue;
+ if (i == j) continue;
+
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ list->gnum = 0;
+}
diff --git a/src/USER-OMP/neigh_gran_omp.cpp b/src/USER-OMP/neigh_gran_omp.cpp
new file mode 100644
index 000000000..eca58ddcc
--- /dev/null
+++ b/src/USER-OMP/neigh_gran_omp.cpp
@@ -0,0 +1,657 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "fix_shear_history.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ granular particles
+ N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
+ shear history must be accounted for when a neighbor pair is added
+ pair added to list if atoms i and j are both owned and i < j
+ pair added if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::granular_nsq_no_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ FixShearHistory * const fix_history = list->fix_history;
+ NeighList * listgranhistory = list->listgranhistory;
+
+ NEIGH_OMP_INIT;
+
+ if (fix_history)
+ if (nthreads > listgranhistory->maxpage)
+ listgranhistory->add_pages(nthreads - listgranhistory->maxpage);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listgranhistory)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,m,n,nn;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ double radi,radsum,cutsq;
+ int *neighptr,*touchptr;
+ double *shearptr;
+
+ int *npartner,**partner;
+ double ***shearpartner;
+ int **firsttouch;
+ double **firstshear;
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ if (fix_history) {
+ npartner = fix_history->npartner;
+ partner = fix_history->partner;
+ shearpartner = fix_history->shearpartner;
+ firsttouch = listgranhistory->firstneigh;
+ firstshear = listgranhistory->firstdouble;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) {
+ list->add_pages(nthreads);
+ if (fix_history)
+ listgranhistory->add_pages(nthreads);
+ }
+ }
+
+ n = nn = 0;
+ neighptr = &(list->pages[npage][npnt]);
+ if (fix_history) {
+ touchptr = &(listgranhistory->pages[npage][npnt]);
+ shearptr = &(listgranhistory->dpages[npage][3*npnt]);
+ }
+ }
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+
+ // loop over remaining atoms, owned and ghost
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) {
+ neighptr[n] = j;
+
+ if (fix_history) {
+ if (rsq < radsum*radsum) {
+ for (m = 0; m < npartner[i]; m++)
+ if (partner[i][m] == tag[j]) break;
+ if (m < npartner[i]) {
+ touchptr[n] = 1;
+ shearptr[nn++] = shearpartner[i][m][0];
+ shearptr[nn++] = shearpartner[i][m][1];
+ shearptr[nn++] = shearpartner[i][m][2];
+ } else {
+ touchptr[n] = 0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ }
+ } else {
+ touchptr[n] = 0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ }
+ }
+
+ n++;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ if (fix_history) {
+ firsttouch[i] = touchptr;
+ firstshear[i] = shearptr;
+ }
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ granular particles
+ N^2 / 2 search for neighbor pairs with full Newton's 3rd law
+ no shear history is allowed for this option
+ pair added to list if atoms i and j are both owned and i < j
+ if j is ghost only me or other proc adds pair
+ decision based on itag,jtag tests
+------------------------------------------------------------------------- */
+
+void Neighbor::granular_nsq_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itag,jtag;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ double radi,radsum,cutsq;
+ int *neighptr;
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itag = tag[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+
+ // loop over remaining atoms, owned and ghost
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+
+ if (j >= nlocal) {
+ jtag = tag[j];
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+ }
+
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) neighptr[n++] = j;
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ granular particles
+ binned neighbor list construction with partial Newton's 3rd law
+ shear history must be accounted for when a neighbor pair is added
+ each owned atom i checks own bin and surrounding bins in non-Newton stencil
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::granular_bin_no_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ FixShearHistory * const fix_history = list->fix_history;
+ NeighList * listgranhistory = list->listgranhistory;
+
+ NEIGH_OMP_INIT;
+
+ if (fix_history)
+ if (nthreads > listgranhistory->maxpage)
+ listgranhistory->add_pages(nthreads - listgranhistory->maxpage);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listgranhistory)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,m,n,nn,ibin;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ double radi,radsum,cutsq;
+ int *neighptr,*touchptr;
+ double *shearptr;
+
+ int *npartner,**partner;
+ double ***shearpartner;
+ int **firsttouch;
+ double **firstshear;
+
+ // loop over each atom, storing neighbors
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ if (fix_history) {
+ npartner = fix_history->npartner;
+ partner = fix_history->partner;
+ shearpartner = fix_history->shearpartner;
+ firsttouch = listgranhistory->firstneigh;
+ firstshear = listgranhistory->firstdouble;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) {
+ list->add_pages(nthreads);
+ if (fix_history)
+ listgranhistory->add_pages(nthreads);
+ }
+ }
+
+ n = nn = 0;
+ neighptr = &(list->pages[npage][npnt]);
+ if (fix_history) {
+ touchptr = &(listgranhistory->pages[npage][npnt]);
+ shearptr = &(listgranhistory->dpages[npage][3*npnt]);
+ }
+ }
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+ ibin = coord2bin(x[i]);
+
+ // loop over all atoms in surrounding bins in stencil including self
+ // only store pair if i < j
+ // stores own/own pairs only once
+ // stores own/ghost pairs on both procs
+
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (j <= i) continue;
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) {
+ neighptr[n] = j;
+
+ if (fix_history) {
+ if (rsq < radsum*radsum) {
+ for (m = 0; m < npartner[i]; m++)
+ if (partner[i][m] == tag[j]) break;
+ if (m < npartner[i]) {
+ touchptr[n] = 1;
+ shearptr[nn++] = shearpartner[i][m][0];
+ shearptr[nn++] = shearpartner[i][m][1];
+ shearptr[nn++] = shearpartner[i][m][2];
+ } else {
+ touchptr[n] = 0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ }
+ } else {
+ touchptr[n] = 0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ shearptr[nn++] = 0.0;
+ }
+ }
+
+ n++;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ if (fix_history) {
+ firsttouch[i] = touchptr;
+ firstshear[i] = shearptr;
+ }
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ granular particles
+ binned neighbor list construction with full Newton's 3rd law
+ no shear history is allowed for this option
+ each owned atom i checks its own bin and other bins in Newton stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::granular_bin_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,ibin;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ double radi,radsum,cutsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ n = 0;
+ neighptr = &(list->pages[npage][npnt]);
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+
+ // loop over rest of atoms in i's bin, ghosts are at end of linked list
+ // if j is owned atom, store it, since j is beyond i in linked list
+ // if j is ghost, only store if j coords are "above and to the right" of i
+
+ for (j = bins[i]; j >= 0; j = bins[j]) {
+ if (j >= nlocal) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) neighptr[n++] = j;
+ }
+
+ // loop over all atoms in other bins in stencil, store every pair
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ granular particles
+ binned neighbor list construction with Newton's 3rd law for triclinic
+ no shear history is allowed for this option
+ each owned atom i checks its own bin and other bins in triclinic stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::granular_bin_newton_tri_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,ibin;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ double radi,radsum,cutsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ double **x = atom->x;
+ double *radius = atom->radius;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ n = 0;
+ neighptr = &(list->pages[npage][npnt]);
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ radi = radius[i];
+
+ // loop over all atoms in bins in stencil
+ // pairs for atoms j "below" i are excluded
+ // below = lower z or (equal z and lower y) or (equal zy and lower x)
+ // (equal zyx and j <= i)
+ // latter excludes self-self interaction but allows superposed atoms
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp) {
+ if (x[j][0] < xtmp) continue;
+ if (x[j][0] == xtmp && j <= i) continue;
+ }
+ }
+
+ if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ radsum = radi + radius[j];
+ cutsq = (radsum+skin) * (radsum+skin);
+
+ if (rsq <= cutsq) neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
diff --git a/src/USER-OMP/neigh_half_bin_omp.cpp b/src/USER-OMP/neigh_half_bin_omp.cpp
new file mode 100644
index 000000000..3df11d38a
--- /dev/null
+++ b/src/USER-OMP/neigh_half_bin_omp.cpp
@@ -0,0 +1,364 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with partial Newton's 3rd law
+ each owned atom i checks own bin and other bins in stencil
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::half_bin_no_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in other bins in stencil including self
+ // only store pair if i < j
+ // stores own/own pairs only once
+ // stores own/ghost pairs on both procs
+
+ ibin = coord2bin(x[i]);
+
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (j <= i) continue;
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with full Newton's 3rd law
+ each owned atom i checks its own bin and other bins in Newton stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::half_bin_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over rest of atoms in i's bin, ghosts are at end of linked list
+ // if j is owned atom, store it, since j is beyond i in linked list
+ // if j is ghost, only store if j coords are "above and to the right" of i
+
+ for (j = bins[i]; j >= 0; j = bins[j]) {
+ if (j >= nlocal) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+
+ // loop over all atoms in other bins in stencil, store every pair
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with Newton's 3rd law for triclinic
+ each owned atom i checks its own bin and other bins in triclinic stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::half_bin_newton_tri_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in bins in stencil
+ // pairs for atoms j "below" i are excluded
+ // below = lower z or (equal z and lower y) or (equal zy and lower x)
+ // (equal zyx and j <= i)
+ // latter excludes self-self interaction but allows superposed atoms
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp) {
+ if (x[j][0] < xtmp) continue;
+ if (x[j][0] == xtmp && j <= i) continue;
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
diff --git a/src/USER-OMP/neigh_half_multi_omp.cpp b/src/USER-OMP/neigh_half_multi_omp.cpp
new file mode 100644
index 000000000..dcc266131
--- /dev/null
+++ b/src/USER-OMP/neigh_half_multi_omp.cpp
@@ -0,0 +1,392 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with partial Newton's 3rd law
+ each owned atom i checks own bin and other bins in stencil
+ multi-type stencil is itype dependent and is distance checked
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::half_multi_no_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,ns;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*s;
+ double *cutsq,*distsq;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *nstencil_multi = list->nstencil_multi;
+ int **stencil_multi = list->stencil_multi;
+ double **distsq_multi = list->distsq_multi;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in other bins in stencil including self
+ // only store pair if i < j
+ // skip if i,j neighbor cutoff is less than bin distance
+ // stores own/own pairs only once
+ // stores own/ghost pairs on both procs
+
+ ibin = coord2bin(x[i]);
+ s = stencil_multi[itype];
+ distsq = distsq_multi[itype];
+ cutsq = cutneighsq[itype];
+ ns = nstencil_multi[itype];
+ for (k = 0; k < ns; k++) {
+ for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
+ if (j <= i) continue;
+ jtype = type[j];
+ if (cutsq[jtype] < distsq[k]) continue;
+
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with full Newton's 3rd law
+ each owned atom i checks its own bin and other bins in Newton stencil
+ multi-type stencil is itype dependent and is distance checked
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::half_multi_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,ns;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*s;
+ double *cutsq,*distsq;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *nstencil_multi = list->nstencil_multi;
+ int **stencil_multi = list->stencil_multi;
+ double **distsq_multi = list->distsq_multi;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over rest of atoms in i's bin, ghosts are at end of linked list
+ // if j is owned atom, store it, since j is beyond i in linked list
+ // if j is ghost, only store if j coords are "above and to the right" of i
+
+ for (j = bins[i]; j >= 0; j = bins[j]) {
+ if (j >= nlocal) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+
+ // loop over all atoms in other bins in stencil, store every pair
+ // skip if i,j neighbor cutoff is less than bin distance
+
+ ibin = coord2bin(x[i]);
+ s = stencil_multi[itype];
+ distsq = distsq_multi[itype];
+ cutsq = cutneighsq[itype];
+ ns = nstencil_multi[itype];
+ for (k = 0; k < ns; k++) {
+ for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
+ jtype = type[j];
+ if (cutsq[jtype] < distsq[k]) continue;
+
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ binned neighbor list construction with Newton's 3rd law for triclinic
+ each owned atom i checks its own bin and other bins in triclinic stencil
+ multi-type stencil is itype dependent and is distance checked
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::half_multi_newton_tri_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,ns;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*s;
+ double *cutsq,*distsq;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int *nstencil_multi = list->nstencil_multi;
+ int **stencil_multi = list->stencil_multi;
+ double **distsq_multi = list->distsq_multi;
+
+ // each thread works on its own page
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in bins, including self, in stencil
+ // skip if i,j neighbor cutoff is less than bin distance
+ // bins below self are excluded from stencil
+ // pairs for atoms j "below" i are excluded
+ // below = lower z or (equal z and lower y) or (equal zy and lower x)
+ // (equal zyx and j <= i)
+ // latter excludes self-self interaction but allows superposed atoms
+
+ ibin = coord2bin(x[i]);
+ s = stencil_multi[itype];
+ distsq = distsq_multi[itype];
+ cutsq = cutneighsq[itype];
+ ns = nstencil_multi[itype];
+ for (k = 0; k < ns; k++) {
+ for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
+ jtype = type[j];
+ if (cutsq[jtype] < distsq[k]) continue;
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp) {
+ if (x[j][0] < xtmp) continue;
+ if (x[j][0] == xtmp && j <= i) continue;
+ }
+ }
+
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
diff --git a/src/USER-OMP/neigh_half_nsq_omp.cpp b/src/USER-OMP/neigh_half_nsq_omp.cpp
new file mode 100644
index 000000000..0d389b45f
--- /dev/null
+++ b/src/USER-OMP/neigh_half_nsq_omp.cpp
@@ -0,0 +1,222 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::half_nsq_no_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itype,jtype,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over remaining atoms, owned and ghost
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ N^2 / 2 search for neighbor pairs with full Newton's 3rd law
+ every pair stored exactly once by some processor
+ decision on ghost atoms based on itag,jtag tests
+------------------------------------------------------------------------- */
+
+void Neighbor::half_nsq_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itype,jtype,itag,jtag,which;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= list->maxpage) list->add_pages(nthreads);
+ }
+
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+ itag = tag[i];
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over remaining atoms, owned and ghost
+ // itag = jtag is possible for long cutoffs that include images of self
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+
+ if (j >= nlocal) {
+ jtag = tag[j];
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+}
diff --git a/src/USER-OMP/neigh_respa_omp.cpp b/src/USER-OMP/neigh_respa_omp.cpp
new file mode 100644
index 000000000..f8487244a
--- /dev/null
+++ b/src/USER-OMP/neigh_respa_omp.cpp
@@ -0,0 +1,985 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include "neighbor.h"
+#include "neighbor_omp.h"
+#include "neigh_list.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ----------------------------------------------------------------------
+ multiple respa lists
+ N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
+ pair added to list if atoms i and j are both owned and i < j
+ pair added if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::respa_nsq_no_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+
+ NeighList *listinner = list->listinner;
+ if (nthreads > listinner->maxpage)
+ listinner->add_pages(nthreads - listinner->maxpage);
+
+ NeighList *listmiddle;
+ const int respamiddle = list->respamiddle;
+ if (respamiddle) {
+ listmiddle = list->listmiddle;
+ if (nthreads > listmiddle->maxpage)
+ listmiddle->add_pages(nthreads - listmiddle->maxpage);
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listinner,listmiddle)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itype,jtype,which,n_inner,n_middle;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*neighptr_inner,*neighptr_middle;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int *ilist_inner = listinner->ilist;
+ int *numneigh_inner = listinner->numneigh;
+ int **firstneigh_inner = listinner->firstneigh;
+
+ int *ilist_middle,*numneigh_middle,**firstneigh_middle;
+ if (respamiddle) {
+ ilist_middle = listmiddle->ilist;
+ numneigh_middle = listmiddle->numneigh;
+ firstneigh_middle = listmiddle->firstneigh;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+ int npage_inner = tid;
+ int npnt_inner = 0;
+ int npage_middle = tid;
+ int npnt_middle = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage == list->maxpage) list->add_pages(nthreads);
+ }
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt_inner < oneatom) {
+ npnt_inner = 0;
+ npage_inner += nthreads;
+ if (npage_inner == listinner->maxpage) listinner->add_pages(nthreads);
+ }
+ neighptr_inner = &(listinner->pages[npage_inner][npnt_inner]);
+ n_inner = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (respamiddle) {
+ if (pgsize - npnt_middle < oneatom) {
+ npnt_middle = 0;
+ npage_middle += nthreads;
+ if (npage_middle == listmiddle->maxpage) listmiddle->add_pages(nthreads);
+ }
+ neighptr_middle = &(listmiddle->pages[npage_middle][npnt_middle]);
+ n_middle = 0;
+ }
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over remaining atoms, owned and ghost
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ ilist_inner[i] = i;
+ firstneigh_inner[i] = neighptr_inner;
+ numneigh_inner[i] = n_inner;
+ npnt_inner += n_inner;
+ if (npnt_inner >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ if (respamiddle) {
+ ilist_middle[i] = i;
+ firstneigh_middle[i] = neighptr_middle;
+ numneigh_middle[i] = n_middle;
+ npnt_middle += n_middle;
+ if (npnt_middle >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ listinner->inum = nlocal;
+ if (respamiddle) listmiddle->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ multiple respa lists
+ N^2 / 2 search for neighbor pairs with full Newton's 3rd law
+ pair added to list if atoms i and j are both owned and i < j
+ if j is ghost only me or other proc adds pair
+ decision based on itag,jtag tests
+------------------------------------------------------------------------- */
+
+void Neighbor::respa_nsq_newton_omp(NeighList *list)
+{
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+ const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
+
+ NEIGH_OMP_INIT;
+
+ NeighList *listinner = list->listinner;
+ if (nthreads > listinner->maxpage)
+ listinner->add_pages(nthreads - listinner->maxpage);
+
+ NeighList *listmiddle;
+ const int respamiddle = list->respamiddle;
+ if (respamiddle) {
+ listmiddle = list->listmiddle;
+ if (nthreads > listmiddle->maxpage)
+ listmiddle->add_pages(nthreads - listmiddle->maxpage);
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listinner,listmiddle)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,n,itype,jtype,itag,jtag,which,n_inner,n_middle;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*neighptr_inner,*neighptr_middle;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int nall = atom->nlocal + atom->nghost;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ int *ilist_inner = listinner->ilist;
+ int *numneigh_inner = listinner->numneigh;
+ int **firstneigh_inner = listinner->firstneigh;
+
+ int *ilist_middle,*numneigh_middle,**firstneigh_middle;
+ if (respamiddle) {
+ ilist_middle = listmiddle->ilist;
+ numneigh_middle = listmiddle->numneigh;
+ firstneigh_middle = listmiddle->firstneigh;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+ int npage_inner = tid;
+ int npnt_inner = 0;
+ int npage_middle = tid;
+ int npnt_middle = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage == list->maxpage) list->add_pages(nthreads);
+ }
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt_inner < oneatom) {
+ npnt_inner = 0;
+ npage_inner += nthreads;
+ if (npage_inner == listinner->maxpage) listinner->add_pages(nthreads);
+ }
+ neighptr_inner = &(listinner->pages[npage_inner][npnt_inner]);
+ n_inner = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (respamiddle) {
+ if (pgsize - npnt_middle < oneatom) {
+ npnt_middle = 0;
+ npage_middle += nthreads;
+ if (npage_middle == listmiddle->maxpage) listmiddle->add_pages(nthreads);
+ }
+ neighptr_middle = &(listmiddle->pages[npage_middle][npnt_middle]);
+ n_middle = 0;
+ }
+
+ itag = tag[i];
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over remaining atoms, owned and ghost
+
+ for (j = i+1; j < nall; j++) {
+ if (includegroup && !(mask[j] & bitmask)) continue;
+
+ if (j >= nlocal) {
+ jtag = tag[j];
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle &&
+ rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ ilist_inner[i] = i;
+ firstneigh_inner[i] = neighptr_inner;
+ numneigh_inner[i] = n_inner;
+ npnt_inner += n_inner;
+ if (npnt_inner >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ if (respamiddle) {
+ ilist_middle[i] = i;
+ firstneigh_middle[i] = neighptr_middle;
+ numneigh_middle[i] = n_middle;
+ npnt_middle += n_middle;
+ if (npnt_middle >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ listinner->inum = nlocal;
+ if (respamiddle) listmiddle->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ multiple respa lists
+ binned neighbor list construction with partial Newton's 3rd law
+ each owned atom i checks own bin and surrounding bins in non-Newton stencil
+ pair stored once if i,j are both owned and i < j
+ pair stored by me if j is ghost (also stored by proc owning j)
+------------------------------------------------------------------------- */
+
+void Neighbor::respa_bin_no_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+
+ NeighList *listinner = list->listinner;
+ if (nthreads > listinner->maxpage)
+ listinner->add_pages(nthreads - listinner->maxpage);
+
+ NeighList *listmiddle;
+ const int respamiddle = list->respamiddle;
+ if (respamiddle) {
+ listmiddle = list->listmiddle;
+ if (nthreads > listmiddle->maxpage)
+ listmiddle->add_pages(nthreads - listmiddle->maxpage);
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listinner,listmiddle)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*neighptr_inner,*neighptr_middle;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int *ilist_inner = listinner->ilist;
+ int *numneigh_inner = listinner->numneigh;
+ int **firstneigh_inner = listinner->firstneigh;
+
+ int *ilist_middle,*numneigh_middle,**firstneigh_middle;
+ if (respamiddle) {
+ ilist_middle = listmiddle->ilist;
+ numneigh_middle = listmiddle->numneigh;
+ firstneigh_middle = listmiddle->firstneigh;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+ int npage_inner = tid;
+ int npnt_inner = 0;
+ int npage_middle = tid;
+ int npnt_middle = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage == list->maxpage) list->add_pages(nthreads);
+ }
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt_inner < oneatom) {
+ npnt_inner = 0;
+ npage_inner += nthreads;
+ if (npage_inner == listinner->maxpage) listinner->add_pages(nthreads);
+ }
+ neighptr_inner = &(listinner->pages[npage_inner][npnt_inner]);
+ n_inner = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (respamiddle) {
+ if (pgsize - npnt_middle < oneatom) {
+ npnt_middle = 0;
+ npage_middle += nthreads;
+ if (npage_middle == listmiddle->maxpage) listmiddle->add_pages(nthreads);
+ }
+ neighptr_middle = &(listmiddle->pages[npage_middle][npnt_middle]);
+ n_middle = 0;
+ }
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ ibin = coord2bin(x[i]);
+
+ // loop over all atoms in surrounding bins in stencil including self
+ // only store pair if i < j
+ // stores own/own pairs only once
+ // stores own/ghost pairs on both procs
+
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (j <= i) continue;
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0)
+ neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle &&
+ rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ ilist_inner[i] = i;
+ firstneigh_inner[i] = neighptr_inner;
+ numneigh_inner[i] = n_inner;
+ npnt_inner += n_inner;
+ if (npnt_inner >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ if (respamiddle) {
+ ilist_middle[i] = i;
+ firstneigh_middle[i] = neighptr_middle;
+ numneigh_middle[i] = n_middle;
+ npnt_middle += n_middle;
+ if (npnt_middle >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ listinner->inum = nlocal;
+ if (respamiddle) listmiddle->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ multiple respa lists
+ binned neighbor list construction with full Newton's 3rd law
+ each owned atom i checks its own bin and other bins in Newton stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::respa_bin_newton_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+
+ NeighList *listinner = list->listinner;
+ if (nthreads > listinner->maxpage)
+ listinner->add_pages(nthreads - listinner->maxpage);
+
+ NeighList *listmiddle;
+ const int respamiddle = list->respamiddle;
+ if (respamiddle) {
+ listmiddle = list->listmiddle;
+ if (nthreads > listmiddle->maxpage)
+ listmiddle->add_pages(nthreads - listmiddle->maxpage);
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listinner,listmiddle)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*neighptr_inner,*neighptr_middle;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int *ilist_inner = listinner->ilist;
+ int *numneigh_inner = listinner->numneigh;
+ int **firstneigh_inner = listinner->firstneigh;
+
+ int *ilist_middle,*numneigh_middle,**firstneigh_middle;
+ if (respamiddle) {
+ ilist_middle = listmiddle->ilist;
+ numneigh_middle = listmiddle->numneigh;
+ firstneigh_middle = listmiddle->firstneigh;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+ int npage_inner = tid;
+ int npnt_inner = 0;
+ int npage_middle = tid;
+ int npnt_middle = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage == list->maxpage) list->add_pages(nthreads);
+ }
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt_inner < oneatom) {
+ npnt_inner = 0;
+ npage_inner += nthreads;
+ if (npage_inner == listinner->maxpage) listinner->add_pages(nthreads);
+ }
+ neighptr_inner = &(listinner->pages[npage_inner][npnt_inner]);
+ n_inner = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (respamiddle) {
+ if (pgsize - npnt_middle < oneatom) {
+ npnt_middle = 0;
+ npage_middle += nthreads;
+ if (npage_middle == listmiddle->maxpage) listmiddle->add_pages(nthreads);
+ }
+ neighptr_middle = &(listmiddle->pages[npage_middle][npnt_middle]);
+ n_middle = 0;
+ }
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over rest of atoms in i's bin, ghosts are at end of linked list
+ // if j is owned atom, store it, since j is beyond i in linked list
+ // if j is ghost, only store if j coords are "above and to the right" of i
+
+ for (j = bins[i]; j >= 0; j = bins[j]) {
+ if (j >= nlocal) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle &&
+ rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+
+ // loop over all atoms in other bins in stencil, store every pair
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0)
+ neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle &&
+ rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ ilist_inner[i] = i;
+ firstneigh_inner[i] = neighptr_inner;
+ numneigh_inner[i] = n_inner;
+ npnt_inner += n_inner;
+ if (npnt_inner >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ if (respamiddle) {
+ ilist_middle[i] = i;
+ firstneigh_middle[i] = neighptr_middle;
+ numneigh_middle[i] = n_middle;
+ npnt_middle += n_middle;
+ if (npnt_middle >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ listinner->inum = nlocal;
+ if (respamiddle) listmiddle->inum = nlocal;
+}
+
+/* ----------------------------------------------------------------------
+ multiple respa lists
+ binned neighbor list construction with Newton's 3rd law for triclinic
+ each owned atom i checks its own bin and other bins in triclinic stencil
+ every pair stored exactly once by some processor
+------------------------------------------------------------------------- */
+
+void Neighbor::respa_bin_newton_tri_omp(NeighList *list)
+{
+ // bin local & ghost atoms
+
+ bin_atoms();
+
+ const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
+
+ NEIGH_OMP_INIT;
+
+ NeighList *listinner = list->listinner;
+ if (nthreads > listinner->maxpage)
+ listinner->add_pages(nthreads - listinner->maxpage);
+
+ NeighList *listmiddle;
+ const int respamiddle = list->respamiddle;
+ if (respamiddle) {
+ listmiddle = list->listmiddle;
+ if (nthreads > listmiddle->maxpage)
+ listmiddle->add_pages(nthreads - listmiddle->maxpage);
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(list,listinner,listmiddle)
+#endif
+ NEIGH_OMP_SETUP(nlocal);
+
+ int i,j,k,n,itype,jtype,ibin,which,n_inner,n_middle;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+ int *neighptr,*neighptr_inner,*neighptr_middle;
+
+ // loop over each atom, storing neighbors
+
+ int **special = atom->special;
+ int **nspecial = atom->nspecial;
+ int *tag = atom->tag;
+
+ double **x = atom->x;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int *molecule = atom->molecule;
+ int molecular = atom->molecular;
+
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+ int nstencil = list->nstencil;
+ int *stencil = list->stencil;
+
+ int *ilist_inner = listinner->ilist;
+ int *numneigh_inner = listinner->numneigh;
+ int **firstneigh_inner = listinner->firstneigh;
+
+ int *ilist_middle,*numneigh_middle,**firstneigh_middle;
+ if (respamiddle) {
+ ilist_middle = listmiddle->ilist;
+ numneigh_middle = listmiddle->numneigh;
+ firstneigh_middle = listmiddle->firstneigh;
+ }
+
+ int npage = tid;
+ int npnt = 0;
+ int npage_inner = tid;
+ int npnt_inner = 0;
+ int npage_middle = tid;
+ int npnt_middle = 0;
+
+ for (i = ifrom; i < ito; i++) {
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage == list->maxpage) list->add_pages(nthreads);
+ }
+ neighptr = &(list->pages[npage][npnt]);
+ n = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt_inner < oneatom) {
+ npnt_inner = 0;
+ npage_inner += nthreads;
+ if (npage_inner == listinner->maxpage) listinner->add_pages(nthreads);
+ }
+ neighptr_inner = &(listinner->pages[npage_inner][npnt_inner]);
+ n_inner = 0;
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (respamiddle) {
+ if (pgsize - npnt_middle < oneatom) {
+ npnt_middle = 0;
+ npage_middle += nthreads;
+ if (npage_middle == listmiddle->maxpage) listmiddle->add_pages(nthreads);
+ }
+ neighptr_middle = &(listmiddle->pages[npage_middle][npnt_middle]);
+ n_middle = 0;
+ }
+
+ itype = type[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ // loop over all atoms in bins in stencil
+ // pairs for atoms j "below" i are excluded
+ // below = lower z or (equal z and lower y) or (equal zy and lower x)
+ // (equal zyx and j <= i)
+ // latter excludes self-self interaction but allows superposed atoms
+
+ ibin = coord2bin(x[i]);
+ for (k = 0; k < nstencil; k++) {
+ for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp) {
+ if (x[j][1] < ytmp) continue;
+ if (x[j][1] == ytmp) {
+ if (x[j][0] < xtmp) continue;
+ if (x[j][0] == xtmp && j <= i) continue;
+ }
+ }
+
+ jtype = type[j];
+ if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq <= cutneighsq[itype][jtype]) {
+ if (molecular) {
+ which = find_special(special[i],nspecial[i],tag[j]);
+ if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
+ } else neighptr[n++] = j;
+
+ if (rsq < cut_inner_sq) {
+ if (which == 0) neighptr_inner[n_inner++] = j;
+ else if (which > 0)
+ neighptr_inner[n_inner++] = j ^ (which << SBBITS);
+ }
+
+ if (respamiddle &&
+ rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
+ if (which == 0) neighptr_middle[n_middle++] = j;
+ else if (which > 0)
+ neighptr_middle[n_middle++] = j ^ (which << SBBITS);
+ }
+ }
+ }
+ }
+
+ ilist[i] = i;
+ firstneigh[i] = neighptr;
+ numneigh[i] = n;
+ npnt += n;
+ if (n > oneatom || npnt >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ ilist_inner[i] = i;
+ firstneigh_inner[i] = neighptr_inner;
+ numneigh_inner[i] = n_inner;
+ npnt_inner += n_inner;
+ if (npnt_inner >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+
+ if (respamiddle) {
+ ilist_middle[i] = i;
+ firstneigh_middle[i] = neighptr_middle;
+ numneigh_middle[i] = n_middle;
+ npnt_middle += n_middle;
+ if (npnt_middle >= pgsize)
+ error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
+ }
+ }
+ NEIGH_OMP_CLOSE;
+ list->inum = nlocal;
+ listinner->inum = nlocal;
+ if (respamiddle) listmiddle->inum = nlocal;
+}
diff --git a/src/USER-OMP/neighbor_omp.h b/src/USER-OMP/neighbor_omp.h
new file mode 100644
index 000000000..8cdd61d5b
--- /dev/null
+++ b/src/USER-OMP/neighbor_omp.h
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifndef LMP_NEIGHBOR_OMP_H
+#define LMP_NEIGHBOR_OMP_H
+
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
+
+namespace LAMMPS_NS {
+
+// these macros hide some ugly and redundant OpenMP related stuff
+#if defined(_OPENMP)
+
+// make sure we have at least one page for each thread
+#define NEIGH_OMP_INIT \
+ const int nthreads = comm->nthreads; \
+ if (nthreads > list->maxpage) \
+ list->add_pages(nthreads - list->maxpage)
+
+// get thread id and then assign each thread a fixed chunk of atoms
+#define NEIGH_OMP_SETUP(num) \
+ { \
+ const int tid = omp_get_thread_num(); \
+ const int idelta = 1 + num/nthreads; \
+ const int ifrom = tid*idelta; \
+ int ito = ifrom + idelta; \
+ if (ito > num) \
+ ito = num
+
+#define NEIGH_OMP_CLOSE }
+
+#else /* !defined(_OPENMP) */
+
+#define NEIGH_OMP_INIT \
+ const int nthreads = comm->nthreads;
+
+#define NEIGH_OMP_SETUP(num) \
+ const int tid = 0; \
+ const int ifrom = 0; \
+ const int ito = num
+
+#define NEIGH_OMP_CLOSE
+
+#endif
+
+}
+
+#endif
diff --git a/src/USER-OMP/pair_adp_omp.cpp b/src/USER-OMP/pair_adp_omp.cpp
index e91642e6b..3af4a2f7c 100644
--- a/src/USER-OMP/pair_adp_omp.cpp
+++ b/src/USER-OMP/pair_adp_omp.cpp
@@ -1,404 +1,388 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "pair_adp_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairADPOMP::PairADPOMP(LAMMPS *lmp) :
- PairADP(lmp), ThrOMP(lmp, PAIR)
+ PairADP(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairADPOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
- const int nall = atom->nlocal + atom->nghost;
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow energy and fp arrays if necessary
// need to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(rho);
memory->destroy(fp);
memory->destroy(mu);
memory->destroy(lambda);
nmax = atom->nmax;
memory->create(rho,nthreads*nmax,"pair:rho");
memory->create(fp,nmax,"pair:fp");
memory->create(mu,nthreads*nmax,3,"pair:mu");
memory->create(lambda,nthreads*nmax,6,"pair:lambda");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, *rho_t, **mu_t, **lambda_t;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- if (force->newton_pair) {
- rho_t = rho + tid*nall;
- mu_t = mu + tid*nall;
- lambda_t = lambda + tid*nall;
- } else {
- rho_t = rho + tid*atom->nlocal;
- mu_t = mu + tid*atom->nlocal;
- lambda_t = lambda + tid*atom->nlocal;
- }
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (force->newton_pair)
+ thr->init_adp(nall, rho, mu, lambda);
+ else
+ thr->init_adp(nlocal, rho, mu, lambda);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
- else eval<1,1,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
- else eval<1,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
- else eval<0,0,0>(f, rho_t, mu_t, lambda_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairADPOMP::eval(double **f, double *rho_t, double **mu_t,
- double **lambda_t, int iifrom, int iito, int tid)
+void PairADPOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,m,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi;
double u2,u2p,w2,w2p,nu;
double *coeff;
int *ilist,*jlist,*numneigh,**firstneigh;
double delmux,delmuy,delmuz,trdelmu,tradellam;
double adpx,adpy,adpz,fx,fy,fz;
double sumlamxx,sumlamyy,sumlamzz,sumlamyz,sumlamxz,sumlamxy;
evdwl = 0.0;
- double **x = atom->x;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const rho_t = thr->get_rho();
+ double * const * const mu_t = thr->get_mu();
+ double * const * const lambda_t = thr->get_lambda();
+ const int tid = thr->get_tid();
+
int *type = atom->type;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- // zero out density
-
- if (NEWTON_PAIR) {
- memset(rho_t, 0, nall*sizeof(double));
- memset(&(mu_t[0][0]), 0, 3*nall*sizeof(double));
- memset(&(lambda_t[0][0]), 0, 6*nall*sizeof(double));
- } else {
- memset(rho_t, 0, nlocal*sizeof(double));
- memset(&(mu_t[0][0]), 0, 3*nlocal*sizeof(double));
- memset(&(lambda_t[0][0]), 0, 6*nlocal*sizeof(double));
- }
-
// rho = density at each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq) {
jtype = type[j];
p = sqrt(rsq)*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
coeff = rhor_spline[type2rhor[jtype][itype]][m];
rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coeff = u2r_spline[type2u2r[jtype][itype]][m];
u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
mu_t[i][0] += u2*delx;
mu_t[i][1] += u2*dely;
mu_t[i][2] += u2*delz;
coeff = w2r_spline[type2w2r[jtype][itype]][m];
w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
lambda_t[i][0] += w2*delx*delx;
lambda_t[i][1] += w2*dely*dely;
lambda_t[i][2] += w2*delz*delz;
lambda_t[i][3] += w2*dely*delz;
lambda_t[i][4] += w2*delx*delz;
lambda_t[i][5] += w2*delx*dely;
if (NEWTON_PAIR || j < nlocal) {
// verify sign difference for mu and lambda
coeff = rhor_spline[type2rhor[itype][jtype]][m];
rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coeff = u2r_spline[type2u2r[itype][jtype]][m];
u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
mu_t[j][0] -= u2*delx;
mu_t[j][1] -= u2*dely;
mu_t[j][2] -= u2*delz;
coeff = w2r_spline[type2w2r[itype][jtype]][m];
w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
lambda_t[j][0] += w2*delx*delx;
lambda_t[j][1] += w2*dely*dely;
lambda_t[j][2] += w2*delz*delz;
lambda_t[j][3] += w2*dely*delz;
lambda_t[j][4] += w2*delx*delz;
lambda_t[j][5] += w2*delx*dely;
}
}
}
}
// wait until all threads are done with computation
sync_threads();
// communicate and sum densities
if (NEWTON_PAIR) {
// reduce per thread density
data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
data_reduce_thr(&(mu[0][0]), nall, comm->nthreads, 3, tid);
data_reduce_thr(&(lambda[0][0]), nall, comm->nthreads, 6, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{ comm->reverse_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
} else {
// reduce per thread density
data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
data_reduce_thr(&(mu[0][0]), nlocal, comm->nthreads, 3, tid);
data_reduce_thr(&(lambda[0][0]), nlocal, comm->nthreads, 6, tid);
// wait until reduction is complete
sync_threads();
}
// fp = derivative of embedding energy at each atom
// phi = embedding energy at each atom
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
p = rho[i]*rdrho + 1.0;
m = static_cast<int> (p);
m = MAX(1,MIN(m,nrho-1));
p -= m;
p = MIN(p,1.0);
coeff = frho_spline[type2frho[type[i]]][m];
fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
if (EFLAG) {
phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
phi += 0.5*(mu[i][0]*mu[i][0]+mu[i][1]*mu[i][1]+mu[i][2]*mu[i][2]);
phi += 0.5*(lambda[i][0]*lambda[i][0]+lambda[i][1]*
lambda[i][1]+lambda[i][2]*lambda[i][2]);
phi += 1.0*(lambda[i][3]*lambda[i][3]+lambda[i][4]*
lambda[i][4]+lambda[i][5]*lambda[i][5]);
phi -= 1.0/6.0*(lambda[i][0]+lambda[i][1]+lambda[i][2])*
(lambda[i][0]+lambda[i][1]+lambda[i][2]);
- if (eflag_global) eng_vdwl_thr[tid] += phi;
- if (eflag_atom) eatom_thr[tid][i] += phi;
+ e_tally_thr(this,i,i,nlocal,/* newton_pair */ 1, phi, 0.0, thr);
}
}
// wait until all theads are done with computation
sync_threads();
// communicate derivative of embedding function
// MPI communication only on master thread
#if defined(_OPENMP)
#pragma omp master
#endif
{ comm->forward_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
// compute forces on each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fxtmp = fytmp = fztmp = 0.0;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq) {
jtype = type[j];
r = sqrt(rsq);
p = r*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
// rhoip = derivative of (density at atom j due to atom i)
// rhojp = derivative of (density at atom i due to atom j)
// phi = pair potential energy
// phip = phi'
// z2 = phi * r
// z2p = (phi * r)' = (phi' r) + phi
// u2 = u
// u2p = u'
// w2 = w
// w2p = w'
// psip needs both fp[i] and fp[j] terms since r_ij appears in two
// terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji)
// hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip
coeff = rhor_spline[type2rhor[itype][jtype]][m];
rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = rhor_spline[type2rhor[jtype][itype]][m];
rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = z2r_spline[type2z2r[itype][jtype]][m];
z2p = (coeff[0]*p + coeff[1])*p + coeff[2];
z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coeff = u2r_spline[type2u2r[itype][jtype]][m];
u2p = (coeff[0]*p + coeff[1])*p + coeff[2];
u2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coeff = w2r_spline[type2w2r[itype][jtype]][m];
w2p = (coeff[0]*p + coeff[1])*p + coeff[2];
w2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
recip = 1.0/r;
phi = z2*recip;
phip = z2p*recip - phi*recip;
psip = fp[i]*rhojp + fp[j]*rhoip + phip;
fpair = -psip*recip;
delmux = mu[i][0]-mu[j][0];
delmuy = mu[i][1]-mu[j][1];
delmuz = mu[i][2]-mu[j][2];
trdelmu = delmux*delx+delmuy*dely+delmuz*delz;
sumlamxx = lambda[i][0]+lambda[j][0];
sumlamyy = lambda[i][1]+lambda[j][1];
sumlamzz = lambda[i][2]+lambda[j][2];
sumlamyz = lambda[i][3]+lambda[j][3];
sumlamxz = lambda[i][4]+lambda[j][4];
sumlamxy = lambda[i][5]+lambda[j][5];
tradellam = sumlamxx*delx*delx+sumlamyy*dely*dely+
sumlamzz*delz*delz+2.0*sumlamxy*delx*dely+
2.0*sumlamxz*delx*delz+2.0*sumlamyz*dely*delz;
nu = sumlamxx+sumlamyy+sumlamzz;
adpx = delmux*u2 + trdelmu*u2p*delx*recip +
2.0*w2*(sumlamxx*delx+sumlamxy*dely+sumlamxz*delz) +
w2p*delx*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delx;
adpy = delmuy*u2 + trdelmu*u2p*dely*recip +
2.0*w2*(sumlamxy*delx+sumlamyy*dely+sumlamyz*delz) +
w2p*dely*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*dely;
adpz = delmuz*u2 + trdelmu*u2p*delz*recip +
2.0*w2*(sumlamxz*delx+sumlamyz*dely+sumlamzz*delz) +
w2p*delz*recip*tradellam - 1.0/3.0*nu*(w2p*r+2.0*w2)*delz;
adpx*=-1.0; adpy*=-1.0; adpz*=-1.0;
fx = delx*fpair+adpx;
fy = dely*fpair+adpy;
fz = delz*fpair+adpz;
fxtmp += fx;
fytmp += fy;
fztmp += fz;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
}
if (EFLAG) evdwl = phi;
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
- fx,fy,fz,delx,dely,delz,tid);
+ fx,fy,fz,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairADPOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairADP::memory_usage();
-
+ bytes += (comm->nthreads-1) * nmax * (10*sizeof(double) + 3*sizeof(double *));
return bytes;
}
diff --git a/src/USER-OMP/pair_adp_omp.h b/src/USER-OMP/pair_adp_omp.h
index f7d2509cd..9a7f4023f 100644
--- a/src/USER-OMP/pair_adp_omp.h
+++ b/src/USER-OMP/pair_adp_omp.h
@@ -1,49 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(adp/omp,PairADPOMP)
#else
#ifndef LMP_PAIR_ADP_OMP_H
#define LMP_PAIR_ADP_OMP_H
#include "pair_adp.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairADPOMP : public PairADP, public ThrOMP {
public:
PairADPOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double *rho_t, double **mu_t, double **lambda_t,
- int iifrom, int iito, int tid);
+ void eval(int iifrom, int iito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/USER-OMP/pair_airebo_omp.cpp
similarity index 51%
copy from src/MANYBODY/pair_airebo.cpp
copy to src/USER-OMP/pair_airebo_omp.cpp
index c2625072c..bb8b38a5b 100644
--- a/src/MANYBODY/pair_airebo.cpp
+++ b/src/USER-OMP/pair_airebo_omp.cpp
@@ -1,4199 +1,2768 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
- Copyright (2003) Sandia Corporation. Under the terms of Contract
- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
- certain rights in this software. This software is distributed under
- the GNU General Public License.
+ This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
- Contributing author: Ase Henry (MIT)
- Bugfixes and optimizations:
- Marcel Fallet & Steve Stuart (Clemson), Axel Kohlmeyer (Temple U)
+ Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "mpi.h"
-#include "pair_airebo.h"
+#include "pair_airebo_omp.h"
#include "atom.h"
-#include "neighbor.h"
-#include "neigh_request.h"
-#include "force.h"
#include "comm.h"
+#include "error.h"
+#include "force.h"
+#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
-#include "neigh_request.h"
-#include "math_const.h"
-#include "memory.h"
-#include "error.h"
+
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
using namespace LAMMPS_NS;
-using namespace MathConst;
-#define MAXLINE 1024
#define TOL 1.0e-9
-#define PGDELTA 1
/* ---------------------------------------------------------------------- */
-PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp)
+PairAIREBOOMP::PairAIREBOOMP(LAMMPS *lmp) :
+ PairAIREBO(lmp), ThrOMP(lmp, THR_PAIR)
{
- single_enable = 0;
- one_coeff = 1;
- ghostneigh = 1;
-
- maxlocal = 0;
- REBO_numneigh = NULL;
- REBO_firstneigh = NULL;
- maxpage = 0;
- pages = NULL;
- nC = nH = NULL;
-}
-
-/* ----------------------------------------------------------------------
- check if allocated, since class can be destructed when incomplete
-------------------------------------------------------------------------- */
-
-PairAIREBO::~PairAIREBO()
-{
- memory->destroy(REBO_numneigh);
- memory->sfree(REBO_firstneigh);
- for (int i = 0; i < maxpage; i++) memory->destroy(pages[i]);
- memory->sfree(pages);
- memory->destroy(nC);
- memory->destroy(nH);
-
- if (allocated) {
- memory->destroy(setflag);
- memory->destroy(cutsq);
- memory->destroy(cutghost);
-
- memory->destroy(cutljsq);
- memory->destroy(lj1);
- memory->destroy(lj2);
- memory->destroy(lj3);
- memory->destroy(lj4);
- delete [] map;
- }
+ respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
-void PairAIREBO::compute(int eflag, int vflag)
+void PairAIREBOOMP::compute(int eflag, int vflag)
{
- if (eflag || vflag) ev_setup(eflag,vflag);
- else evflag = vflag_fdotr = vflag_atom = 0;
-
- REBO_neigh();
- FREBO(eflag,vflag);
- if (ljflag) FLJ(eflag,vflag);
- if (torflag) TORSION(eflag,vflag);
-
- if (vflag_fdotr) virial_fdotr_compute();
-}
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
-/* ----------------------------------------------------------------------
- allocate all arrays
-------------------------------------------------------------------------- */
-
-void PairAIREBO::allocate()
-{
- allocated = 1;
- int n = atom->ntypes;
+ REBO_neigh_thr();
- memory->create(setflag,n+1,n+1,"pair:setflag");
- for (int i = 1; i <= n; i++)
- for (int j = i; j <= n; j++)
- setflag[i][j] = 0;
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
- memory->create(cutsq,n+1,n+1,"pair:cutsq");
- memory->create(cutghost,n+1,n+1,"pair:cutghost");
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
- // only sized by C,H = 2 types
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
- memory->create(cutljsq,2,2,"pair:cutljsq");
- memory->create(lj1,2,2,"pair:lj1");
- memory->create(lj2,2,2,"pair:lj2");
- memory->create(lj3,2,2,"pair:lj3");
- memory->create(lj4,2,2,"pair:lj4");
+ FREBO_thr(ifrom,ito,evflag,eflag,vflag_atom,thr);
+ if (ljflag) FLJ_thr(ifrom,ito,evflag,eflag,vflag_atom,thr);
+ if (torflag) TORSION_thr(ifrom,ito,evflag,eflag,thr);
- map = new int[n+1];
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
}
/* ----------------------------------------------------------------------
- global settings
+ Bij function
------------------------------------------------------------------------- */
-void PairAIREBO::settings(int narg, char **arg)
+double PairAIREBOOMP::bondorder_thr(int i, int j, double rij[3], double rijmag,
+ double VA, int vflag_atom, ThrData * const thr)
{
- if (narg != 1 && narg != 3) error->all(FLERR,"Illegal pair_style command");
+ int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
+ int itype,jtype,ktype,ltype,ntype;
+ double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij;
+ double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
+ double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
+ double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS;
+ double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
+ double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
+ double dN2[2],dN3[3];
+ double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3];
+ double Tij;
+ double r32[3],r32mag,cos321,r43[3],r13[3];
+ double dNlj;
+ double om1234,rln[3];
+ double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
+ double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
+ double cross321[3],cross234[3],prefactor,SpN;
+ double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
+ double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
+ double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
+ double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
+ double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
+ double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3];
+ double f1[3],f2[3],f3[3],f4[4];
+ double dcut321,PijS,PjiS;
+ double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
+ int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
- cutlj = force->numeric(arg[0]);
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ int *type = atom->type;
- ljflag = torflag = 1;
- if (narg == 3) {
- ljflag = force->inumeric(arg[1]);
- torflag = force->inumeric(arg[2]);
- }
-}
+ atomi = i;
+ atomj = j;
+ itype = map[type[i]];
+ jtype = map[type[j]];
+ wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+ NijC = nC[i]-(wij*kronecker(jtype,0));
+ NijH = nH[i]-(wij*kronecker(jtype,1));
+ NjiC = nC[j]-(wij*kronecker(itype,0));
+ NjiH = nH[j]-(wij*kronecker(itype,1));
+ bij = 0.0;
+ tmp = 0.0;
+ tmp2 = 0.0;
+ tmp3 = 0.0;
+ dgdc = 0.0;
+ dgdN = 0.0;
+ NconjtmpI = 0.0;
+ NconjtmpJ = 0.0;
+ Etmp = 0.0;
-/* ----------------------------------------------------------------------
- set coeffs for one or more type pairs
-------------------------------------------------------------------------- */
+ REBO_neighs = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs[k];
+ if (atomk != atomj) {
+ ktype = map[type[atomk]];
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ lamdajik = 4.0*kronecker(itype,1) *
+ ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
+ Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+ (wik*kronecker(itype,1));
+ cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+ (rijmag*rikmag);
+ cosjik = MIN(cosjik,1.0);
+ cosjik = MAX(cosjik,-1.0);
-void PairAIREBO::coeff(int narg, char **arg)
-{
- if (!allocated) allocate();
+ // evaluate splines g and derivatives dg
- if (narg != 3 + atom->ntypes)
- error->all(FLERR,"Incorrect args for pair coefficients");
+ g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+ Etmp = Etmp+(wik*g*exp(lamdajik));
+ tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
+ NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
+ }
+ }
- // insure I,J args are * *
+ PijS = 0.0;
+ dN2[0] = 0.0;
+ dN2[1] = 0.0;
+ PijS = PijSpline(NijC,NijH,itype,jtype,dN2);
+ pij = 1.0/sqrt(1.0+Etmp+PijS);
+ tmp = -0.5*pij*pij*pij;
- if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
- error->all(FLERR,"Incorrect args for pair coefficients");
+ const double invrijm = 1.0/rijmag;
+ const double invrijm2 = invrijm*invrijm;
- // read args that map atom types to C and H
- // map[i] = which element (0,1) the Ith atom type is, -1 if NULL
+ // pij forces
- for (int i = 3; i < narg; i++) {
- if (strcmp(arg[i],"NULL") == 0) {
- map[i-2] = -1;
- continue;
- } else if (strcmp(arg[i],"C") == 0) {
- map[i-2] = 0;
- } else if (strcmp(arg[i],"H") == 0) {
- map[i-2] = 1;
- } else error->all(FLERR,"Incorrect args for pair coefficients");
- }
+ REBO_neighs = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs[k];
+ if (atomk != atomj) {
+ ktype = map[type[atomk]];
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ lamdajik = 4.0*kronecker(itype,1) *
+ ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- // read potential file and initialize fitting splines
+ const double invrikm = 1.0/rikmag;
+ const double invrijkm = invrijm*invrikm;
+ const double invrikm2 = invrikm*invrikm;
- read_file(arg[2]);
- spline_init();
+ cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) * invrijkm;
+ cosjik = MIN(cosjik,1.0);
+ cosjik = MAX(cosjik,-1.0);
- // clear setflag since coeff() called once with I,J = * *
+ dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) -
+ (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2)));
+ dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) -
+ (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2)));
+ dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) -
+ (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2)));
+ dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2));
+ dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2));
+ dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2));
+ dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2));
+ dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2));
+ dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2));
- int n = atom->ntypes;
- for (int i = 1; i <= n; i++)
- for (int j = i; j <= n; j++)
- setflag[i][j] = 0;
+ g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+ tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
+ fj[0] = -tmp2*dcosjikdrj[0];
+ fj[1] = -tmp2*dcosjikdrj[1];
+ fj[2] = -tmp2*dcosjikdrj[2];
+ fi[0] = -tmp2*dcosjikdri[0];
+ fi[1] = -tmp2*dcosjikdri[1];
+ fi[2] = -tmp2*dcosjikdri[2];
+ fk[0] = -tmp2*dcosjikdrk[0];
+ fk[1] = -tmp2*dcosjikdrk[1];
+ fk[2] = -tmp2*dcosjikdrk[2];
- // set setflag i,j for type pairs where both are mapped to elements
+ tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
+ fj[0] -= tmp2*(-rij[0]*invrijm);
+ fj[1] -= tmp2*(-rij[1]*invrijm);
+ fj[2] -= tmp2*(-rij[2]*invrijm);
+ fi[0] -= tmp2*((-rik[0]*invrikm)+(rij[0]*invrijm));
+ fi[1] -= tmp2*((-rik[1]*invrikm)+(rij[1]*invrijm));
+ fi[2] -= tmp2*((-rik[2]*invrikm)+(rij[2]*invrijm));
+ fk[0] -= tmp2*(rik[0]*invrikm);
+ fk[1] -= tmp2*(rik[1]*invrikm);
+ fk[2] -= tmp2*(rik[2]*invrikm);
- int count = 0;
- for (int i = 1; i <= n; i++)
- for (int j = i; j <= n; j++)
- if (map[i] >= 0 && map[j] >= 0) {
- setflag[i][j] = 1;
- count++;
- }
+ // coordination forces
- if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
-}
+ // dwik forces
-/* ----------------------------------------------------------------------
- init specific to this pair style
-------------------------------------------------------------------------- */
+ tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))*invrikm;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
-void PairAIREBO::init_style()
-{
- if (atom->tag_enable == 0)
- error->all(FLERR,"Pair style AIREBO requires atom IDs");
- if (force->newton_pair == 0)
- error->all(FLERR,"Pair style AIREBO requires newton pair on");
+ // PIJ forces
- // need a full neighbor list, including neighbors of ghosts
+ tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)*invrikm;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
- int irequest = neighbor->request(this);
- neighbor->requests[irequest]->half = 0;
- neighbor->requests[irequest]->full = 1;
- neighbor->requests[irequest]->ghost = 1;
+ // dgdN forces
- // local REBO neighbor list memory
+ tmp2 = VA*.5*(tmp*tmp3*dwik)*invrikm;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
- pgsize = neighbor->pgsize;
- oneatom = neighbor->oneatom;
- if (maxpage == 0) add_pages();
-}
+ f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+ f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
-/* ----------------------------------------------------------------------
- init for one type pair i,j and corresponding j,i
-------------------------------------------------------------------------- */
+ if (vflag_atom) {
+ rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
+ rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
+ v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
+ }
+ }
+ }
-double PairAIREBO::init_one(int i, int j)
-{
- if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+ tmp = 0.0;
+ tmp2 = 0.0;
+ tmp3 = 0.0;
+ Etmp = 0.0;
- // convert to C,H types
+ REBO_neighs = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml != atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ lamdaijl = 4.0*kronecker(jtype,1) *
+ ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) +
+ nH[atoml]-(wjl*kronecker(jtype,1));
+ cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+ (rijmag*rjlmag);
+ cosijl = MIN(cosijl,1.0);
+ cosijl = MAX(cosijl,-1.0);
- int ii = map[i];
- int jj = map[j];
+ // evaluate splines g and derivatives dg
- // use C-C values for these cutoffs since C atoms are biggest
+ g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+ Etmp = Etmp+(wjl*g*exp(lamdaijl));
+ tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
+ NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
+ }
+ }
- // cut3rebo = 3 REBO distances
+ PjiS = 0.0;
+ dN2[0] = 0.0;
+ dN2[1] = 0.0;
+ PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2);
+ pji = 1.0/sqrt(1.0+Etmp+PjiS);
+ tmp = -0.5*pji*pji*pji;
- cut3rebo = 3.0 * rcmax[0][0];
+ REBO_neighs = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml != atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ lamdaijl = 4.0*kronecker(jtype,1) *
+ ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- // cutljrebosq = furthest distance from an owned atom a ghost atom can be
- // to need its REBO neighs computed
- // interaction = M-K-I-J-L-N with I = owned and J = ghost
- // this insures N is in the REBO neigh list of L
- // since I-J < rcLJmax and J-L < rmax
+ const double invrjlm = 1.0/rjlmag;
+ const double invrijlm = invrijm*invrjlm;
+ const double invrjlm2 = invrjlm*invrjlm;
- double cutljrebo = rcLJmax[0][0] + rcmax[0][0];
- cutljrebosq = cutljrebo * cutljrebo;
+ cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])))
+ * invrijlm;
- // cutmax = furthest distance from an owned atom
- // at which another atom will feel force, i.e. the ghost cutoff
- // for REBO term in potential:
- // interaction = M-K-I-J-L-N with I = owned and J = ghost
- // I to N is max distance = 3 REBO distances
- // for LJ term in potential:
- // short interaction = M-K-I-J-L-N with I = owned, J = ghost, I-J < rcLJmax
- // rcLJmax + 2*rcmax, since I-J < rcLJmax and J-L,L-N = REBO distances
- // long interaction = I-J with I = owned and J = ghost
- // cutlj*sigma, since I-J < LJ cutoff
- // cutghost = REBO cutoff used in REBO_neigh() for neighbors of ghosts
+ cosijl = MIN(cosijl,1.0);
+ cosijl = MAX(cosijl,-1.0);
- double cutmax = cut3rebo;
- if (ljflag) {
- cutmax = MAX(cutmax,rcLJmax[0][0] + 2.0*rcmax[0][0]);
- cutmax = MAX(cutmax,cutlj*sigma[0][0]);
- }
+ dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2);
+ dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2);
+ dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2);
+ dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) +
+ (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2)));
+ dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) +
+ (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2)));
+ dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) +
+ (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2)));
+ dcosijldrl[0] = (rij[0]*invrijlm)+(cosijl*rjl[0]*invrjlm2);
+ dcosijldrl[1] = (rij[1]*invrijlm)+(cosijl*rjl[1]*invrjlm2);
+ dcosijldrl[2] = (rij[2]*invrijlm)+(cosijl*rjl[2]*invrjlm2);
- cutghost[i][j] = rcmax[ii][jj];
- cutljsq[ii][jj] = cutlj*sigma[ii][jj] * cutlj*sigma[ii][jj];
- lj1[ii][jj] = 48.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0);
- lj2[ii][jj] = 24.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0);
- lj3[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],12.0);
- lj4[ii][jj] = 4.0 * epsilon[ii][jj] * pow(sigma[ii][jj],6.0);
-
- cutghost[j][i] = cutghost[i][j];
- cutljsq[jj][ii] = cutljsq[ii][jj];
- lj1[jj][ii] = lj1[ii][jj];
- lj2[jj][ii] = lj2[ii][jj];
- lj3[jj][ii] = lj3[ii][jj];
- lj4[jj][ii] = lj4[ii][jj];
-
- return cutmax;
-}
+ // evaluate splines g and derivatives dg
-/* ----------------------------------------------------------------------
- create REBO neighbor list from main neighbor list
- REBO neighbor list stores neighbors of ghost atoms
-------------------------------------------------------------------------- */
+ g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+ tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
+ fi[0] = -tmp2*dcosijldri[0];
+ fi[1] = -tmp2*dcosijldri[1];
+ fi[2] = -tmp2*dcosijldri[2];
+ fj[0] = -tmp2*dcosijldrj[0];
+ fj[1] = -tmp2*dcosijldrj[1];
+ fj[2] = -tmp2*dcosijldrj[2];
+ fl[0] = -tmp2*dcosijldrl[0];
+ fl[1] = -tmp2*dcosijldrl[1];
+ fl[2] = -tmp2*dcosijldrl[2];
-void PairAIREBO::REBO_neigh()
-{
- int i,j,ii,jj,n,allnum,jnum,itype,jtype;
- double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS;
- int *ilist,*jlist,*numneigh,**firstneigh;
- int *neighptr;
+ tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
+ fi[0] -= tmp2*(rij[0]*invrijm);
+ fi[1] -= tmp2*(rij[1]*invrijm);
+ fi[2] -= tmp2*(rij[2]*invrijm);
+ fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm));
+ fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm));
+ fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm));
+ fl[0] -= tmp2*(rjl[0]*invrjlm);
+ fl[1] -= tmp2*(rjl[1]*invrjlm);
+ fl[2] -= tmp2*(rjl[2]*invrjlm);
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
+ // coordination forces
- if (atom->nmax > maxlocal) {
- maxlocal = atom->nmax;
- memory->destroy(REBO_numneigh);
- memory->sfree(REBO_firstneigh);
- memory->destroy(nC);
- memory->destroy(nH);
- memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh");
- REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),
- "AIREBO:firstneigh");
- memory->create(nC,maxlocal,"AIREBO:nC");
- memory->create(nH,maxlocal,"AIREBO:nH");
- }
-
- allnum = list->inum + list->gnum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
+ // dwik forces
- // store all REBO neighs of owned and ghost atoms
- // scan full neighbor list of I
+ tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- int npage = 0;
- int npnt = 0;
+ // PIJ forces
- for (ii = 0; ii < allnum; ii++) {
- i = ilist[ii];
+ tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- if (pgsize - npnt < oneatom) {
- npnt = 0;
- npage++;
- if (npage == maxpage) add_pages();
- }
- neighptr = &pages[npage][npnt];
- n = 0;
+ // dgdN forces
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- itype = map[type[i]];
- nC[i] = nH[i] = 0.0;
- jlist = firstneigh[i];
- jnum = numneigh[i];
+ tmp2 = VA*.5*(tmp*tmp3*dwjl)*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
- jtype = map[type[j]];
- delx = xtmp - x[j][0];
- dely = ytmp - x[j][1];
- delz = ztmp - x[j][2];
- rsq = delx*delx + dely*dely + delz*delz;
+ f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+ f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
- if (rsq < rcmaxsq[itype][jtype]) {
- neighptr[n++] = j;
- if (jtype == 0)
- nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
- else
- nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+ if (vflag_atom) {
+ rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
+ v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
}
}
-
- REBO_firstneigh[i] = neighptr;
- REBO_numneigh[i] = n;
- npnt += n;
- if (npnt >= pgsize)
- error->one(FLERR,"Neighbor list overflow, boost neigh_modify one or page");
}
-}
-
-/* ----------------------------------------------------------------------
- REBO forces and energy
-------------------------------------------------------------------------- */
-void PairAIREBO::FREBO(int eflag, int vflag)
-{
- int i,j,k,m,ii,inum,itype,jtype,itag,jtag;
- double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
- double rsq,rij,wij;
- double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
- double dwij,del[3];
- int *ilist,*REBO_neighs;
-
- evdwl = 0.0;
+ // evaluate Nij conj
- double **x = atom->x;
- double **f = atom->f;
- int *type = atom->type;
- int *tag = atom->tag;
- int nlocal = atom->nlocal;
- int newton_pair = force->newton_pair;
+ Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
+ piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3);
- inum = list->inum;
- ilist = list->ilist;
+ // piRC forces
- // two-body interactions from REBO neighbor list, skip half of them
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs_i[k];
+ if (atomk !=atomj) {
+ ktype = map[type[atomk]];
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+ Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+ (wik*kronecker(itype,1));
+ SpN = Sp(Nki,Nmin,Nmax,dNki);
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- itag = tag[i];
- itype = map[type[i]];
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- REBO_neighs = REBO_firstneigh[i];
+ tmp2 = VA*dN3[0]*dwik/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- j = REBO_neighs[k];
- jtag = tag[j];
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- if (itag > jtag) {
- if ((itag+jtag) % 2 == 0) continue;
- } else if (itag < jtag) {
- if ((itag+jtag) % 2 == 1) continue;
- } else {
- if (x[j][2] < ztmp) continue;
- if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
- if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
- }
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- jtype = map[type[j]];
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- delx = x[i][0] - x[j][0];
- dely = x[i][1] - x[j][1];
- delz = x[i][2] - x[j][2];
- rsq = delx*delx + dely*dely + delz*delz;
- rij = sqrt(rsq);
- wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
- if (wij <= TOL) continue;
-
- Qij = Q[itype][jtype];
- Aij = A[itype][jtype];
- alphaij = alpha[itype][jtype];
+ if (fabs(dNki) > TOL) {
+ REBO_neighs_k = REBO_firstneigh[atomk];
+ for (n = 0; n < REBO_numneigh[atomk]; n++) {
+ atomn = REBO_neighs_k[n];
+ if (atomn != atomi) {
+ ntype = map[type[atomn]];
+ rkn[0] = x[atomk][0]-x[atomn][0];
+ rkn[1] = x[atomk][1]-x[atomn][1];
+ rkn[2] = x[atomk][2]-x[atomn][2];
+ rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+ Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
- VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij);
- pre = wij*Aij * exp(-alphaij*rij);
- dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij));
- dVRdi += VR/wij * dwij;
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
+ f[atomk][0] -= tmp2*rkn[0];
+ f[atomk][1] -= tmp2*rkn[1];
+ f[atomk][2] -= tmp2*rkn[2];
+ f[atomn][0] += tmp2*rkn[0];
+ f[atomn][1] += tmp2*rkn[1];
+ f[atomn][2] += tmp2*rkn[2];
- VA = dVA = 0.0;
- for (m = 0; m < 3; m++) {
- term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij);
- VA += term;
- dVA += -Beta[itype][jtype][m] * term;
+ if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+ }
+ }
}
- dVA += VA/wij * dwij;
- del[0] = delx;
- del[1] = dely;
- del[2] = delz;
- bij = bondorder(i,j,del,rij,VA,f,vflag_atom);
- dVAdi = bij*dVA;
-
- fpair = -(dVRdi+dVAdi) / rij;
- f[i][0] += delx*fpair;
- f[i][1] += dely*fpair;
- f[i][2] += delz*fpair;
- f[j][0] -= delx*fpair;
- f[j][1] -= dely*fpair;
- f[j][2] -= delz*fpair;
-
- if (eflag) evdwl = VR + bij*VA;
- if (evflag) ev_tally(i,j,nlocal,newton_pair,
- evdwl,0.0,fpair,delx,dely,delz);
}
}
-}
-/* ----------------------------------------------------------------------
- compute LJ forces and energy
- find 3- and 4-step paths between atoms I,J via REBO neighbor lists
-------------------------------------------------------------------------- */
-
-void PairAIREBO::FLJ(int eflag, int vflag)
-{
- int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype,itag,jtag;
- int atomi,atomj,atomk,atomm;
- int testpath,npath,done;
- double evdwl,fpair,xtmp,ytmp,ztmp;
- double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
- double delij[3],rijsq,delik[3],rik,deljk[3];
- double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
- double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2;
- double rljmin,rljmax,sigcut,sigmin,sigwid;
- double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
- int *ilist,*jlist,*numneigh,**firstneigh;
- int *REBO_neighs_i,*REBO_neighs_k;
- double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3];
- double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
- double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
- double fpair1,fpair2,fpair3;
- double fi[3],fj[3],fk[3],fm[3];
-
- // I-J interaction from full neighbor list
- // skip 1/2 of interactions since only consider each pair once
+ // piRC forces
- evdwl = 0.0;
- rljmin = 0.0;
- rljmax = 0.0;
- sigcut = 0.0;
- sigmin = 0.0;
- sigwid = 0.0;
+ REBO_neighs = REBO_firstneigh[atomj];
+ for (l = 0; l < REBO_numneigh[atomj]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml !=atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+ (wjl*kronecker(jtype,1));
+ SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+ tmp2 = VA*dN3[1]*dwjl/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- double **x = atom->x;
- double **f = atom->f;
- int *tag = atom->tag;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int newton_pair = force->newton_pair;
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- inum = list->inum;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- // loop over neighbors of my atoms
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- itag = tag[i];
- itype = map[type[i]];
- atomi = i;
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- jlist = firstneigh[i];
- jnum = numneigh[i];
+ if (fabs(dNlj) > TOL) {
+ REBO_neighs_l = REBO_firstneigh[atoml];
+ for (n = 0; n < REBO_numneigh[atoml]; n++) {
+ atomn = REBO_neighs_l[n];
+ if (atomn != atomj) {
+ ntype = map[type[atomn]];
+ rln[0] = x[atoml][0]-x[atomn][0];
+ rln[1] = x[atoml][1]-x[atomn][1];
+ rln[2] = x[atoml][2]-x[atomn][2];
+ rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+ Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
- for (jj = 0; jj < jnum; jj++) {
- j = jlist[jj];
- j &= NEIGHMASK;
- jtag = tag[j];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
+ f[atoml][0] -= tmp2*rln[0];
+ f[atoml][1] -= tmp2*rln[1];
+ f[atoml][2] -= tmp2*rln[2];
+ f[atomn][0] += tmp2*rln[0];
+ f[atomn][1] += tmp2*rln[1];
+ f[atomn][2] += tmp2*rln[2];
- if (itag > jtag) {
- if ((itag+jtag) % 2 == 0) continue;
- } else if (itag < jtag) {
- if ((itag+jtag) % 2 == 1) continue;
- } else {
- if (x[j][2] < ztmp) continue;
- if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
- if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
+ }
+ }
}
+ }
+ }
- jtype = map[type[j]];
- atomj = j;
-
- delij[0] = xtmp - x[j][0];
- delij[1] = ytmp - x[j][1];
- delij[2] = ztmp - x[j][2];
- rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2];
+ Tij = 0.0;
+ dN3[0] = 0.0;
+ dN3[1] = 0.0;
+ dN3[2] = 0.0;
+ if (itype == 0 && jtype == 0)
+ Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3);
+ Etmp = 0.0;
- // if outside of LJ cutoff, skip
- // if outside of 4-path cutoff, best = 0.0, no need to test paths
- // if outside of 2-path cutoff but inside 4-path cutoff,
- // best = 0.0, test 3-,4-paths
- // if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1
-
- if (rijsq >= cutljsq[itype][jtype]) continue;
- rij = sqrt(rijsq);
- if (rij >= cut3rebo) {
- best = 0.0;
- testpath = 0;
- } else if (rij >= rcmax[itype][jtype]) {
- best = 0.0;
- testpath = 1;
- } else {
- best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
- npath = 2;
- if (best < 1.0) testpath = 1;
- else testpath = 0;
- }
+ if (fabs(Tij) > TOL) {
+ atom2 = atomi;
+ atom3 = atomj;
+ r32[0] = x[atom3][0]-x[atom2][0];
+ r32[1] = x[atom3][1]-x[atom2][1];
+ r32[2] = x[atom3][2]-x[atom2][2];
+ r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
+ r23[0] = -r32[0];
+ r23[1] = -r32[1];
+ r23[2] = -r32[2];
+ r23mag = r32mag;
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs_i[k];
+ atom1 = atomk;
+ ktype = map[type[atomk]];
+ if (atomk != atomj) {
+ r21[0] = x[atom2][0]-x[atom1][0];
+ r21[1] = x[atom2][1]-x[atom1][1];
+ r21[2] = x[atom2][2]-x[atom1][2];
+ r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
+ cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) /
+ (r21mag*r32mag);
+ cos321 = MIN(cos321,1.0);
+ cos321 = MAX(cos321,-1.0);
+ Sp2(cos321,thmin,thmax,dcut321);
+ sin321 = sqrt(1.0 - cos321*cos321);
+ sink2i = 1.0/(sin321*sin321);
+ rik2i = 1.0/(r21mag*r21mag);
+ if (sin321 != 0.0) {
+ rr = (r23mag*r23mag)-(r21mag*r21mag);
+ rjk[0] = r21[0]-r23[0];
+ rjk[1] = r21[1]-r23[1];
+ rjk[2] = r21[2]-r23[2];
+ rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+ rijrik = 2.0*r23mag*r21mag;
+ rik2 = r21mag*r21mag;
+ dctik = (-rr+rjk2)/(rijrik*rik2);
+ dctij = (rr+rjk2)/(rijrik*r23mag*r23mag);
+ dctjk = -2.0/rijrik;
+ w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
+ rijmag = r32mag;
+ rikmag = r21mag;
+ rij2 = r32mag*r32mag;
+ rik2 = r21mag*r21mag;
+ costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+ tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+ dtsjik = -dtsjik;
- done = 0;
- if (testpath) {
+ REBO_neighs_j = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs_j[l];
+ atom4 = atoml;
+ ltype = map[type[atoml]];
+ if (!(atoml == atomi || atoml == atomk)) {
+ r34[0] = x[atom3][0]-x[atom4][0];
+ r34[1] = x[atom3][1]-x[atom4][1];
+ r34[2] = x[atom3][2]-x[atom4][2];
+ r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2]));
+ cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) /
+ (r32mag*r34mag);
+ cos234 = MIN(cos234,1.0);
+ cos234 = MAX(cos234,-1.0);
+ sin234 = sqrt(1.0 - cos234*cos234);
+ sinl2i = 1.0/(sin234*sin234);
+ rjl2i = 1.0/(r34mag*r34mag);
- // test all 3-body paths = I-K-J
- // I-K interactions come from atom I's REBO neighbors
- // if wik > current best, compute wkj
- // if best = 1.0, done
+ if (sin234 != 0.0) {
+ w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34);
+ rr = (r23mag*r23mag)-(r34mag*r34mag);
+ ril[0] = r23[0]+r34[0];
+ ril[1] = r23[1]+r34[1];
+ ril[2] = r23[2]+r34[2];
+ ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+ rijrjl = 2.0*r23mag*r34mag;
+ rjl2 = r34mag*r34mag;
+ dctjl = (-rr+ril2)/(rijrjl*rjl2);
+ dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
+ dctil = -2.0/rijrjl;
+ rjlmag = r34mag;
+ rjl2 = r34mag*r34mag;
+ costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+ tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+ dtsijl = -dtsijl;
+ prefactor = VA*Tij;
- REBO_neighs_i = REBO_firstneigh[i];
- for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) {
- k = REBO_neighs_i[kk];
- if (k == j) continue;
- ktype = map[type[k]];
+ cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
+ cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
+ cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
+ cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
+ cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
+ cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
- delik[0] = x[i][0] - x[k][0];
- delik[1] = x[i][1] - x[k][1];
- delik[2] = x[i][2] - x[k][2];
- rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2];
- if (rsq < rcmaxsq[itype][ktype]) {
- rik = sqrt(rsq);
- wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- } else wik = 0.0;
+ cwnum = (cross321[0]*cross234[0]) +
+ (cross321[1]*cross234[1]) + (cross321[2]*cross234[2]);
+ cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
+ om1234 = cwnum/cwnom;
+ cw = om1234;
+ Etmp += ((1.0-(om1234*om1234))*w21*w34) *
+ (1.0-tspjik)*(1.0-tspijl);
- if (wik > best) {
- deljk[0] = x[j][0] - x[k][0];
- deljk[1] = x[j][1] - x[k][1];
- deljk[2] = x[j][2] - x[k][2];
- rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
- if (rsq < rcmaxsq[ktype][jtype]) {
- rkj = sqrt(rsq);
- wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj);
- if (wik*wkj > best) {
- best = wik*wkj;
- npath = 3;
- atomk = k;
- delikS[0] = delik[0];
- delikS[1] = delik[1];
- delikS[2] = delik[2];
- rikS = rik;
- wikS = wik;
- dwikS = dwik;
- deljkS[0] = deljk[0];
- deljkS[1] = deljk[1];
- deljkS[2] = deljk[2];
- rkjS = rkj;
- wkjS = wkj;
- dwkjS = dwkj;
- if (best == 1.0) {
- done = 1;
- break;
- }
- }
- }
+ dt1dik = (rik2i)-(dctik*sink2i*cos321);
+ dt1djk = (-dctjk*sink2i*cos321);
+ dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
+ dt1dil = (-dctil*sinl2i*cos234);
+ dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) -
+ (dctji*sinl2i*cos234);
- // test all 4-body paths = I-K-M-J
- // K-M interactions come from atom K's REBO neighbors
- // if wik*wkm > current best, compute wmj
- // if best = 1.0, done
+ dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
+ dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
+ dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
- REBO_neighs_k = REBO_firstneigh[k];
- for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) {
- m = REBO_neighs_k[mm];
- if (m == i || m == j) continue;
- mtype = map[type[m]];
- delkm[0] = x[k][0] - x[m][0];
- delkm[1] = x[k][1] - x[m][1];
- delkm[2] = x[k][2] - x[m][2];
- rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2];
- if (rsq < rcmaxsq[ktype][mtype]) {
- rkm = sqrt(rsq);
- wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm);
- } else wkm = 0.0;
+ dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
+ dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
+ dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
- if (wik*wkm > best) {
- deljm[0] = x[j][0] - x[m][0];
- deljm[1] = x[j][1] - x[m][1];
- deljm[2] = x[j][2] - x[m][2];
- rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] +
- deljm[2]*deljm[2];
- if (rsq < rcmaxsq[mtype][jtype]) {
- rmj = sqrt(rsq);
- wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj);
- if (wik*wkm*wmj > best) {
- best = wik*wkm*wmj;
- npath = 4;
- atomk = k;
- delikS[0] = delik[0];
- delikS[1] = delik[1];
- delikS[2] = delik[2];
- rikS = rik;
- wikS = wik;
- dwikS = dwik;
- atomm = m;
- delkmS[0] = delkm[0];
- delkmS[1] = delkm[1];
- delkmS[2] = delkm[2];
- rkmS = rkm;
- wkmS = wkm;
- dwkmS = dwkm;
- deljmS[0] = deljm[0];
- deljmS[1] = deljm[1];
- deljmS[2] = deljm[2];
- rmjS = rmj;
- wmjS = wmj;
- dwmjS = dwmj;
- if (best == 1.0) {
- done = 1;
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-
- cij = 1.0 - best;
- if (cij == 0.0) continue;
+ dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) -
+ (r21[1]*cross234[2])+(r34[1]*cross321[2]);
+ dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) -
+ (r21[2]*cross234[0])+(r34[2]*cross321[0]);
+ dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) -
+ (r21[0]*cross234[1])+(r34[0]*cross321[1]);
- // compute LJ forces and energy
+ aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
+ (1.0-tspjik)*(1.0-tspijl);
+ aaa1 = -prefactor*(1.0-(om1234*om1234)) *
+ (1.0-tspjik)*(1.0-tspijl);
+ aaa2 = aaa1*w21*w34;
+ at2 = aa*cwnum;
- sigwid = 0.84;
- sigcut = 3.0;
- sigmin = sigcut - sigwid;
-
- rljmin = sigma[itype][jtype];
- rljmax = sigcut * rljmin;
- rljmin = sigmin * rljmin;
-
- if (rij > rljmax){
- slw = 0.0;
- dslw = 0.0;}
- else if (rij > rljmin){
- drij = rij - rljmin;
- swidth = rljmax - rljmin;
- tee = drij / swidth;
- tee2 = pow (tee,2);
- slw = 1.0 - tee2 * (3.0 - 2.0 * tee);
- dslw = 6.0 * tee * (1.0 - tee) / rij / swidth;
- }
- else
- slw = 1.0;
- dslw = 0.0;
+ fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
+ (aaa2*dtsijl*dctji*(1.0-tspjik));
+ fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
+ fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
+ fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
+ fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
- r2inv = 1.0/rijsq;
- r6inv = r2inv*r2inv*r2inv;
+ F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
+ F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
+ F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
- vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
- dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij;
+ F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
+ F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
+ F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
- // VLJ now becomes vdw * slw, derivaties, etc.
-
- VLJ = vdw * slw;
- dVLJ = dvdw * slw + vdw * dslw;
-
- Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr);
- VA = Str*cij*VLJ;
- if (Str > 0.0) {
- scale = rcmin[itype][jtype] / rij;
- delscale[0] = scale * delij[0];
- delscale[1] = scale * delij[1];
- delscale[2] = scale * delij[2];
- Stb = bondorderLJ(i,j,delscale,rcmin[itype][jtype],VA,
- delij,rij,f,vflag_atom);
- } else Stb = 0.0;
-
- fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
- dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
-
- f[i][0] += delij[0]*fpair;
- f[i][1] += delij[1]*fpair;
- f[i][2] += delij[2]*fpair;
- f[j][0] -= delij[0]*fpair;
- f[j][1] -= delij[1]*fpair;
- f[j][2] -= delij[2]*fpair;
-
- if (eflag) evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
- if (evflag) ev_tally(i,j,nlocal,newton_pair,
- evdwl,0.0,fpair,delij[0],delij[1],delij[2]);
-
- if (cij < 1.0) {
- dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
- if (npath == 2) {
- fpair = dC*dwij / rij;
- f[atomi][0] += delij[0]*fpair;
- f[atomi][1] += delij[1]*fpair;
- f[atomi][2] += delij[2]*fpair;
- f[atomj][0] -= delij[0]*fpair;
- f[atomj][1] -= delij[1]*fpair;
- f[atomj][2] -= delij[2]*fpair;
-
- if (vflag_atom) v_tally2(atomi,atomj,fpair,delij);
-
- } else if (npath == 3) {
- fpair1 = dC*dwikS*wkjS / rikS;
- fi[0] = delikS[0]*fpair1;
- fi[1] = delikS[1]*fpair1;
- fi[2] = delikS[2]*fpair1;
- fpair2 = dC*wikS*dwkjS / rkjS;
- fj[0] = deljkS[0]*fpair2;
- fj[1] = deljkS[1]*fpair2;
- fj[2] = deljkS[2]*fpair2;
+ F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
+ F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
+ F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
- f[atomi][0] += fi[0];
- f[atomi][1] += fi[1];
- f[atomi][2] += fi[2];
- f[atomj][0] += fj[0];
- f[atomj][1] += fj[1];
- f[atomj][2] += fj[2];
- f[atomk][0] -= fi[0] + fj[0];
- f[atomk][1] -= fi[1] + fj[1];
- f[atomk][2] -= fi[2] + fj[2];
+ F31[0] = (fcjkpc*rjk[0]);
+ F31[1] = (fcjkpc*rjk[1]);
+ F31[2] = (fcjkpc*rjk[2]);
- if (vflag_atom)
- v_tally3(atomi,atomj,atomk,fi,fj,delikS,deljkS);
+ F24[0] = (fcilpc*ril[0]);
+ F24[1] = (fcilpc*ril[1]);
+ F24[2] = (fcilpc*ril[2]);
- } else {
- fpair1 = dC*dwikS*wkmS*wmjS / rikS;
- fi[0] = delikS[0]*fpair1;
- fi[1] = delikS[1]*fpair1;
- fi[2] = delikS[2]*fpair1;
+ f1[0] = -F12[0]-F31[0];
+ f1[1] = -F12[1]-F31[1];
+ f1[2] = -F12[2]-F31[2];
+ f2[0] = F23[0]+F12[0]+F24[0];
+ f2[1] = F23[1]+F12[1]+F24[1];
+ f2[2] = F23[2]+F12[2]+F24[2];
+ f3[0] = -F23[0]+F34[0]+F31[0];
+ f3[1] = -F23[1]+F34[1]+F31[1];
+ f3[2] = -F23[2]+F34[2]+F31[2];
+ f4[0] = -F34[0]-F24[0];
+ f4[1] = -F34[1]-F24[1];
+ f4[2] = -F34[2]-F24[2];
- fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
- fk[0] = delkmS[0]*fpair2 - fi[0];
- fk[1] = delkmS[1]*fpair2 - fi[1];
- fk[2] = delkmS[2]*fpair2 - fi[2];
+ // coordination forces
- fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
- fj[0] = deljmS[0]*fpair3;
- fj[1] = deljmS[1]*fpair3;
- fj[2] = deljmS[2]*fpair3;
+ tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+ (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
+ f2[0] -= tmp2*r21[0];
+ f2[1] -= tmp2*r21[1];
+ f2[2] -= tmp2*r21[2];
+ f1[0] += tmp2*r21[0];
+ f1[1] += tmp2*r21[1];
+ f1[2] += tmp2*r21[2];
- fm[0] = -delkmS[0]*fpair2 - fj[0];
- fm[1] = -delkmS[1]*fpair2 - fj[1];
- fm[2] = -delkmS[2]*fpair2 - fj[2];
+ tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+ (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
+ f3[0] -= tmp2*r34[0];
+ f3[1] -= tmp2*r34[1];
+ f3[2] -= tmp2*r34[2];
+ f4[0] += tmp2*r34[0];
+ f4[1] += tmp2*r34[1];
+ f4[2] += tmp2*r34[2];
- f[atomi][0] += fi[0];
- f[atomi][1] += fi[1];
- f[atomi][2] += fi[2];
- f[atomj][0] += fj[0];
- f[atomj][1] += fj[1];
- f[atomj][2] += fj[2];
- f[atomk][0] += fk[0];
- f[atomk][1] += fk[1];
- f[atomk][2] += fk[2];
- f[atomm][0] += fm[0];
- f[atomm][1] += fm[1];
- f[atomm][2] += fm[2];
+ f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
+ f[atom1][2] += f1[2];
+ f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
+ f[atom2][2] += f2[2];
+ f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
+ f[atom3][2] += f3[2];
+ f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
+ f[atom4][2] += f4[2];
- if (vflag_atom) {
- delimS[0] = delikS[0] + delkmS[0];
- delimS[1] = delikS[1] + delkmS[1];
- delimS[2] = delikS[2] + delkmS[2];
- v_tally4(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS);
+ if (vflag_atom) {
+ r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
+ r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
+ v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
+ }
+ }
+ }
}
}
- }
+ }
}
- }
-}
-
-/* ----------------------------------------------------------------------
- torsional forces and energy
-------------------------------------------------------------------------- */
-void PairAIREBO::TORSION(int eflag, int vflag)
-{
- int i,j,k,l,ii,inum,itag,jtag;
- double evdwl,fpair,xtmp,ytmp,ztmp;
- double cos321;
- double w21,dw21,cos234,w34,dw34;
- double cross321[3],cross321mag,cross234[3],cross234mag;
- double w23,dw23,cw2,ekijl,Ec;
- double cw,cwnum,cwnom;
- double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc;
- double sin321,sin234,rjk2,rik2,ril2,rjl2;
- double rjk,ril;
- double Vtors;
- double dndij[3],tmpvec[3],dndik[3],dndjl[3];
- double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil;
- double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil;
- double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
- double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
- double del32[3],rsq,r32,del23[3],del21[3],r21;
- double deljk[3],del34[3],delil[3],delkl[3],r23,r34;
- double fi[3],fj[3],fk[3],fl[3];
- int itype,jtype,ktype,ltype,kk,ll,jj;
- int *ilist,*REBO_neighs_i,*REBO_neighs_j;
-
- double **x = atom->x;
- double **f = atom->f;
- int *type = atom->type;
- int *tag = atom->tag;
-
- inum = list->inum;
- ilist = list->ilist;
-
- for (ii = 0; ii < inum; ii++) {
- i = ilist[ii];
- itag = tag[i];
- itype = map[type[i]];
- if (itype != 0) continue;
- xtmp = x[i][0];
- ytmp = x[i][1];
- ztmp = x[i][2];
- REBO_neighs_i = REBO_firstneigh[i];
-
- for (jj = 0; jj < REBO_numneigh[i]; jj++) {
- j = REBO_neighs_i[jj];
- jtag = tag[j];
-
- if (itag > jtag) {
- if ((itag+jtag) % 2 == 0) continue;
- } else if (itag < jtag) {
- if ((itag+jtag) % 2 == 1) continue;
- } else {
- if (x[j][2] < ztmp) continue;
- if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
- if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
- }
+ // Tij forces now that we have Etmp
- jtype = map[type[j]];
- if (jtype != 0) continue;
+ REBO_neighs = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs[k];
+ if (atomk != atomj) {
+ ktype = map[type[atomk]];
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+ Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+ (wik*kronecker(itype,1));
+ SpN = Sp(Nki,Nmin,Nmax,dNki);
- del32[0] = x[j][0]-x[i][0];
- del32[1] = x[j][1]-x[i][1];
- del32[2] = x[j][2]-x[i][2];
- rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2];
- r32 = sqrt(rsq);
- del23[0] = -del32[0];
- del23[1] = -del32[1];
- del23[2] = -del32[2];
- r23 = r32;
- w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23);
+ tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- for (kk = 0; kk < REBO_numneigh[i]; kk++) {
- k = REBO_neighs_i[kk];
- ktype = map[type[k]];
- if (k == j) continue;
- del21[0] = x[i][0]-x[k][0];
- del21[1] = x[i][1]-x[k][1];
- del21[2] = x[i][2]-x[k][2];
- rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2];
- r21 = sqrt(rsq);
- cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) +
- (del21[2]*del32[2])) / (r21*r32);
- cos321 = MIN(cos321,1.0);
- cos321 = MAX(cos321,-1.0);
- sin321 = sqrt(1.0 - cos321*cos321);
- if (sin321 < TOL) continue;
-
- deljk[0] = del21[0]-del23[0];
- deljk[1] = del21[1]-del23[1];
- deljk[2] = del21[2]-del23[2];
- rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
- rjk=sqrt(rjk2);
- rik2 = r21*r21;
- w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21);
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- rij = r32;
- rik = r21;
- rij2 = r32*r32;
- rik2 = r21*r21;
- costmp = 0.5*(rij2+rik2-rjk2)/rij/rik;
- tspjik = Sp2(costmp,thmin,thmax,dtsjik);
- dtsjik = -dtsjik;
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- REBO_neighs_j = REBO_firstneigh[j];
- for (ll = 0; ll < REBO_numneigh[j]; ll++) {
- l = REBO_neighs_j[ll];
- ltype = map[type[l]];
- if (l == i || l == k) continue;
- del34[0] = x[j][0]-x[l][0];
- del34[1] = x[j][1]-x[l][1];
- del34[2] = x[j][2]-x[l][2];
- rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2];
- r34 = sqrt(rsq);
- cos234 = (del32[0]*del34[0] + del32[1]*del34[1] +
- del32[2]*del34[2]) / (r32*r34);
- cos234 = MIN(cos234,1.0);
- cos234 = MAX(cos234,-1.0);
- sin234 = sqrt(1.0 - cos234*cos234);
- if (sin234 < TOL) continue;
- w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34);
- delil[0] = del23[0] + del34[0];
- delil[1] = del23[1] + del34[1];
- delil[2] = del23[2] + del34[2];
- ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2];
- ril=sqrt(ril2);
- rjl2 = r34*r34;
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- rjl = r34;
- rjl2 = r34*r34;
- costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl;
- tspijl = Sp2(costmp,thmin,thmax,dtsijl);
- dtsijl = -dtsijl; //need minus sign
- cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]);
- cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]);
- cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]);
- cross321mag = sqrt(cross321[0]*cross321[0]+
- cross321[1]*cross321[1]+
- cross321[2]*cross321[2]);
- cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]);
- cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]);
- cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]);
- cross234mag = sqrt(cross234[0]*cross234[0]+
- cross234[1]*cross234[1]+
- cross234[2]*cross234[2]);
- cwnum = (cross321[0]*cross234[0]) +
- (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
- cwnom = r21*r34*r32*r32*sin321*sin234;
- cw = cwnum/cwnom;
-
- cw2 = (.5*(1.0-cw));
- ekijl = epsilonT[ktype][ltype];
- Ec = 256.0*ekijl/405.0;
- Vtors = (Ec*(pow(cw2,5.0)))-(ekijl/10.0);
+ if (fabs(dNki) > TOL) {
+ REBO_neighs_k = REBO_firstneigh[atomk];
+ for (n = 0; n < REBO_numneigh[atomk]; n++) {
+ atomn = REBO_neighs_k[n];
+ ntype = map[type[atomn]];
+ if (atomn != atomi) {
+ rkn[0] = x[atomk][0]-x[atomn][0];
+ rkn[1] = x[atomk][1]-x[atomn][1];
+ rkn[2] = x[atomk][2]-x[atomn][2];
+ rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+ Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
- if (eflag) evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
-
- dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
- dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
- dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]);
-
- tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]);
- tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]);
- tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]);
-
- dndij[0] = dndij[0]+tmpvec[0];
- dndij[1] = dndij[1]+tmpvec[1];
- dndij[2] = dndij[2]+tmpvec[2];
-
- dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]);
- dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]);
- dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]);
-
- dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]);
- dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]);
- dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]);
-
- dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21);
- dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21);
- dcidjk = (-rjk)/(r23*r21);
- dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34);
- dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34);
- dcjdil = (-ril)/(r23*r34);
-
- dsidij = (-cos321/sin321)*dcidij;
- dsidik = (-cos321/sin321)*dcidik;
- dsidjk = (-cos321/sin321)*dcidjk;
-
- dsjdji = (-cos234/sin234)*dcjdji;
- dsjdjl = (-cos234/sin234)*dcjdjl;
- dsjdil = (-cos234/sin234)*dcjdil;
-
- dxidij = (r21*sin321)+(r23*r21*dsidij);
- dxidik = (r23*sin321)+(r23*r21*dsidik);
- dxidjk = (r23*r21*dsidjk);
-
- dxjdji = (r34*sin234)+(r23*r34*dsjdji);
- dxjdjl = (r23*sin234)+(r23*r34*dsjdjl);
- dxjdil = (r23*r34*dsjdil);
-
- ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji);
- ddndik = dxidik*cross234mag;
- ddndjk = dxidjk*cross234mag;
- ddndjl = cross321mag*dxjdjl;
- ddndil = cross321mag*dxjdil;
- dcwddn = -cwnum/(cwnom*cwnom);
- dcwdn = 1.0/cwnom;
- dvpdcw = (-1.0)*Ec*(-.5)*5.0*pow(cw2,4.0) *
- w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
+ f[atomk][0] -= tmp2*rkn[0];
+ f[atomk][1] -= tmp2*rkn[1];
+ f[atomk][2] -= tmp2*rkn[2];
+ f[atomn][0] += tmp2*rkn[0];
+ f[atomn][1] += tmp2*rkn[1];
+ f[atomn][2] += tmp2*rkn[2];
- Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
- Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
- Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
- fi[0] = Ftmp[0];
- fi[1] = Ftmp[1];
- fi[2] = Ftmp[2];
- fj[0] = -Ftmp[0];
- fj[1] = -Ftmp[1];
- fj[2] = -Ftmp[2];
-
- Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
- Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
- Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
- fi[0] += Ftmp[0];
- fi[1] += Ftmp[1];
- fi[2] += Ftmp[2];
- fk[0] = -Ftmp[0];
- fk[1] = -Ftmp[1];
- fk[2] = -Ftmp[2];
-
- Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
- Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
- Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
- fj[0] += Ftmp[0];
- fj[1] += Ftmp[1];
- fj[2] += Ftmp[2];
- fk[0] -= Ftmp[0];
- fk[1] -= Ftmp[1];
- fk[2] -= Ftmp[2];
-
- Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
- Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
- Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
- fj[0] += Ftmp[0];
- fj[1] += Ftmp[1];
- fj[2] += Ftmp[2];
- fl[0] = -Ftmp[0];
- fl[1] = -Ftmp[1];
- fl[2] = -Ftmp[2];
-
- Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
- Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
- Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
- fi[0] += Ftmp[0];
- fi[1] += Ftmp[1];
- fi[2] += Ftmp[2];
- fl[0] -= Ftmp[0];
- fl[1] -= Ftmp[1];
- fl[2] -= Ftmp[2];
-
- // coordination forces
-
- fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
- fi[0] -= del21[0]*fpair;
- fi[1] -= del21[1]*fpair;
- fi[2] -= del21[2]*fpair;
- fk[0] += del21[0]*fpair;
- fk[1] += del21[1]*fpair;
- fk[2] += del21[2]*fpair;
-
- fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
- fi[0] -= del23[0]*fpair;
- fi[1] -= del23[1]*fpair;
- fi[2] -= del23[2]*fpair;
- fj[0] += del23[0]*fpair;
- fj[1] += del23[1]*fpair;
- fj[2] += del23[2]*fpair;
-
- fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
- fj[0] -= del34[0]*fpair;
- fj[1] -= del34[1]*fpair;
- fj[2] -= del34[2]*fpair;
- fl[0] += del34[0]*fpair;
- fl[1] += del34[1]*fpair;
- fl[2] += del34[2]*fpair;
+ if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+ }
+ }
+ }
+ }
+ }
- // additional cut off function forces
+ // Tij forces
- fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
- fpair = fcpc*dcidij/rij;
- fi[0] += fpair*del23[0];
- fi[1] += fpair*del23[1];
- fi[2] += fpair*del23[2];
- fj[0] -= fpair*del23[0];
- fj[1] -= fpair*del23[1];
- fj[2] -= fpair*del23[2];
+ REBO_neighs = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml != atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+ (wjl*kronecker(jtype,1));
+ SpN = Sp(Nlj,Nmin,Nmax,dNlj);
- fpair = fcpc*dcidik/rik;
- fi[0] += fpair*del21[0];
- fi[1] += fpair*del21[1];
- fi[2] += fpair*del21[2];
- fk[0] -= fpair*del21[0];
- fk[1] -= fpair*del21[1];
- fk[2] -= fpair*del21[2];
+ tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- fpair = fcpc*dcidjk/rjk;
- fj[0] += fpair*deljk[0];
- fj[1] += fpair*deljk[1];
- fj[2] += fpair*deljk[2];
- fk[0] -= fpair*deljk[0];
- fk[1] -= fpair*deljk[1];
- fk[2] -= fpair*deljk[2];
-
- fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
- fpair = fcpc*dcjdji/rij;
- fi[0] += fpair*del23[0];
- fi[1] += fpair*del23[1];
- fi[2] += fpair*del23[2];
- fj[0] -= fpair*del23[0];
- fj[1] -= fpair*del23[1];
- fj[2] -= fpair*del23[2];
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- fpair = fcpc*dcjdjl/rjl;
- fj[0] += fpair*del34[0];
- fj[1] += fpair*del34[1];
- fj[2] += fpair*del34[2];
- fl[0] -= fpair*del34[0];
- fl[1] -= fpair*del34[1];
- fl[2] -= fpair*del34[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- fpair = fcpc*dcjdil/ril;
- fi[0] += fpair*delil[0];
- fi[1] += fpair*delil[1];
- fi[2] += fpair*delil[2];
- fl[0] -= fpair*delil[0];
- fl[1] -= fpair*delil[1];
- fl[2] -= fpair*delil[2];
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- // sum per-atom forces into atom force array
+ if (fabs(dNlj) > TOL) {
+ REBO_neighs_l = REBO_firstneigh[atoml];
+ for (n = 0; n < REBO_numneigh[atoml]; n++) {
+ atomn = REBO_neighs_l[n];
+ ntype = map[type[atomn]];
+ if (atomn !=atomj) {
+ rln[0] = x[atoml][0]-x[atomn][0];
+ rln[1] = x[atoml][1]-x[atomn][1];
+ rln[2] = x[atoml][2]-x[atomn][2];
+ rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+ Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
- f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
- f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
- f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
- f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
+ f[atoml][0] -= tmp2*rln[0];
+ f[atoml][1] -= tmp2*rln[1];
+ f[atoml][2] -= tmp2*rln[2];
+ f[atomn][0] += tmp2*rln[0];
+ f[atomn][1] += tmp2*rln[1];
+ f[atomn][2] += tmp2*rln[2];
- if (evflag) {
- delkl[0] = delil[0] - del21[0];
- delkl[1] = delil[1] - del21[1];
- delkl[2] = delil[2] - del21[2];
- ev_tally4(i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl);
+ if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
+ }
}
}
}
}
}
+
+ bij = (0.5*(pij+pji))+piRC+(Tij*Etmp);
+ return bij;
}
/* ----------------------------------------------------------------------
- Bij function
+ Bij* function
------------------------------------------------------------------------- */
-double PairAIREBO::bondorder(int i, int j, double rij[3],
- double rijmag, double VA,
- double **f, int vflag_atom)
+double PairAIREBOOMP::bondorderLJ_thr(int i, int j, double rij[3], double rijmag,
+ double VA, double rij0[3], double rij0mag,
+ int vflag_atom, ThrData * const thr)
{
- int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
- int itype,jtype,ktype,ltype,ntype;
- double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij;
+ int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
+ int atomi,atomj,itype,jtype,ktype,ltype,ntype;
+ double rik[3], rjl[3], rkn[3],rknmag,dNki;
double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
- double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS;
- double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
+ double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ;
+ double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
double dN2[2],dN3[3];
- double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3];
- double Tij;
- double r32[3],r32mag,cos321,r43[3],r13[3];
- double dNlj;
+ double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl;
+ double Tij,crosskij[3],crosskijmag;
+ double crossijl[3],crossijlmag,omkijl;
+ double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3];
+ double bij,tmp3pij,tmp3pji,Stb,dStb;
+ double r32[3],r32mag,cos321;
double om1234,rln[3];
double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
double cross321[3],cross234[3],prefactor,SpN;
double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
- double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3];
- double f1[3],f2[3],f3[3],f4[4];
- double dcut321,PijS,PjiS;
+ double dNlj;
+ double PijS,PjiS;
double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
+ double F12[3],F23[3],F34[3],F31[3],F24[3];
+ double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4];
+ double rji[3],rki[3],rlj[3],r13[3],r43[3];
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
- double **x = atom->x;
- int *type = atom->type;
-
atomi = i;
atomj = j;
- itype = map[type[i]];
- jtype = map[type[j]];
- wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
- NijC = nC[i]-(wij*kronecker(jtype,0));
- NijH = nH[i]-(wij*kronecker(jtype,1));
- NjiC = nC[j]-(wij*kronecker(itype,0));
- NjiH = nH[j]-(wij*kronecker(itype,1));
+ itype = map[type[atomi]];
+ jtype = map[type[atomj]];
+ wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+ NijC = nC[atomi]-(wij*kronecker(jtype,0));
+ NijH = nH[atomi]-(wij*kronecker(jtype,1));
+ NjiC = nC[atomj]-(wij*kronecker(itype,0));
+ NjiH = nH[atomj]-(wij*kronecker(itype,1));
+
bij = 0.0;
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
dgdc = 0.0;
dgdN = 0.0;
NconjtmpI = 0.0;
NconjtmpJ = 0.0;
Etmp = 0.0;
-
+
REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
atomk = REBO_neighs[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- lamdajik = 4.0*kronecker(itype,1) *
+ lamdajik = 4.0*kronecker(itype,1) *
((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
- Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
- (wik*kronecker(itype,1));
- cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+ Nki = nC[atomk]-(wik*kronecker(itype,0)) +
+ nH[atomk]-(wik*kronecker(itype,1));
+ cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
(rijmag*rikmag);
cosjik = MIN(cosjik,1.0);
cosjik = MAX(cosjik,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
- Etmp = Etmp+(wik*g*exp(lamdajik));
+ Etmp = Etmp+(wik*g*exp(lamdajik));
tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
}
}
PijS = 0.0;
- dN2[0] = 0.0;
- dN2[1] = 0.0;
- PijS = PijSpline(NijC,NijH,itype,jtype,dN2);
- pij = pow(1.0+Etmp+PijS,-0.5);
- tmp = -0.5*pow(pij,3.0);
-
- // pij forces
-
- REBO_neighs = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs[k];
- if (atomk != atomj) {
- ktype = map[type[atomk]];
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- lamdajik = 4.0*kronecker(itype,1) *
- ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) /
- (rijmag*rikmag);
- cosjik = MIN(cosjik,1.0);
- cosjik = MAX(cosjik,-1.0);
-
- dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) -
- (cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag))));
- dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) -
- (cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag))));
- dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) -
- (cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag))));
- dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) +
- (cosjik*(rik[0]/(rikmag*rikmag)));
- dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) +
- (cosjik*(rik[1]/(rikmag*rikmag)));
- dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) +
- (cosjik*(rik[2]/(rikmag*rikmag)));
- dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) +
- (cosjik*(rij[0]/(rijmag*rijmag)));
- dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) +
- (cosjik*(rij[1]/(rijmag*rijmag)));
- dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) +
- (cosjik*(rij[2]/(rijmag*rijmag)));
-
- g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
- tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
- fj[0] = -tmp2*dcosjikdrj[0];
- fj[1] = -tmp2*dcosjikdrj[1];
- fj[2] = -tmp2*dcosjikdrj[2];
- fi[0] = -tmp2*dcosjikdri[0];
- fi[1] = -tmp2*dcosjikdri[1];
- fi[2] = -tmp2*dcosjikdri[2];
- fk[0] = -tmp2*dcosjikdrk[0];
- fk[1] = -tmp2*dcosjikdrk[1];
- fk[2] = -tmp2*dcosjikdrk[2];
-
- tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
- fj[0] -= tmp2*(-rij[0]/rijmag);
- fj[1] -= tmp2*(-rij[1]/rijmag);
- fj[2] -= tmp2*(-rij[2]/rijmag);
- fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag));
- fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag));
- fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag));
- fk[0] -= tmp2*(rik[0]/rikmag);
- fk[1] -= tmp2*(rik[1]/rikmag);
- fk[2] -= tmp2*(rik[2]/rikmag);
-
- // coordination forces
-
- // dwik forces
-
- tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
-
- // PIJ forces
-
- tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
-
- // dgdN forces
-
- tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
-
- f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
- f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
- f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
-
- if (vflag_atom) {
- rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
- rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
- v_tally3(atomi,atomj,atomk,fj,fk,rji,rki);
- }
- }
- }
-
+ dN2PIJ[0] = 0.0;
+ dN2PIJ[1] = 0.0;
+ PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ);
+ pij = 1.0/sqrt(1.0+Etmp+PijS);
+ tmppij = -.5*pij*pij*pij;
+ tmp3pij = tmp3;
tmp = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
Etmp = 0.0;
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- lamdaijl = 4.0*kronecker(jtype,1) *
+ lamdaijl = 4.0*kronecker(jtype,1) *
((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) +
- nH[atoml]-(wjl*kronecker(jtype,1));
- cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+ (wjl*kronecker(jtype,1));
+ cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
(rijmag*rjlmag);
cosijl = MIN(cosijl,1.0);
cosijl = MAX(cosijl,-1.0);
// evaluate splines g and derivatives dg
g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
- Etmp = Etmp+(wjl*g*exp(lamdaijl));
- tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
+ Etmp = Etmp+(wjl*g*exp(lamdaijl));
+ tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
}
}
PjiS = 0.0;
- dN2[0] = 0.0;
- dN2[1] = 0.0;
- PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2);
- pji = pow(1.0+Etmp+PjiS,-0.5);
- tmp = -0.5*pow(pji,3.0);
+ dN2PJI[0] = 0.0;
+ dN2PJI[1] = 0.0;
+ PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI);
+ pji = 1.0/sqrt(1.0+Etmp+PjiS);
+ tmppji = -.5*pji*pji*pji;
+ tmp3pji = tmp3;
- REBO_neighs = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs[l];
- if (atoml != atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- lamdaijl = 4.0*kronecker(jtype,1) *
- ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) /
- (rijmag*rjlmag);
- cosijl = MIN(cosijl,1.0);
- cosijl = MAX(cosijl,-1.0);
+ // evaluate Nij conj
- dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) -
- (cosijl*rij[0]/(rijmag*rijmag));
- dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) -
- (cosijl*rij[1]/(rijmag*rijmag));
- dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) -
- (cosijl*rij[2]/(rijmag*rijmag));
- dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) +
- (cosijl*((rij[0]/pow(rijmag,2.0))-(rjl[0]/(rjlmag*rjlmag))));
- dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) +
- (cosijl*((rij[1]/pow(rijmag,2.0))-(rjl[1]/(rjlmag*rjlmag))));
- dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) +
- (cosijl*((rij[2]/pow(rijmag,2.0))-(rjl[2]/(rjlmag*rjlmag))));
- dcosijldrl[0] = (rij[0]/(rijmag*rjlmag))+(cosijl*rjl[0]/(rjlmag*rjlmag));
- dcosijldrl[1] = (rij[1]/(rijmag*rjlmag))+(cosijl*rjl[1]/(rjlmag*rjlmag));
- dcosijldrl[2] = (rij[2]/(rijmag*rjlmag))+(cosijl*rjl[2]/(rjlmag*rjlmag));
+ Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
+ piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC);
+ Tij = 0.0;
+ dN3Tij[0] = 0.0;
+ dN3Tij[1] = 0.0;
+ dN3Tij[2] = 0.0;
+ if (itype == 0 && jtype == 0)
+ Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij);
- // evaluate splines g and derivatives dg
+ Etmp = 0.0;
+ if (fabs(Tij) > TOL) {
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs_i[k];
+ ktype = map[type[atomk]];
+ if (atomk != atomj) {
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+ (rijmag*rikmag);
+ cos321 = MIN(cos321,1.0);
+ cos321 = MAX(cos321,-1.0);
- g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
- tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
- fi[0] = -tmp2*dcosijldri[0];
- fi[1] = -tmp2*dcosijldri[1];
- fi[2] = -tmp2*dcosijldri[2];
- fj[0] = -tmp2*dcosijldrj[0];
- fj[1] = -tmp2*dcosijldrj[1];
- fj[2] = -tmp2*dcosijldrj[2];
- fl[0] = -tmp2*dcosijldrl[0];
- fl[1] = -tmp2*dcosijldrl[1];
- fl[2] = -tmp2*dcosijldrl[2];
+ rjk[0] = rik[0]-rij[0];
+ rjk[1] = rik[1]-rij[1];
+ rjk[2] = rik[2]-rij[2];
+ rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+ rij2 = rijmag*rijmag;
+ rik2 = rikmag*rikmag;
+ costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+ tspjik = Sp2(costmp,thmin,thmax,dtsjik);
- tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
- fi[0] -= tmp2*(rij[0]/rijmag);
- fi[1] -= tmp2*(rij[1]/rijmag);
- fi[2] -= tmp2*(rij[2]/rijmag);
- fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag));
- fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag));
- fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag));
- fl[0] -= tmp2*(rjl[0]/rjlmag);
- fl[1] -= tmp2*(rjl[1]/rjlmag);
- fl[2] -= tmp2*(rjl[2]/rjlmag);
+ if (sqrt(1.0 - cos321*cos321) != 0.0) {
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik);
+ REBO_neighs_j = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs_j[l];
+ ltype = map[type[atoml]];
+ if (!(atoml == atomi || atoml == atomk)) {
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]);
+ cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+ (rijmag*rjlmag);
+ cos234 = MIN(cos234,1.0);
+ cos234 = MAX(cos234,-1.0);
+
+ ril[0] = rij[0]+rjl[0];
+ ril[1] = rij[1]+rjl[1];
+ ril[2] = rij[2]+rjl[2];
+ ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+ rijrjl = 2.0*rijmag*rjlmag;
+ rjl2 = rjlmag*rjlmag;
+ costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+ tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+
+ if (sqrt(1.0 - cos234*cos234) != 0.0) {
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS);
+ crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]);
+ crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]);
+ crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]);
+ crosskijmag = sqrt(crosskij[0]*crosskij[0] +
+ crosskij[1]*crosskij[1] +
+ crosskij[2]*crosskij[2]);
+ crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]);
+ crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]);
+ crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]);
+ crossijlmag = sqrt(crossijl[0]*crossijl[0] +
+ crossijl[1]*crossijl[1] +
+ crossijl[2]*crossijl[2]);
+ omkijl = -1.0*(((crosskij[0]*crossijl[0]) +
+ (crosskij[1]*crossijl[1]) +
+ (crosskij[2]*crossijl[2])) /
+ (crosskijmag*crossijlmag));
+ Etmp += ((1.0-(omkijl*omkijl))*wik*wjl) *
+ (1.0-tspjik)*(1.0-tspijl);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bij = (.5*(pij+pji))+piRC+(Tij*Etmp);
+ Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb);
+ VA = VA*dStb;
+
+ if (dStb != 0.0) {
+ tmp = tmppij;
+ dN2[0] = dN2PIJ[0];
+ dN2[1] = dN2PIJ[1];
+ tmp3 = tmp3pij;
+
+ const double invrijm = 1.0/rijmag;
+ const double invrijm2 = invrijm*invrijm;
- // coordination forces
-
- // dwik forces
+ // pij forces
- tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs_i[k];
+ if (atomk != atomj) {
+ lamdajik = 0.0;
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]);
+ lamdajik = 4.0*kronecker(itype,1) *
+ ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- // PIJ forces
+ const double invrikm = 1.0/rikmag;
+ const double invrijkm = invrijm*invrikm;
+ const double invrikm2 = invrikm*invrikm;
- tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2]))
+ * invrijkm;
+ cosjik = MIN(cosjik,1.0);
+ cosjik = MAX(cosjik,-1.0);
- // dgdN forces
+ dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) -
+ (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2)));
+ dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) -
+ (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2)));
+ dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) -
+ (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2)));
+ dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2));
+ dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2));
+ dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2));
+ dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2));
+ dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2));
+ dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2));
- tmp2 = VA*.5*(tmp*tmp3*dwjl)/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
- f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
- f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
- f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
+ tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
+ fj[0] = -tmp2*dcosjikdrj[0];
+ fj[1] = -tmp2*dcosjikdrj[1];
+ fj[2] = -tmp2*dcosjikdrj[2];
+ fi[0] = -tmp2*dcosjikdri[0];
+ fi[1] = -tmp2*dcosjikdri[1];
+ fi[2] = -tmp2*dcosjikdri[2];
+ fk[0] = -tmp2*dcosjikdrk[0];
+ fk[1] = -tmp2*dcosjikdrk[1];
+ fk[2] = -tmp2*dcosjikdrk[2];
- if (vflag_atom) {
- rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
- v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj);
- }
- }
- }
-
- // evaluate Nij conj
+ tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
+ fj[0] -= tmp2*(-rij[0]*invrijm);
+ fj[1] -= tmp2*(-rij[1]*invrijm);
+ fj[2] -= tmp2*(-rij[2]*invrijm);
+ fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]*invrijm));
+ fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]*invrijm));
+ fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]*invrijm));
+ fk[0] -= tmp2*(rik[0]/rikmag);
+ fk[1] -= tmp2*(rik[1]/rikmag);
+ fk[2] -= tmp2*(rik[2]/rikmag);
- Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
- piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3);
-
- // piRC forces
+ // coordination forces
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- if (atomk !=atomj) {
- ktype = map[type[atomk]];
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
- (wik*kronecker(itype,1));
- SpN = Sp(Nki,Nmin,Nmax,dNki);
+ // dwik forces
- tmp2 = VA*dN3[0]*dwik/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ // PIJ forces
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ // dgdN forces
- if (fabs(dNki) > TOL) {
- REBO_neighs_k = REBO_firstneigh[atomk];
- for (n = 0; n < REBO_numneigh[atomk]; n++) {
- atomn = REBO_neighs_k[n];
- if (atomn != atomi) {
- ntype = map[type[atomn]];
- rkn[0] = x[atomk][0]-x[atomn][0];
- rkn[1] = x[atomk][1]-x[atomn][1];
- rkn[2] = x[atomk][2]-x[atomn][2];
- rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
- Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+ tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
+ fi[0] -= tmp2*rik[0];
+ fi[1] -= tmp2*rik[1];
+ fi[2] -= tmp2*rik[2];
+ fk[0] += tmp2*rik[0];
+ fk[1] += tmp2*rik[1];
+ fk[2] += tmp2*rik[2];
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
- f[atomk][0] -= tmp2*rkn[0];
- f[atomk][1] -= tmp2*rkn[1];
- f[atomk][2] -= tmp2*rkn[2];
- f[atomn][0] += tmp2*rkn[0];
- f[atomn][1] += tmp2*rkn[1];
- f[atomn][2] += tmp2*rkn[2];
+ f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+ f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
- if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
- }
+ if (vflag_atom) {
+ rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
+ rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
+ v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
}
- }
+ }
}
- }
-
- // piRC forces
- REBO_neighs = REBO_firstneigh[atomj];
- for (l = 0; l < REBO_numneigh[atomj]; l++) {
- atoml = REBO_neighs[l];
- if (atoml !=atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
- (wjl*kronecker(jtype,1));
- SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+ tmp = tmppji;
+ tmp3 = tmp3pji;
+ dN2[0] = dN2PJI[0];
+ dN2[1] = dN2PJI[1];
+ REBO_neighs = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml !=atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ lamdaijl = 4.0*kronecker(jtype,1) *
+ ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- tmp2 = VA*dN3[1]*dwjl/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ const double invrjlm = 1.0/rjlmag;
+ const double invrijlm = invrijm*invrjlm;
+ const double invrjlm2 = invrjlm*invrjlm;
+
+ cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) *
+ invrijlm;
+ cosijl = MIN(cosijl,1.0);
+ cosijl = MAX(cosijl,-1.0);
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2);
+ dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2);
+ dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2);
+ dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) +
+ (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2)));
+ dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) +
+ (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2)));
+ dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) +
+ (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2)));
+ dcosijldrl[0] = (rij[0]*invrijlm) + (cosijl*rjl[0]*invrjlm2);
+ dcosijldrl[1] = (rij[1]*invrijlm) + (cosijl*rjl[1]*invrjlm2);
+ dcosijldrl[2] = (rij[2]*invrijlm) + (cosijl*rjl[2]*invrjlm2);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ // evaluate splines g and derivatives dg
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+ tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
+ fi[0] = -tmp2*dcosijldri[0];
+ fi[1] = -tmp2*dcosijldri[1];
+ fi[2] = -tmp2*dcosijldri[2];
+ fj[0] = -tmp2*dcosijldrj[0];
+ fj[1] = -tmp2*dcosijldrj[1];
+ fj[2] = -tmp2*dcosijldrj[2];
+ fl[0] = -tmp2*dcosijldrl[0];
+ fl[1] = -tmp2*dcosijldrl[1];
+ fl[2] = -tmp2*dcosijldrl[2];
- if (fabs(dNlj) > TOL) {
- REBO_neighs_l = REBO_firstneigh[atoml];
- for (n = 0; n < REBO_numneigh[atoml]; n++) {
- atomn = REBO_neighs_l[n];
- if (atomn != atomj) {
- ntype = map[type[atomn]];
- rln[0] = x[atoml][0]-x[atomn][0];
- rln[1] = x[atoml][1]-x[atomn][1];
- rln[2] = x[atoml][2]-x[atomn][2];
- rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
- Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+ tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
+ fi[0] -= tmp2*(rij[0]*invrijm);
+ fi[1] -= tmp2*(rij[1]*invrijm);
+ fi[2] -= tmp2*(rij[2]*invrijm);
+ fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm));
+ fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm));
+ fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm));
+ fl[0] -= tmp2*(rjl[0]*invrjlm);
+ fl[1] -= tmp2*(rjl[1]*invrjlm);
+ fl[2] -= tmp2*(rjl[2]*invrjlm);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
- f[atoml][0] -= tmp2*rln[0];
- f[atoml][1] -= tmp2*rln[1];
- f[atoml][2] -= tmp2*rln[2];
- f[atomn][0] += tmp2*rln[0];
- f[atomn][1] += tmp2*rln[1];
- f[atomn][2] += tmp2*rln[2];
-
- if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
- }
- }
- }
- }
- }
-
- Tij = 0.0;
- dN3[0] = 0.0;
- dN3[1] = 0.0;
- dN3[2] = 0.0;
- if (itype == 0 && jtype == 0)
- Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3);
- Etmp = 0.0;
+ // coordination forces
+ // dwik forces
- if (fabs(Tij) > TOL) {
- atom2 = atomi;
- atom3 = atomj;
- r32[0] = x[atom3][0]-x[atom2][0];
- r32[1] = x[atom3][1]-x[atom2][1];
- r32[2] = x[atom3][2]-x[atom2][2];
- r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
- r23[0] = -r32[0];
- r23[1] = -r32[1];
- r23[2] = -r32[2];
- r23mag = r32mag;
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- atom1 = atomk;
- ktype = map[type[atomk]];
- if (atomk != atomj) {
- r21[0] = x[atom2][0]-x[atom1][0];
- r21[1] = x[atom2][1]-x[atom1][1];
- r21[2] = x[atom2][2]-x[atom1][2];
- r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
- cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) /
- (r21mag*r32mag);
- cos321 = MIN(cos321,1.0);
- cos321 = MAX(cos321,-1.0);
- Sp2(cos321,thmin,thmax,dcut321);
- sin321 = sqrt(1.0 - cos321*cos321);
- sink2i = 1.0/(sin321*sin321);
- rik2i = 1.0/(r21mag*r21mag);
- if (sin321 != 0.0) {
- rr = (r23mag*r23mag)-(r21mag*r21mag);
- rjk[0] = r21[0]-r23[0];
- rjk[1] = r21[1]-r23[1];
- rjk[2] = r21[2]-r23[2];
- rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
- rijrik = 2.0*r23mag*r21mag;
- rik2 = r21mag*r21mag;
- dctik = (-rr+rjk2)/(rijrik*rik2);
- dctij = (rr+rjk2)/(rijrik*r23mag*r23mag);
- dctjk = -2.0/rijrik;
- w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
- rijmag = r32mag;
- rikmag = r21mag;
- rij2 = r32mag*r32mag;
- rik2 = r21mag*r21mag;
- costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
- tspjik = Sp2(costmp,thmin,thmax,dtsjik);
- dtsjik = -dtsjik;
+ tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- REBO_neighs_j = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs_j[l];
- atom4 = atoml;
- ltype = map[type[atoml]];
- if (!(atoml == atomi || atoml == atomk)) {
- r34[0] = x[atom3][0]-x[atom4][0];
- r34[1] = x[atom3][1]-x[atom4][1];
- r34[2] = x[atom3][2]-x[atom4][2];
- r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2]));
- cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) /
- (r32mag*r34mag);
- cos234 = MIN(cos234,1.0);
- cos234 = MAX(cos234,-1.0);
- sin234 = sqrt(1.0 - cos234*cos234);
- sinl2i = 1.0/(sin234*sin234);
- rjl2i = 1.0/(r34mag*r34mag);
+ // PIJ forces
- if (sin234 != 0.0) {
- w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34);
- rr = (r23mag*r23mag)-(r34mag*r34mag);
- ril[0] = r23[0]+r34[0];
- ril[1] = r23[1]+r34[1];
- ril[2] = r23[2]+r34[2];
- ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
- rijrjl = 2.0*r23mag*r34mag;
- rjl2 = r34mag*r34mag;
- dctjl = (-rr+ril2)/(rijrjl*rjl2);
- dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
- dctil = -2.0/rijrjl;
- rjlmag = r34mag;
- rjl2 = r34mag*r34mag;
- costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
- tspijl = Sp2(costmp,thmin,thmax,dtsijl);
- dtsijl = -dtsijl;
- prefactor = VA*Tij;
+ tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
- cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
- cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
- cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
- cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
- cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
+ // dgdN forces
- cwnum = (cross321[0]*cross234[0]) +
- (cross321[1]*cross234[1]) + (cross321[2]*cross234[2]);
- cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
- om1234 = cwnum/cwnom;
- cw = om1234;
- Etmp += ((1.0-pow(om1234,2.0))*w21*w34) *
- (1.0-tspjik)*(1.0-tspijl);
-
- dt1dik = (rik2i)-(dctik*sink2i*cos321);
- dt1djk = (-dctjk*sink2i*cos321);
- dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
- dt1dil = (-dctil*sinl2i*cos234);
- dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) -
- (dctji*sinl2i*cos234);
-
- dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
- dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
- dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
-
- dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
- dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
- dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
-
- dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) -
- (r21[1]*cross234[2])+(r34[1]*cross321[2]);
- dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) -
- (r21[2]*cross234[0])+(r34[2]*cross321[0]);
- dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) -
- (r21[0]*cross234[1])+(r34[0]*cross321[1]);
-
- aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
- (1.0-tspjik)*(1.0-tspijl);
- aaa1 = -prefactor*(1.0-pow(om1234,2.0)) *
- (1.0-tspjik)*(1.0-tspijl);
- aaa2 = aaa1*w21*w34;
- at2 = aa*cwnum;
-
- fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
- (aaa2*dtsijl*dctji*(1.0-tspjik));
- fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
- fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
- fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
- fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
-
- F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
- F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
- F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
-
- F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
- F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
- F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
-
- F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
- F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
- F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
-
- F31[0] = (fcjkpc*rjk[0]);
- F31[1] = (fcjkpc*rjk[1]);
- F31[2] = (fcjkpc*rjk[2]);
-
- F24[0] = (fcilpc*ril[0]);
- F24[1] = (fcilpc*ril[1]);
- F24[2] = (fcilpc*ril[2]);
-
- f1[0] = -F12[0]-F31[0];
- f1[1] = -F12[1]-F31[1];
- f1[2] = -F12[2]-F31[2];
- f2[0] = F23[0]+F12[0]+F24[0];
- f2[1] = F23[1]+F12[1]+F24[1];
- f2[2] = F23[2]+F12[2]+F24[2];
- f3[0] = -F23[0]+F34[0]+F31[0];
- f3[1] = -F23[1]+F34[1]+F31[1];
- f3[2] = -F23[2]+F34[2]+F31[2];
- f4[0] = -F34[0]-F24[0];
- f4[1] = -F34[1]-F24[1];
- f4[2] = -F34[2]-F24[2];
-
- // coordination forces
+ tmp2=VA*.5*(tmp*tmp3*dwjl)*invrjlm;
+ fj[0] -= tmp2*rjl[0];
+ fj[1] -= tmp2*rjl[1];
+ fj[2] -= tmp2*rjl[2];
+ fl[0] += tmp2*rjl[0];
+ fl[1] += tmp2*rjl[1];
+ fl[2] += tmp2*rjl[2];
- tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
- (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
- f2[0] -= tmp2*r21[0];
- f2[1] -= tmp2*r21[1];
- f2[2] -= tmp2*r21[2];
- f1[0] += tmp2*r21[0];
- f1[1] += tmp2*r21[1];
- f1[2] += tmp2*r21[2];
-
- tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
- (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
- f3[0] -= tmp2*r34[0];
- f3[1] -= tmp2*r34[1];
- f3[2] -= tmp2*r34[2];
- f4[0] += tmp2*r34[0];
- f4[1] += tmp2*r34[1];
- f4[2] += tmp2*r34[2];
+ f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+ f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
- f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
- f[atom1][2] += f1[2];
- f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
- f[atom2][2] += f2[2];
- f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
- f[atom3][2] += f3[2];
- f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
- f[atom4][2] += f4[2];
-
- if (vflag_atom) {
- r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
- r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
- v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43);
- }
- }
- }
- }
+ if (vflag_atom) {
+ rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
+ v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
}
}
}
-
- // Tij forces now that we have Etmp
- REBO_neighs = REBO_firstneigh[i];
+ // piRC forces
+
+ dN3[0] = dN3piRC[0];
+ dN3[1] = dN3piRC[1];
+ dN3[2] = dN3piRC[2];
+
+ REBO_neighs_i = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs[k];
+ atomk = REBO_neighs_i[k];
if (atomk != atomj) {
ktype = map[type[atomk]];
rik[0] = x[atomi][0]-x[atomk][0];
rik[1] = x[atomi][1]-x[atomk][1];
rik[2] = x[atomi][2]-x[atomk][2];
rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+ Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
(wik*kronecker(itype,1));
SpN = Sp(Nki,Nmin,Nmax,dNki);
- tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ tmp2 = VA*dN3[0]*dwik/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
if (fabs(dNki) > TOL) {
REBO_neighs_k = REBO_firstneigh[atomk];
for (n = 0; n < REBO_numneigh[atomk]; n++) {
atomn = REBO_neighs_k[n];
- ntype = map[type[atomn]];
if (atomn != atomi) {
+ ntype = map[type[atomn]];
rkn[0] = x[atomk][0]-x[atomn][0];
rkn[1] = x[atomk][1]-x[atomn][1];
rkn[2] = x[atomk][2]-x[atomn][2];
rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
- f[atomk][0] -= tmp2*rkn[0];
- f[atomk][1] -= tmp2*rkn[1];
- f[atomk][2] -= tmp2*rkn[2];
- f[atomn][0] += tmp2*rkn[0];
- f[atomn][1] += tmp2*rkn[1];
- f[atomn][2] += tmp2*rkn[2];
-
- if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
+ f[atomk][0] -= tmp2*rkn[0];
+ f[atomk][1] -= tmp2*rkn[1];
+ f[atomk][2] -= tmp2*rkn[2];
+ f[atomn][0] += tmp2*rkn[0];
+ f[atomn][1] += tmp2*rkn[1];
+ f[atomn][2] += tmp2*rkn[2];
+
+ if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
}
}
}
}
}
- // Tij forces
+ // piRC forces to J side
REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) {
atoml = REBO_neighs[l];
if (atoml != atomi) {
ltype = map[type[atoml]];
rjl[0] = x[atomj][0]-x[atoml][0];
rjl[1] = x[atomj][1]-x[atoml][1];
rjl[2] = x[atomj][2]-x[atoml][2];
rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
(wjl*kronecker(jtype,1));
SpN = Sp(Nlj,Nmin,Nmax,dNlj);
- tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ tmp2 = VA*dN3[1]*dwjl/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
if (fabs(dNlj) > TOL) {
REBO_neighs_l = REBO_firstneigh[atoml];
for (n = 0; n < REBO_numneigh[atoml]; n++) {
atomn = REBO_neighs_l[n];
- ntype = map[type[atomn]];
- if (atomn !=atomj) {
+ if (atomn != atomj) {
+ ntype = map[type[atomn]];
rln[0] = x[atoml][0]-x[atomn][0];
rln[1] = x[atoml][1]-x[atomn][1];
rln[2] = x[atoml][2]-x[atomn][2];
rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
f[atoml][0] -= tmp2*rln[0];
f[atoml][1] -= tmp2*rln[1];
f[atoml][2] -= tmp2*rln[2];
f[atomn][0] += tmp2*rln[0];
f[atomn][1] += tmp2*rln[1];
f[atomn][2] += tmp2*rln[2];
- if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
+ if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
}
}
}
}
}
- }
- bij = (0.5*(pij+pji))+piRC+(Tij*Etmp);
- return bij;
-}
+ if (fabs(Tij) > TOL) {
+ dN3[0] = dN3Tij[0];
+ dN3[1] = dN3Tij[1];
+ dN3[2] = dN3Tij[2];
+ atom2 = atomi;
+ atom3 = atomj;
+ r32[0] = x[atom3][0]-x[atom2][0];
+ r32[1] = x[atom3][1]-x[atom2][1];
+ r32[2] = x[atom3][2]-x[atom2][2];
+ r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
+ r23[0] = -r32[0];
+ r23[1] = -r32[1];
+ r23[2] = -r32[2];
+ r23mag = r32mag;
-/* ----------------------------------------------------------------------
- Bij* function
-------------------------------------------------------------------------- */
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs_i[k];
+ atom1 = atomk;
+ ktype = map[type[atomk]];
+ if (atomk != atomj) {
+ r21[0] = x[atom2][0]-x[atom1][0];
+ r21[1] = x[atom2][1]-x[atom1][1];
+ r21[2] = x[atom2][2]-x[atom1][2];
+ r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
+ cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) /
+ (r21mag*rijmag);
+ cos321 = MIN(cos321,1.0);
+ cos321 = MAX(cos321,-1.0);
+ sin321 = sqrt(1.0 - cos321*cos321);
+ sink2i = 1.0/(sin321*sin321);
+ rik2i = 1.0/(r21mag*r21mag);
-double PairAIREBO::bondorderLJ(int i, int j, double rij[3], double rijmag,
- double VA, double rij0[3], double rij0mag,
- double **f, int vflag_atom)
-{
- int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
- int atomi,atomj,itype,jtype,ktype,ltype,ntype;
- double rik[3], rjl[3], rkn[3],rknmag,dNki;
- double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
- double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
- double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ;
- double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
- double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
- double dN2[2],dN3[3];
- double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl;
- double Tij,crosskij[3],crosskijmag;
- double crossijl[3],crossijlmag,omkijl;
- double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3];
- double bij,tmp3pij,tmp3pji,Stb,dStb;
- double r32[3],r32mag,cos321;
- double om1234,rln[3];
- double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
- double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
- double cross321[3],cross234[3],prefactor,SpN;
- double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
- double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
- double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
- double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
- double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
- double dNlj;
- double PijS,PjiS;
- double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
- int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
- double F12[3],F23[3],F34[3],F31[3],F24[3];
- double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4];
- double rji[3],rki[3],rlj[3],r13[3],r43[3];
+ if (sin321 != 0.0) {
+ rr = (rijmag*rijmag)-(r21mag*r21mag);
+ rjk[0] = r21[0]-rij[0];
+ rjk[1] = r21[1]-rij[1];
+ rjk[2] = r21[2]-rij[2];
+ rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+ rijrik = 2.0*rijmag*r21mag;
+ rik2 = r21mag*r21mag;
+ dctik = (-rr+rjk2)/(rijrik*rik2);
+ dctij = (rr+rjk2)/(rijrik*rijmag*rijmag);
+ dctjk = -2.0/rijrik;
+ w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
+ rikmag = r21mag;
+ rij2 = r32mag*r32mag;
+ rik2 = r21mag*r21mag;
+ costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+ tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+ dtsjik = -dtsjik;
+
+ REBO_neighs_j = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs_j[l];
+ atom4 = atoml;
+ ltype = map[type[atoml]];
+ if (!(atoml == atomi || atoml == atomk)) {
+ r34[0] = x[atom3][0]-x[atom4][0];
+ r34[1] = x[atom3][1]-x[atom4][1];
+ r34[2] = x[atom3][2]-x[atom4][2];
+ r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]);
+ cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) +
+ (rij[2]*r34[2]))/(rijmag*r34mag);
+ cos234 = MIN(cos234,1.0);
+ cos234 = MAX(cos234,-1.0);
+ sin234 = sqrt(1.0 - cos234*cos234);
+ sinl2i = 1.0/(sin234*sin234);
+ rjl2i = 1.0/(r34mag*r34mag);
+
+ if (sin234 != 0.0) {
+ w34 = Sp(r34mag,rcmin[jtype][ltype],
+ rcmaxp[jtype][ltype],dw34);
+ rr = (r23mag*r23mag)-(r34mag*r34mag);
+ ril[0] = r23[0]+r34[0];
+ ril[1] = r23[1]+r34[1];
+ ril[2] = r23[2]+r34[2];
+ ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+ rijrjl = 2.0*r23mag*r34mag;
+ rjl2 = r34mag*r34mag;
+ dctjl = (-rr+ril2)/(rijrjl*rjl2);
+ dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
+ dctil = -2.0/rijrjl;
+ rjlmag = r34mag;
+ rjl2 = r34mag*r34mag;
+ costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+ tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+ dtsijl = -dtsijl; //need minus sign
+ prefactor = VA*Tij;
- double **x = atom->x;
- int *type = atom->type;
-
- atomi = i;
- atomj = j;
- itype = map[type[atomi]];
- jtype = map[type[atomj]];
- wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
- NijC = nC[atomi]-(wij*kronecker(jtype,0));
- NijH = nH[atomi]-(wij*kronecker(jtype,1));
- NjiC = nC[atomj]-(wij*kronecker(itype,0));
- NjiH = nH[atomj]-(wij*kronecker(itype,1));
-
- bij = 0.0;
- tmp = 0.0;
- tmp2 = 0.0;
- tmp3 = 0.0;
- dgdc = 0.0;
- dgdN = 0.0;
- NconjtmpI = 0.0;
- NconjtmpJ = 0.0;
- Etmp = 0.0;
+ cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
+ cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
+ cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
+ cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
+ cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
+ cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
- REBO_neighs = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs[k];
- if (atomk != atomj) {
- ktype = map[type[atomk]];
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- lamdajik = 4.0*kronecker(itype,1) *
- ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
- Nki = nC[atomk]-(wik*kronecker(itype,0)) +
- nH[atomk]-(wik*kronecker(itype,1));
- cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
- (rijmag*rikmag);
- cosjik = MIN(cosjik,1.0);
- cosjik = MAX(cosjik,-1.0);
+ cwnum = (cross321[0]*cross234[0]) +
+ (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
+ cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
+ om1234 = cwnum/cwnom;
+ cw = om1234;
+ Etmp += ((1.0-(om1234*om1234))*w21*w34) *
+ (1.0-tspjik)*(1.0-tspijl);
- // evaluate splines g and derivatives dg
+ dt1dik = (rik2i)-(dctik*sink2i*cos321);
+ dt1djk = (-dctjk*sink2i*cos321);
+ dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
+ dt1dil = (-dctil*sinl2i*cos234);
+ dt1dij = (2.0/(r23mag*r23mag)) -
+ (dctij*sink2i*cos321)-(dctji*sinl2i*cos234);
- g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
- Etmp = Etmp+(wik*g*exp(lamdajik));
- tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
- NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
- }
- }
+ dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
+ dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
+ dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
- PijS = 0.0;
- dN2PIJ[0] = 0.0;
- dN2PIJ[1] = 0.0;
- PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ);
- pij = pow(1.0+Etmp+PijS,-0.5);
- tmppij = -.5*pow(pij,3.0);
- tmp3pij = tmp3;
- tmp = 0.0;
- tmp2 = 0.0;
- tmp3 = 0.0;
- Etmp = 0.0;
+ dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
+ dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
+ dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
- REBO_neighs = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs[l];
- if (atoml != atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- lamdaijl = 4.0*kronecker(jtype,1) *
- ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
- (wjl*kronecker(jtype,1));
- cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
- (rijmag*rjlmag);
- cosijl = MIN(cosijl,1.0);
- cosijl = MAX(cosijl,-1.0);
+ dt2dij[0] = (r21[2]*cross234[1]) -
+ (r34[2]*cross321[1])-(r21[1]*cross234[2]) +
+ (r34[1]*cross321[2]);
+ dt2dij[1] = (r21[0]*cross234[2]) -
+ (r34[0]*cross321[2])-(r21[2]*cross234[0]) +
+ (r34[2]*cross321[0]);
+ dt2dij[2] = (r21[1]*cross234[0]) -
+ (r34[1]*cross321[0])-(r21[0]*cross234[1]) +
+ (r34[0]*cross321[1]);
- // evaluate splines g and derivatives dg
+ aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
+ (1.0-tspjik)*(1.0-tspijl);
+ aaa1 = -prefactor*(1.0-(om1234*om1234)) *
+ (1.0-tspjik)*(1.0-tspijl);
+ aaa2 = aaa1*w21*w34;
+ at2 = aa*cwnum;
- g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
- Etmp = Etmp+(wjl*g*exp(lamdaijl));
- tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
- NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
- }
- }
+ fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
+ (aaa2*dtsijl*dctji*(1.0-tspjik));
+ fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
+ fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
+ fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
+ fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
- PjiS = 0.0;
- dN2PJI[0] = 0.0;
- dN2PJI[1] = 0.0;
- PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI);
- pji = pow(1.0+Etmp+PjiS,-0.5);
- tmppji = -.5*pow(pji,3.0);
- tmp3pji = tmp3;
+ F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
+ F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
+ F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
- // evaluate Nij conj
+ F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
+ F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
+ F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
- Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
- piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC);
- Tij = 0.0;
- dN3Tij[0] = 0.0;
- dN3Tij[1] = 0.0;
- dN3Tij[2] = 0.0;
- if (itype == 0 && jtype == 0)
- Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij);
+ F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
+ F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
+ F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
- Etmp = 0.0;
- if (fabs(Tij) > TOL) {
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- ktype = map[type[atomk]];
- if (atomk != atomj) {
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
- (rijmag*rikmag);
- cos321 = MIN(cos321,1.0);
- cos321 = MAX(cos321,-1.0);
+ F31[0] = (fcjkpc*rjk[0]);
+ F31[1] = (fcjkpc*rjk[1]);
+ F31[2] = (fcjkpc*rjk[2]);
- rjk[0] = rik[0]-rij[0];
- rjk[1] = rik[1]-rij[1];
- rjk[2] = rik[2]-rij[2];
- rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
- rij2 = rijmag*rijmag;
- rik2 = rikmag*rikmag;
- costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
- tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+ F24[0] = (fcilpc*ril[0]);
+ F24[1] = (fcilpc*ril[1]);
+ F24[2] = (fcilpc*ril[2]);
- if (sqrt(1.0 - cos321*cos321) != 0.0) {
- wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik);
- REBO_neighs_j = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs_j[l];
- ltype = map[type[atoml]];
- if (!(atoml == atomi || atoml == atomk)) {
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]);
- cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
- (rijmag*rjlmag);
- cos234 = MIN(cos234,1.0);
- cos234 = MAX(cos234,-1.0);
+ f1[0] = -F12[0]-F31[0];
+ f1[1] = -F12[1]-F31[1];
+ f1[2] = -F12[2]-F31[2];
+ f2[0] = F23[0]+F12[0]+F24[0];
+ f2[1] = F23[1]+F12[1]+F24[1];
+ f2[2] = F23[2]+F12[2]+F24[2];
+ f3[0] = -F23[0]+F34[0]+F31[0];
+ f3[1] = -F23[1]+F34[1]+F31[1];
+ f3[2] = -F23[2]+F34[2]+F31[2];
+ f4[0] = -F34[0]-F24[0];
+ f4[1] = -F34[1]-F24[1];
+ f4[2] = -F34[2]-F24[2];
- ril[0] = rij[0]+rjl[0];
- ril[1] = rij[1]+rjl[1];
- ril[2] = rij[2]+rjl[2];
- ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
- rijrjl = 2.0*rijmag*rjlmag;
- rjl2 = rjlmag*rjlmag;
- costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
- tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+ // coordination forces
- if (sqrt(1.0 - cos234*cos234) != 0.0) {
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS);
- crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]);
- crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]);
- crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]);
- crosskijmag = sqrt(crosskij[0]*crosskij[0] +
- crosskij[1]*crosskij[1] +
- crosskij[2]*crosskij[2]);
- crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]);
- crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]);
- crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]);
- crossijlmag = sqrt(crossijl[0]*crossijl[0] +
- crossijl[1]*crossijl[1] +
- crossijl[2]*crossijl[2]);
- omkijl = -1.0*(((crosskij[0]*crossijl[0]) +
- (crosskij[1]*crossijl[1]) +
- (crosskij[2]*crossijl[2])) /
- (crosskijmag*crossijlmag));
- Etmp += ((1.0-pow(omkijl,2.0))*wik*wjl) *
- (1.0-tspjik)*(1.0-tspijl);
- }
+ tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+ (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
+ f2[0] -= tmp2*r21[0];
+ f2[1] -= tmp2*r21[1];
+ f2[2] -= tmp2*r21[2];
+ f1[0] += tmp2*r21[0];
+ f1[1] += tmp2*r21[1];
+ f1[2] += tmp2*r21[2];
+
+ tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+ (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
+ f3[0] -= tmp2*r34[0];
+ f3[1] -= tmp2*r34[1];
+ f3[2] -= tmp2*r34[2];
+ f4[0] += tmp2*r34[0];
+ f4[1] += tmp2*r34[1];
+ f4[2] += tmp2*r34[2];
+
+ f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
+ f[atom1][2] += f1[2];
+ f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
+ f[atom2][2] += f2[2];
+ f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
+ f[atom3][2] += f3[2];
+ f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
+ f[atom4][2] += f4[2];
+
+ if (vflag_atom) {
+ r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
+ r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
+ v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
+ }
+ }
+ }
}
}
}
}
- }
- }
-
- bij = (.5*(pij+pji))+piRC+(Tij*Etmp);
- Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb);
- VA = VA*dStb;
- if (dStb != 0.0) {
- tmp = tmppij;
- dN2[0] = dN2PIJ[0];
- dN2[1] = dN2PIJ[1];
- tmp3 = tmp3pij;
+ REBO_neighs = REBO_firstneigh[i];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ atomk = REBO_neighs[k];
+ if (atomk != atomj) {
+ ktype = map[type[atomk]];
+ rik[0] = x[atomi][0]-x[atomk][0];
+ rik[1] = x[atomi][1]-x[atomk][1];
+ rik[2] = x[atomi][2]-x[atomk][2];
+ rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+ wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+ Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+ (wik*kronecker(itype,1));
+ SpN = Sp(Nki,Nmin,Nmax,dNki);
+
+ tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- // pij forces
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- if (atomk != atomj) {
- lamdajik = 0.0;
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]);
- lamdajik = 4.0*kronecker(itype,1) *
- ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
- (rijmag*rikmag);
- cosjik = MIN(cosjik,1.0);
- cosjik = MAX(cosjik,-1.0);
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
+ f[atomi][0] -= tmp2*rik[0];
+ f[atomi][1] -= tmp2*rik[1];
+ f[atomi][2] -= tmp2*rik[2];
+ f[atomk][0] += tmp2*rik[0];
+ f[atomk][1] += tmp2*rik[1];
+ f[atomk][2] += tmp2*rik[2];
- dcosjikdri[0] = ((rij[0]+rik[0])/(rijmag*rikmag)) -
- (cosjik*((rij[0]/(rijmag*rijmag))+(rik[0]/(rikmag*rikmag))));
- dcosjikdri[1] = ((rij[1]+rik[1])/(rijmag*rikmag)) -
- (cosjik*((rij[1]/(rijmag*rijmag))+(rik[1]/(rikmag*rikmag))));
- dcosjikdri[2] = ((rij[2]+rik[2])/(rijmag*rikmag)) -
- (cosjik*((rij[2]/(rijmag*rijmag))+(rik[2]/(rikmag*rikmag))));
- dcosjikdrk[0] = (-rij[0]/(rijmag*rikmag)) +
- (cosjik*(rik[0]/(rikmag*rikmag)));
- dcosjikdrk[1] = (-rij[1]/(rijmag*rikmag)) +
- (cosjik*(rik[1]/(rikmag*rikmag)));
- dcosjikdrk[2] = (-rij[2]/(rijmag*rikmag)) +
- (cosjik*(rik[2]/(rikmag*rikmag)));
- dcosjikdrj[0] = (-rik[0]/(rijmag*rikmag)) +
- (cosjik*(rij[0]/(rijmag*rijmag)));
- dcosjikdrj[1] = (-rik[1]/(rijmag*rikmag)) +
- (cosjik*(rij[1]/(rijmag*rijmag)));
- dcosjikdrj[2] = (-rik[2]/(rijmag*rikmag)) +
- (cosjik*(rij[2]/(rijmag*rijmag)));
+ if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
- g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+ if (fabs(dNki) >TOL) {
+ REBO_neighs_k = REBO_firstneigh[atomk];
+ for (n = 0; n < REBO_numneigh[atomk]; n++) {
+ atomn = REBO_neighs_k[n];
+ ntype = map[type[atomn]];
+ if (atomn !=atomi) {
+ rkn[0] = x[atomk][0]-x[atomn][0];
+ rkn[1] = x[atomk][1]-x[atomn][1];
+ rkn[2] = x[atomk][2]-x[atomn][2];
+ rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+ Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
- tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
- fj[0] = -tmp2*dcosjikdrj[0];
- fj[1] = -tmp2*dcosjikdrj[1];
- fj[2] = -tmp2*dcosjikdrj[2];
- fi[0] = -tmp2*dcosjikdri[0];
- fi[1] = -tmp2*dcosjikdri[1];
- fi[2] = -tmp2*dcosjikdri[2];
- fk[0] = -tmp2*dcosjikdrk[0];
- fk[1] = -tmp2*dcosjikdrk[1];
- fk[2] = -tmp2*dcosjikdrk[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
+ f[atomk][0] -= tmp2*rkn[0];
+ f[atomk][1] -= tmp2*rkn[1];
+ f[atomk][2] -= tmp2*rkn[2];
+ f[atomn][0] += tmp2*rkn[0];
+ f[atomn][1] += tmp2*rkn[1];
+ f[atomn][2] += tmp2*rkn[2];
+
+ if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+ }
+ }
+ }
+ }
+ }
- tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
- fj[0] -= tmp2*(-rij[0]/rijmag);
- fj[1] -= tmp2*(-rij[1]/rijmag);
- fj[2] -= tmp2*(-rij[2]/rijmag);
- fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]/rijmag));
- fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]/rijmag));
- fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]/rijmag));
- fk[0] -= tmp2*(rik[0]/rikmag);
- fk[1] -= tmp2*(rik[1]/rikmag);
- fk[2] -= tmp2*(rik[2]/rikmag);
+ // Tij forces
- // coordination forces
-
- // dwik forces
+ REBO_neighs = REBO_firstneigh[j];
+ for (l = 0; l < REBO_numneigh[j]; l++) {
+ atoml = REBO_neighs[l];
+ if (atoml != atomi) {
+ ltype = map[type[atoml]];
+ rjl[0] = x[atomj][0]-x[atoml][0];
+ rjl[1] = x[atomj][1]-x[atoml][1];
+ rjl[2] = x[atomj][2]-x[atoml][2];
+ rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+ wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+ Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+ (wjl*kronecker(jtype,1));
+ SpN = Sp(Nlj,Nmin,Nmax,dNlj);
- tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
+ tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- // PIJ forces
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
+ f[atomj][0] -= tmp2*rjl[0];
+ f[atomj][1] -= tmp2*rjl[1];
+ f[atomj][2] -= tmp2*rjl[2];
+ f[atoml][0] += tmp2*rjl[0];
+ f[atoml][1] += tmp2*rjl[1];
+ f[atoml][2] += tmp2*rjl[2];
- // dgdN forces
+ if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
- tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
- fi[0] -= tmp2*rik[0];
- fi[1] -= tmp2*rik[1];
- fi[2] -= tmp2*rik[2];
- fk[0] += tmp2*rik[0];
- fk[1] += tmp2*rik[1];
- fk[2] += tmp2*rik[2];
+ if (fabs(dNlj) > TOL) {
+ REBO_neighs_l = REBO_firstneigh[atoml];
+ for (n = 0; n < REBO_numneigh[atoml]; n++) {
+ atomn = REBO_neighs_l[n];
+ ntype = map[type[atomn]];
+ if (atomn != atomj) {
+ rln[0] = x[atoml][0]-x[atomn][0];
+ rln[1] = x[atoml][1]-x[atomn][1];
+ rln[2] = x[atoml][2]-x[atomn][2];
+ rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+ Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
- f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
- f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
- f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
-
- if (vflag_atom) {
- rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
- rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
- v_tally3(atomi,atomj,atomk,fj,fk,rji,rki);
+ tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
+ f[atoml][0] -= tmp2*rln[0];
+ f[atoml][1] -= tmp2*rln[1];
+ f[atoml][2] -= tmp2*rln[2];
+ f[atomn][0] += tmp2*rln[0];
+ f[atomn][1] += tmp2*rln[1];
+ f[atomn][2] += tmp2*rln[2];
+
+ if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
+ }
+ }
+ }
}
}
}
+ }
- tmp = tmppji;
- tmp3 = tmp3pji;
- dN2[0] = dN2PJI[0];
- dN2[1] = dN2PJI[1];
- REBO_neighs = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs[l];
- if (atoml !=atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- lamdaijl = 4.0*kronecker(jtype,1) *
- ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) /
- (rijmag*rjlmag);
- cosijl = MIN(cosijl,1.0);
- cosijl = MAX(cosijl,-1.0);
+ return Stb;
+}
- dcosijldri[0] = (-rjl[0]/(rijmag*rjlmag)) -
- (cosijl*rij[0]/(rijmag*rijmag));
- dcosijldri[1] = (-rjl[1]/(rijmag*rjlmag)) -
- (cosijl*rij[1]/(rijmag*rijmag));
- dcosijldri[2] = (-rjl[2]/(rijmag*rjlmag)) -
- (cosijl*rij[2]/(rijmag*rijmag));
- dcosijldrj[0] = ((-rij[0]+rjl[0])/(rijmag*rjlmag)) +
- (cosijl*((rij[0]/pow(rijmag,2.0))-(rjl[0]/(rjlmag*rjlmag))));
- dcosijldrj[1] = ((-rij[1]+rjl[1])/(rijmag*rjlmag)) +
- (cosijl*((rij[1]/pow(rijmag,2.0))-(rjl[1]/(rjlmag*rjlmag))));
- dcosijldrj[2] = ((-rij[2]+rjl[2])/(rijmag*rjlmag)) +
- (cosijl*((rij[2]/pow(rijmag,2.0))-(rjl[2]/(rjlmag*rjlmag))));
- dcosijldrl[0] = (rij[0]/(rijmag*rjlmag)) +
- (cosijl*rjl[0]/(rjlmag*rjlmag));
- dcosijldrl[1] = (rij[1]/(rijmag*rjlmag)) +
- (cosijl*rjl[1]/(rjlmag*rjlmag));
- dcosijldrl[2] = (rij[2]/(rijmag*rjlmag)) +
- (cosijl*rjl[2]/(rjlmag*rjlmag));
+/* ----------------------------------------------------------------------
+ REBO forces and energy
+------------------------------------------------------------------------- */
- // evaluate splines g and derivatives dg
+void PairAIREBOOMP::FREBO_thr(int ifrom, int ito, int evflag, int eflag,
+ int vflag_atom, ThrData * const thr)
+{
+ int i,j,k,m,ii,itype,jtype,itag,jtag;
+ double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
+ double rsq,rij,wij;
+ double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
+ double dwij,del[3];
+ int *ilist,*REBO_neighs;
- g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
- tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
- fi[0] = -tmp2*dcosijldri[0];
- fi[1] = -tmp2*dcosijldri[1];
- fi[2] = -tmp2*dcosijldri[2];
- fj[0] = -tmp2*dcosijldrj[0];
- fj[1] = -tmp2*dcosijldrj[1];
- fj[2] = -tmp2*dcosijldrj[2];
- fl[0] = -tmp2*dcosijldrl[0];
- fl[1] = -tmp2*dcosijldrl[1];
- fl[2] = -tmp2*dcosijldrl[2];
+ evdwl = 0.0;
- tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
- fi[0] -= tmp2*(rij[0]/rijmag);
- fi[1] -= tmp2*(rij[1]/rijmag);
- fi[2] -= tmp2*(rij[2]/rijmag);
- fj[0] -= tmp2*((-rjl[0]/rjlmag)-(rij[0]/rijmag));
- fj[1] -= tmp2*((-rjl[1]/rjlmag)-(rij[1]/rijmag));
- fj[2] -= tmp2*((-rjl[2]/rjlmag)-(rij[2]/rijmag));
- fl[0] -= tmp2*(rjl[0]/rjlmag);
- fl[1] -= tmp2*(rjl[1]/rjlmag);
- fl[2] -= tmp2*(rjl[2]/rjlmag);
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ int *type = atom->type;
+ int *tag = atom->tag;
+ int nlocal = atom->nlocal;
- // coordination forces
- // dwik forces
+ ilist = list->ilist;
- tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ // two-body interactions from REBO neighbor list, skip half of them
- // PIJ forces
+ for (ii = ifrom; ii < ito; ii++) {
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ REBO_neighs = REBO_firstneigh[i];
- tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ for (k = 0; k < REBO_numneigh[i]; k++) {
+ j = REBO_neighs[k];
+ jtag = tag[j];
- // dgdN forces
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
- tmp2=VA*.5*(tmp*tmp3*dwjl)/rjlmag;
- fj[0] -= tmp2*rjl[0];
- fj[1] -= tmp2*rjl[1];
- fj[2] -= tmp2*rjl[2];
- fl[0] += tmp2*rjl[0];
- fl[1] += tmp2*rjl[1];
- fl[2] += tmp2*rjl[2];
+ jtype = map[type[j]];
- f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
- f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
- f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
-
- if (vflag_atom) {
- rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
- v_tally3(atomi,atomj,atoml,fi,fl,rij,rlj);
- }
- }
- }
-
- // piRC forces
+ delx = x[i][0] - x[j][0];
+ dely = x[i][1] - x[j][1];
+ delz = x[i][2] - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ rij = sqrt(rsq);
+ wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+ if (wij <= TOL) continue;
- dN3[0] = dN3piRC[0];
- dN3[1] = dN3piRC[1];
- dN3[2] = dN3piRC[2];
+ Qij = Q[itype][jtype];
+ Aij = A[itype][jtype];
+ alphaij = alpha[itype][jtype];
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- if (atomk != atomj) {
- ktype = map[type[atomk]];
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
- (wik*kronecker(itype,1));
- SpN = Sp(Nki,Nmin,Nmax,dNki);
+ VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij);
+ pre = wij*Aij * exp(-alphaij*rij);
+ dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij));
+ dVRdi += VR/wij * dwij;
- tmp2 = VA*dN3[0]*dwik/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ VA = dVA = 0.0;
+ for (m = 0; m < 3; m++) {
+ term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij);
+ VA += term;
+ dVA += -Beta[itype][jtype][m] * term;
+ }
+ dVA += VA/wij * dwij;
+ del[0] = delx;
+ del[1] = dely;
+ del[2] = delz;
+ bij = bondorder_thr(i,j,del,rij,VA,vflag_atom,thr);
+ dVAdi = bij*dVA;
+
+ fpair = -(dVRdi+dVAdi) / rij;
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ if (eflag) evdwl = VR + bij*VA;
+ if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+ }
+}
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+/* ----------------------------------------------------------------------
+ compute LJ forces and energy
+ find 3- and 4-step paths between atoms I,J via REBO neighbor lists
+------------------------------------------------------------------------- */
+
+void PairAIREBOOMP::FLJ_thr(int ifrom, int ito, int evflag, int eflag,
+ int vflag_atom, ThrData * const thr)
+{
+ int i,j,k,m,ii,jj,kk,mm,jnum,itype,jtype,ktype,mtype,itag,jtag;
+ int atomi,atomj,atomk,atomm;
+ int testpath,npath,done;
+ double evdwl,fpair,xtmp,ytmp,ztmp;
+ double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
+ double delij[3],rijsq,delik[3],rik,deljk[3];
+ double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
+ double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2;
+ double rljmin,rljmax,sigcut,sigmin,sigwid;
+ double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int *REBO_neighs_i,*REBO_neighs_k;
+ double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3];
+ double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
+ double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
+ double fpair1,fpair2,fpair3;
+ double fi[3],fj[3],fk[3],fm[3];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ // I-J interaction from full neighbor list
+ // skip 1/2 of interactions since only consider each pair once
- if (fabs(dNki) > TOL) {
- REBO_neighs_k = REBO_firstneigh[atomk];
- for (n = 0; n < REBO_numneigh[atomk]; n++) {
- atomn = REBO_neighs_k[n];
- if (atomn != atomi) {
- ntype = map[type[atomn]];
- rkn[0] = x[atomk][0]-x[atomn][0];
- rkn[1] = x[atomk][1]-x[atomn][1];
- rkn[2] = x[atomk][2]-x[atomn][2];
- rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
- Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+ evdwl = 0.0;
+ rljmin = 0.0;
+ rljmax = 0.0;
+ sigcut = 0.0;
+ sigmin = 0.0;
+ sigwid = 0.0;
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
- f[atomk][0] -= tmp2*rkn[0];
- f[atomk][1] -= tmp2*rkn[1];
- f[atomk][2] -= tmp2*rkn[2];
- f[atomn][0] += tmp2*rkn[0];
- f[atomn][1] += tmp2*rkn[1];
- f[atomn][2] += tmp2*rkn[2];
- if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
- }
- }
- }
- }
- }
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ int *tag = atom->tag;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
- // piRC forces to J side
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
- REBO_neighs = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs[l];
- if (atoml != atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
- (wjl*kronecker(jtype,1));
- SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+ // loop over neighbors of my atoms
- tmp2 = VA*dN3[1]*dwjl/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ for (ii = ifrom; ii < ito; ii++) {
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ atomi = i;
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtag = tag[j];
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ jtype = map[type[j]];
+ atomj = j;
- if (fabs(dNlj) > TOL) {
- REBO_neighs_l = REBO_firstneigh[atoml];
- for (n = 0; n < REBO_numneigh[atoml]; n++) {
- atomn = REBO_neighs_l[n];
- if (atomn != atomj) {
- ntype = map[type[atomn]];
- rln[0] = x[atoml][0]-x[atomn][0];
- rln[1] = x[atoml][1]-x[atomn][1];
- rln[2] = x[atoml][2]-x[atomn][2];
- rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
- Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+ delij[0] = xtmp - x[j][0];
+ delij[1] = ytmp - x[j][1];
+ delij[2] = ztmp - x[j][2];
+ rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2];
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
- f[atoml][0] -= tmp2*rln[0];
- f[atoml][1] -= tmp2*rln[1];
- f[atoml][2] -= tmp2*rln[2];
- f[atomn][0] += tmp2*rln[0];
- f[atomn][1] += tmp2*rln[1];
- f[atomn][2] += tmp2*rln[2];
+ // if outside of LJ cutoff, skip
+ // if outside of 4-path cutoff, best = 0.0, no need to test paths
+ // if outside of 2-path cutoff but inside 4-path cutoff,
+ // best = 0.0, test 3-,4-paths
+ // if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1
- if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
- }
- }
- }
+ if (rijsq >= cutljsq[itype][jtype]) continue;
+ rij = sqrt(rijsq);
+ if (rij >= cut3rebo) {
+ best = 0.0;
+ testpath = 0;
+ } else if (rij >= rcmax[itype][jtype]) {
+ best = 0.0;
+ testpath = 1;
+ } else {
+ best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+ npath = 2;
+ if (best < 1.0) testpath = 1;
+ else testpath = 0;
}
- }
- if (fabs(Tij) > TOL) {
- dN3[0] = dN3Tij[0];
- dN3[1] = dN3Tij[1];
- dN3[2] = dN3Tij[2];
- atom2 = atomi;
- atom3 = atomj;
- r32[0] = x[atom3][0]-x[atom2][0];
- r32[1] = x[atom3][1]-x[atom2][1];
- r32[2] = x[atom3][2]-x[atom2][2];
- r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
- r23[0] = -r32[0];
- r23[1] = -r32[1];
- r23[2] = -r32[2];
- r23mag = r32mag;
+ done = 0;
+ if (testpath) {
- REBO_neighs_i = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs_i[k];
- atom1 = atomk;
- ktype = map[type[atomk]];
- if (atomk != atomj) {
- r21[0] = x[atom2][0]-x[atom1][0];
- r21[1] = x[atom2][1]-x[atom1][1];
- r21[2] = x[atom2][2]-x[atom1][2];
- r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
- cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) /
- (r21mag*rijmag);
- cos321 = MIN(cos321,1.0);
- cos321 = MAX(cos321,-1.0);
- sin321 = sqrt(1.0 - cos321*cos321);
- sink2i = 1.0/(sin321*sin321);
- rik2i = 1.0/(r21mag*r21mag);
+ // test all 3-body paths = I-K-J
+ // I-K interactions come from atom I's REBO neighbors
+ // if wik > current best, compute wkj
+ // if best = 1.0, done
- if (sin321 != 0.0) {
- rr = (rijmag*rijmag)-(r21mag*r21mag);
- rjk[0] = r21[0]-rij[0];
- rjk[1] = r21[1]-rij[1];
- rjk[2] = r21[2]-rij[2];
- rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
- rijrik = 2.0*rijmag*r21mag;
- rik2 = r21mag*r21mag;
- dctik = (-rr+rjk2)/(rijrik*rik2);
- dctij = (rr+rjk2)/(rijrik*rijmag*rijmag);
- dctjk = -2.0/rijrik;
- w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
- rikmag = r21mag;
- rij2 = r32mag*r32mag;
- rik2 = r21mag*r21mag;
- costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
- tspjik = Sp2(costmp,thmin,thmax,dtsjik);
- dtsjik = -dtsjik;
-
- REBO_neighs_j = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs_j[l];
- atom4 = atoml;
- ltype = map[type[atoml]];
- if (!(atoml == atomi || atoml == atomk)) {
- r34[0] = x[atom3][0]-x[atom4][0];
- r34[1] = x[atom3][1]-x[atom4][1];
- r34[2] = x[atom3][2]-x[atom4][2];
- r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]);
- cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) +
- (rij[2]*r34[2]))/(rijmag*r34mag);
- cos234 = MIN(cos234,1.0);
- cos234 = MAX(cos234,-1.0);
- sin234 = sqrt(1.0 - cos234*cos234);
- sinl2i = 1.0/(sin234*sin234);
- rjl2i = 1.0/(r34mag*r34mag);
+ REBO_neighs_i = REBO_firstneigh[i];
+ for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) {
+ k = REBO_neighs_i[kk];
+ if (k == j) continue;
+ ktype = map[type[k]];
- if (sin234 != 0.0) {
- w34 = Sp(r34mag,rcmin[jtype][ltype],
- rcmaxp[jtype][ltype],dw34);
- rr = (r23mag*r23mag)-(r34mag*r34mag);
- ril[0] = r23[0]+r34[0];
- ril[1] = r23[1]+r34[1];
- ril[2] = r23[2]+r34[2];
- ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
- rijrjl = 2.0*r23mag*r34mag;
- rjl2 = r34mag*r34mag;
- dctjl = (-rr+ril2)/(rijrjl*rjl2);
- dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
- dctil = -2.0/rijrjl;
- rjlmag = r34mag;
- rjl2 = r34mag*r34mag;
- costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
- tspijl = Sp2(costmp,thmin,thmax,dtsijl);
- dtsijl = -dtsijl; //need minus sign
- prefactor = VA*Tij;
+ delik[0] = x[i][0] - x[k][0];
+ delik[1] = x[i][1] - x[k][1];
+ delik[2] = x[i][2] - x[k][2];
+ rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2];
+ if (rsq < rcmaxsq[itype][ktype]) {
+ rik = sqrt(rsq);
+ wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+ } else wik = 0.0;
- cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
- cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
- cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
- cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
- cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
- cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
+ if (wik > best) {
+ deljk[0] = x[j][0] - x[k][0];
+ deljk[1] = x[j][1] - x[k][1];
+ deljk[2] = x[j][2] - x[k][2];
+ rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
+ if (rsq < rcmaxsq[ktype][jtype]) {
+ rkj = sqrt(rsq);
+ wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj);
+ if (wik*wkj > best) {
+ best = wik*wkj;
+ npath = 3;
+ atomk = k;
+ delikS[0] = delik[0];
+ delikS[1] = delik[1];
+ delikS[2] = delik[2];
+ rikS = rik;
+ wikS = wik;
+ dwikS = dwik;
+ deljkS[0] = deljk[0];
+ deljkS[1] = deljk[1];
+ deljkS[2] = deljk[2];
+ rkjS = rkj;
+ wkjS = wkj;
+ dwkjS = dwkj;
+ if (best == 1.0) {
+ done = 1;
+ break;
+ }
+ }
+ }
- cwnum = (cross321[0]*cross234[0]) +
- (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
- cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
- om1234 = cwnum/cwnom;
- cw = om1234;
- Etmp += ((1.0-pow(om1234,2.0))*w21*w34) *
- (1.0-tspjik)*(1.0-tspijl);
-
- dt1dik = (rik2i)-(dctik*sink2i*cos321);
- dt1djk = (-dctjk*sink2i*cos321);
- dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
- dt1dil = (-dctil*sinl2i*cos234);
- dt1dij = (2.0/(r23mag*r23mag)) -
- (dctij*sink2i*cos321)-(dctji*sinl2i*cos234);
-
- dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
- dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
- dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
-
- dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
- dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
- dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
-
- dt2dij[0] = (r21[2]*cross234[1]) -
- (r34[2]*cross321[1])-(r21[1]*cross234[2]) +
- (r34[1]*cross321[2]);
- dt2dij[1] = (r21[0]*cross234[2]) -
- (r34[0]*cross321[2])-(r21[2]*cross234[0]) +
- (r34[2]*cross321[0]);
- dt2dij[2] = (r21[1]*cross234[0]) -
- (r34[1]*cross321[0])-(r21[0]*cross234[1]) +
- (r34[0]*cross321[1]);
-
- aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
- (1.0-tspjik)*(1.0-tspijl);
- aaa1 = -prefactor*(1.0-pow(om1234,2.0)) *
- (1.0-tspjik)*(1.0-tspijl);
- aaa2 = aaa1*w21*w34;
- at2 = aa*cwnum;
-
- fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
- (aaa2*dtsijl*dctji*(1.0-tspjik));
- fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
- fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
- fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
- fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
-
- F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
- F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
- F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
-
- F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
- F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
- F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
-
- F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
- F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
- F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
-
- F31[0] = (fcjkpc*rjk[0]);
- F31[1] = (fcjkpc*rjk[1]);
- F31[2] = (fcjkpc*rjk[2]);
-
- F24[0] = (fcilpc*ril[0]);
- F24[1] = (fcilpc*ril[1]);
- F24[2] = (fcilpc*ril[2]);
-
- f1[0] = -F12[0]-F31[0];
- f1[1] = -F12[1]-F31[1];
- f1[2] = -F12[2]-F31[2];
- f2[0] = F23[0]+F12[0]+F24[0];
- f2[1] = F23[1]+F12[1]+F24[1];
- f2[2] = F23[2]+F12[2]+F24[2];
- f3[0] = -F23[0]+F34[0]+F31[0];
- f3[1] = -F23[1]+F34[1]+F31[1];
- f3[2] = -F23[2]+F34[2]+F31[2];
- f4[0] = -F34[0]-F24[0];
- f4[1] = -F34[1]-F24[1];
- f4[2] = -F34[2]-F24[2];
-
- // coordination forces
+ // test all 4-body paths = I-K-M-J
+ // K-M interactions come from atom K's REBO neighbors
+ // if wik*wkm > current best, compute wmj
+ // if best = 1.0, done
- tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
- (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
- f2[0] -= tmp2*r21[0];
- f2[1] -= tmp2*r21[1];
- f2[2] -= tmp2*r21[2];
- f1[0] += tmp2*r21[0];
- f1[1] += tmp2*r21[1];
- f1[2] += tmp2*r21[2];
-
- tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
- (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
- f3[0] -= tmp2*r34[0];
- f3[1] -= tmp2*r34[1];
- f3[2] -= tmp2*r34[2];
- f4[0] += tmp2*r34[0];
- f4[1] += tmp2*r34[1];
- f4[2] += tmp2*r34[2];
+ REBO_neighs_k = REBO_firstneigh[k];
+ for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) {
+ m = REBO_neighs_k[mm];
+ if (m == i || m == j) continue;
+ mtype = map[type[m]];
+ delkm[0] = x[k][0] - x[m][0];
+ delkm[1] = x[k][1] - x[m][1];
+ delkm[2] = x[k][2] - x[m][2];
+ rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2];
+ if (rsq < rcmaxsq[ktype][mtype]) {
+ rkm = sqrt(rsq);
+ wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm);
+ } else wkm = 0.0;
- f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
- f[atom1][2] += f1[2];
- f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
- f[atom2][2] += f2[2];
- f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
- f[atom3][2] += f3[2];
- f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
- f[atom4][2] += f4[2];
-
- if (vflag_atom) {
- r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
- r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
- v_tally4(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43);
+ if (wik*wkm > best) {
+ deljm[0] = x[j][0] - x[m][0];
+ deljm[1] = x[j][1] - x[m][1];
+ deljm[2] = x[j][2] - x[m][2];
+ rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] +
+ deljm[2]*deljm[2];
+ if (rsq < rcmaxsq[mtype][jtype]) {
+ rmj = sqrt(rsq);
+ wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj);
+ if (wik*wkm*wmj > best) {
+ best = wik*wkm*wmj;
+ npath = 4;
+ atomk = k;
+ delikS[0] = delik[0];
+ delikS[1] = delik[1];
+ delikS[2] = delik[2];
+ rikS = rik;
+ wikS = wik;
+ dwikS = dwik;
+ atomm = m;
+ delkmS[0] = delkm[0];
+ delkmS[1] = delkm[1];
+ delkmS[2] = delkm[2];
+ rkmS = rkm;
+ wkmS = wkm;
+ dwkmS = dwkm;
+ deljmS[0] = deljm[0];
+ deljmS[1] = deljm[1];
+ deljmS[2] = deljm[2];
+ rmjS = rmj;
+ wmjS = wmj;
+ dwmjS = dwmj;
+ if (best == 1.0) {
+ done = 1;
+ break;
+ }
}
}
}
}
}
}
}
-
- REBO_neighs = REBO_firstneigh[i];
- for (k = 0; k < REBO_numneigh[i]; k++) {
- atomk = REBO_neighs[k];
- if (atomk != atomj) {
- ktype = map[type[atomk]];
- rik[0] = x[atomi][0]-x[atomk][0];
- rik[1] = x[atomi][1]-x[atomk][1];
- rik[2] = x[atomi][2]-x[atomk][2];
- rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
- wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
- Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
- (wik*kronecker(itype,1));
- SpN = Sp(Nki,Nmin,Nmax,dNki);
-
- tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ cij = 1.0 - best;
+ if (cij == 0.0) continue;
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
- f[atomi][0] -= tmp2*rik[0];
- f[atomi][1] -= tmp2*rik[1];
- f[atomi][2] -= tmp2*rik[2];
- f[atomk][0] += tmp2*rik[0];
- f[atomk][1] += tmp2*rik[1];
- f[atomk][2] += tmp2*rik[2];
+ // compute LJ forces and energy
- if (vflag_atom) v_tally2(atomi,atomk,-tmp2,rik);
+ sigwid = 0.84;
+ sigcut = 3.0;
+ sigmin = sigcut - sigwid;
- if (fabs(dNki) >TOL) {
- REBO_neighs_k = REBO_firstneigh[atomk];
- for (n = 0; n < REBO_numneigh[atomk]; n++) {
- atomn = REBO_neighs_k[n];
- ntype = map[type[atomn]];
- if (atomn !=atomi) {
- rkn[0] = x[atomk][0]-x[atomn][0];
- rkn[1] = x[atomk][1]-x[atomn][1];
- rkn[2] = x[atomk][2]-x[atomn][2];
- rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
- Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+ rljmin = sigma[itype][jtype];
+ rljmax = sigcut * rljmin;
+ rljmin = sigmin * rljmin;
- tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
- f[atomk][0] -= tmp2*rkn[0];
- f[atomk][1] -= tmp2*rkn[1];
- f[atomk][2] -= tmp2*rkn[2];
- f[atomn][0] += tmp2*rkn[0];
- f[atomn][1] += tmp2*rkn[1];
- f[atomn][2] += tmp2*rkn[2];
-
- if (vflag_atom) v_tally2(atomk,atomn,-tmp2,rkn);
- }
- }
- }
- }
+ if (rij > rljmax){
+ slw = 0.0;
+ dslw = 0.0;}
+ else if (rij > rljmin){
+ drij = rij - rljmin;
+ swidth = rljmax - rljmin;
+ tee = drij / swidth;
+ tee2 = tee*tee;
+ slw = 1.0 - tee2 * (3.0 - 2.0 * tee);
+ dslw = 6.0 * tee * (1.0 - tee) / rij / swidth;
}
+ else
+ slw = 1.0;
+ dslw = 0.0;
- // Tij forces
+ r2inv = 1.0/rijsq;
+ r6inv = r2inv*r2inv*r2inv;
- REBO_neighs = REBO_firstneigh[j];
- for (l = 0; l < REBO_numneigh[j]; l++) {
- atoml = REBO_neighs[l];
- if (atoml != atomi) {
- ltype = map[type[atoml]];
- rjl[0] = x[atomj][0]-x[atoml][0];
- rjl[1] = x[atomj][1]-x[atoml][1];
- rjl[2] = x[atomj][2]-x[atoml][2];
- rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
- wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
- Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
- (wjl*kronecker(jtype,1));
- SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+ vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+ dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij;
+
+ // VLJ now becomes vdw * slw, derivaties, etc.
+
+ VLJ = vdw * slw;
+ dVLJ = dvdw * slw + vdw * dslw;
+
+ Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr);
+ VA = Str*cij*VLJ;
+ if (Str > 0.0) {
+ scale = rcmin[itype][jtype] / rij;
+ delscale[0] = scale * delij[0];
+ delscale[1] = scale * delij[1];
+ delscale[2] = scale * delij[2];
+ Stb = bondorderLJ_thr(i,j,delscale,rcmin[itype][jtype],VA,
+ delij,rij,vflag_atom,thr);
+ } else Stb = 0.0;
+
+ fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
+ dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
+
+ f[i][0] += delij[0]*fpair;
+ f[i][1] += delij[1]*fpair;
+ f[i][2] += delij[2]*fpair;
+ f[j][0] -= delij[0]*fpair;
+ f[j][1] -= delij[1]*fpair;
+ f[j][2] -= delij[2]*fpair;
+
+ if (eflag) evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
+ if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delij[0],delij[1],delij[2],thr);
+
+ if (cij < 1.0) {
+ dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
+ if (npath == 2) {
+ fpair = dC*dwij / rij;
+ f[atomi][0] += delij[0]*fpair;
+ f[atomi][1] += delij[1]*fpair;
+ f[atomi][2] += delij[2]*fpair;
+ f[atomj][0] -= delij[0]*fpair;
+ f[atomj][1] -= delij[1]*fpair;
+ f[atomj][2] -= delij[2]*fpair;
+
+ if (vflag_atom) v_tally2_thr(atomi,atomj,fpair,delij,thr);
+
+ } else if (npath == 3) {
+ fpair1 = dC*dwikS*wkjS / rikS;
+ fi[0] = delikS[0]*fpair1;
+ fi[1] = delikS[1]*fpair1;
+ fi[2] = delikS[2]*fpair1;
+ fpair2 = dC*wikS*dwkjS / rkjS;
+ fj[0] = deljkS[0]*fpair2;
+ fj[1] = deljkS[1]*fpair2;
+ fj[2] = deljkS[2]*fpair2;
+
+ f[atomi][0] += fi[0];
+ f[atomi][1] += fi[1];
+ f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0];
+ f[atomj][1] += fj[1];
+ f[atomj][2] += fj[2];
+ f[atomk][0] -= fi[0] + fj[0];
+ f[atomk][1] -= fi[1] + fj[1];
+ f[atomk][2] -= fi[2] + fj[2];
- tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ if (vflag_atom)
+ v_tally3_thr(atomi,atomj,atomk,fi,fj,delikS,deljkS,thr);
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ } else {
+ fpair1 = dC*dwikS*wkmS*wmjS / rikS;
+ fi[0] = delikS[0]*fpair1;
+ fi[1] = delikS[1]*fpair1;
+ fi[2] = delikS[2]*fpair1;
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
- f[atomj][0] -= tmp2*rjl[0];
- f[atomj][1] -= tmp2*rjl[1];
- f[atomj][2] -= tmp2*rjl[2];
- f[atoml][0] += tmp2*rjl[0];
- f[atoml][1] += tmp2*rjl[1];
- f[atoml][2] += tmp2*rjl[2];
+ fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
+ fk[0] = delkmS[0]*fpair2 - fi[0];
+ fk[1] = delkmS[1]*fpair2 - fi[1];
+ fk[2] = delkmS[2]*fpair2 - fi[2];
- if (vflag_atom) v_tally2(atomj,atoml,-tmp2,rjl);
+ fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
+ fj[0] = deljmS[0]*fpair3;
+ fj[1] = deljmS[1]*fpair3;
+ fj[2] = deljmS[2]*fpair3;
- if (fabs(dNlj) > TOL) {
- REBO_neighs_l = REBO_firstneigh[atoml];
- for (n = 0; n < REBO_numneigh[atoml]; n++) {
- atomn = REBO_neighs_l[n];
- ntype = map[type[atomn]];
- if (atomn != atomj) {
- rln[0] = x[atoml][0]-x[atomn][0];
- rln[1] = x[atoml][1]-x[atomn][1];
- rln[2] = x[atoml][2]-x[atomn][2];
- rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
- Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+ fm[0] = -delkmS[0]*fpair2 - fj[0];
+ fm[1] = -delkmS[1]*fpair2 - fj[1];
+ fm[2] = -delkmS[2]*fpair2 - fj[2];
- tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
- f[atoml][0] -= tmp2*rln[0];
- f[atoml][1] -= tmp2*rln[1];
- f[atoml][2] -= tmp2*rln[2];
- f[atomn][0] += tmp2*rln[0];
- f[atomn][1] += tmp2*rln[1];
- f[atomn][2] += tmp2*rln[2];
+ f[atomi][0] += fi[0];
+ f[atomi][1] += fi[1];
+ f[atomi][2] += fi[2];
+ f[atomj][0] += fj[0];
+ f[atomj][1] += fj[1];
+ f[atomj][2] += fj[2];
+ f[atomk][0] += fk[0];
+ f[atomk][1] += fk[1];
+ f[atomk][2] += fk[2];
+ f[atomm][0] += fm[0];
+ f[atomm][1] += fm[1];
+ f[atomm][2] += fm[2];
- if (vflag_atom) v_tally2(atoml,atomn,-tmp2,rln);
- }
- }
+ if (vflag_atom) {
+ delimS[0] = delikS[0] + delkmS[0];
+ delimS[1] = delikS[1] + delkmS[1];
+ delimS[2] = delikS[2] + delkmS[2];
+ v_tally4_thr(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS,thr);
}
}
}
}
}
-
- return Stb;
}
/* ----------------------------------------------------------------------
- G spline
+ torsional forces and energy
------------------------------------------------------------------------- */
-double PairAIREBO::gSpline(double costh, double Nij, int typei,
- double *dgdc, double *dgdN)
+void PairAIREBOOMP::TORSION_thr(int ifrom, int ito,
+ int evflag, int eflag, ThrData * const thr)
{
- double coeffs[6],dS,g1,g2,dg1,dg2,cut,g;
- int i,j;
-
- i = 0;
- j = 0;
- g = 0.0;
- cut = 0.0;
- dS = 0.0;
- dg1 = 0.0;
- dg2 = 0.0;
- *dgdc = 0.0;
- *dgdN = 0.0;
-
- // central atom is Carbon
-
- if (typei == 0) {
- if (costh < gCdom[0]) costh = gCdom[0];
- if (costh > gCdom[4]) costh = gCdom[4];
- if (Nij >= NCmax) {
- for (i = 0; i < 4; i++) {
- if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
- for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j];
- }
- }
- g2 = Sp5th(costh,coeffs,&dg2);
- g = g2;
- *dgdc = dg2;
- *dgdN = 0.0;
- }
- if (Nij <= NCmin) {
- for (i = 0; i < 4; i++) {
- if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
- for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j];
- }
- }
- g1 = Sp5th(costh,coeffs,&dg1);
- g = g1;
- *dgdc = dg1;
- *dgdN = 0.0;
- }
- if (Nij > NCmin && Nij < NCmax) {
- for (i = 0; i < 4; i++) {
- if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
- for (j = 0; j < 6; j++) coeffs[j] = gC1[i][j];
- }
- }
- g1 = Sp5th(costh,coeffs,&dg1);
- for (i = 0; i < 4; i++) {
- if (costh >= gCdom[i] && costh <= gCdom[i+1]) {
- for (j = 0; j < 6; j++) coeffs[j] = gC2[i][j];
- }
- }
- g2 = Sp5th(costh,coeffs,&dg2);
- cut = Sp(Nij,NCmin,NCmax,dS);
- g = g2+cut*(g1-g2);
- *dgdc = dg2+(cut*(dg1-dg2));
- *dgdN = dS*(g1-g2);
- }
- }
-
- // central atom is Hydrogen
-
- if (typei == 1) {
- if (costh < gHdom[0]) costh = gHdom[0];
- if (costh > gHdom[3]) costh = gHdom[3];
- for (i = 0; i < 3; i++) {
- if (costh >= gHdom[i] && costh <= gHdom[i+1]) {
- for (j = 0; j < 6; j++) coeffs[j] = gH[i][j];
+ int i,j,k,l,ii,itag,jtag;
+ double evdwl,fpair,xtmp,ytmp,ztmp;
+ double cos321;
+ double w21,dw21,cos234,w34,dw34;
+ double cross321[3],cross321mag,cross234[3],cross234mag;
+ double w23,dw23,cw2,ekijl,Ec;
+ double cw,cwnum,cwnom;
+ double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc;
+ double sin321,sin234,rjk2,rik2,ril2,rjl2;
+ double rjk,ril;
+ double Vtors;
+ double dndij[3],tmpvec[3],dndik[3],dndjl[3];
+ double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil;
+ double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil;
+ double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
+ double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
+ double del32[3],rsq,r32,del23[3],del21[3],r21;
+ double deljk[3],del34[3],delil[3],delkl[3],r23,r34;
+ double fi[3],fj[3],fk[3],fl[3];
+ int itype,jtype,ktype,ltype,kk,ll,jj;
+ int *ilist,*REBO_neighs_i,*REBO_neighs_j;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ int *type = atom->type;
+ int *tag = atom->tag;
+
+ ilist = list->ilist;
+
+ for (ii = ifrom; ii < ito; ii++) {
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ if (itype != 0) continue;
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ REBO_neighs_i = REBO_firstneigh[i];
+
+ for (jj = 0; jj < REBO_numneigh[i]; jj++) {
+ j = REBO_neighs_i[jj];
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
- }
- g = Sp5th(costh,coeffs,&dg1);
- *dgdN = 0.0;
- *dgdc = dg1;
- }
- return g;
-}
+ jtype = map[type[j]];
+ if (jtype != 0) continue;
-/* ----------------------------------------------------------------------
- Pij spline
-------------------------------------------------------------------------- */
+ del32[0] = x[j][0]-x[i][0];
+ del32[1] = x[j][1]-x[i][1];
+ del32[2] = x[j][2]-x[i][2];
+ rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2];
+ r32 = sqrt(rsq);
+ del23[0] = -del32[0];
+ del23[1] = -del32[1];
+ del23[2] = -del32[2];
+ r23 = r32;
+ w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23);
-double PairAIREBO::PijSpline(double NijC, double NijH, int typei, int typej,
- double dN2[2])
-{
- int x,y,i,done;
- double Pij,coeffs[16];
-
- for (i = 0; i < 16; i++) coeffs[i]=0.0;
+ for (kk = 0; kk < REBO_numneigh[i]; kk++) {
+ k = REBO_neighs_i[kk];
+ ktype = map[type[k]];
+ if (k == j) continue;
+ del21[0] = x[i][0]-x[k][0];
+ del21[1] = x[i][1]-x[k][1];
+ del21[2] = x[i][2]-x[k][2];
+ rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2];
+ r21 = sqrt(rsq);
+ cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) +
+ (del21[2]*del32[2])) / (r21*r32);
+ cos321 = MIN(cos321,1.0);
+ cos321 = MAX(cos321,-1.0);
+ sin321 = sqrt(1.0 - cos321*cos321);
+ if (sin321 < TOL) continue;
- x = 0;
- y = 0;
- dN2[0] = 0.0;
- dN2[1] = 0.0;
- done = 0;
+ deljk[0] = del21[0]-del23[0];
+ deljk[1] = del21[1]-del23[1];
+ deljk[2] = del21[2]-del23[2];
+ rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
+ rjk=sqrt(rjk2);
+ rik2 = r21*r21;
+ w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21);
+
+ rij = r32;
+ rik = r21;
+ rij2 = r32*r32;
+ rik2 = r21*r21;
+ costmp = 0.5*(rij2+rik2-rjk2)/rij/rik;
+ tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+ dtsjik = -dtsjik;
+
+ REBO_neighs_j = REBO_firstneigh[j];
+ for (ll = 0; ll < REBO_numneigh[j]; ll++) {
+ l = REBO_neighs_j[ll];
+ ltype = map[type[l]];
+ if (l == i || l == k) continue;
+ del34[0] = x[j][0]-x[l][0];
+ del34[1] = x[j][1]-x[l][1];
+ del34[2] = x[j][2]-x[l][2];
+ rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2];
+ r34 = sqrt(rsq);
+ cos234 = (del32[0]*del34[0] + del32[1]*del34[1] +
+ del32[2]*del34[2]) / (r32*r34);
+ cos234 = MIN(cos234,1.0);
+ cos234 = MAX(cos234,-1.0);
+ sin234 = sqrt(1.0 - cos234*cos234);
+ if (sin234 < TOL) continue;
+ w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34);
+ delil[0] = del23[0] + del34[0];
+ delil[1] = del23[1] + del34[1];
+ delil[2] = del23[2] + del34[2];
+ ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2];
+ ril=sqrt(ril2);
+ rjl2 = r34*r34;
- // if inputs are out of bounds set them back to a point in bounds
+ rjl = r34;
+ rjl2 = r34*r34;
+ costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl;
+ tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+ dtsijl = -dtsijl; //need minus sign
+ cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]);
+ cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]);
+ cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]);
+ cross321mag = sqrt(cross321[0]*cross321[0]+
+ cross321[1]*cross321[1]+
+ cross321[2]*cross321[2]);
+ cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]);
+ cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]);
+ cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]);
+ cross234mag = sqrt(cross234[0]*cross234[0]+
+ cross234[1]*cross234[1]+
+ cross234[2]*cross234[2]);
+ cwnum = (cross321[0]*cross234[0]) +
+ (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
+ cwnom = r21*r34*r32*r32*sin321*sin234;
+ cw = cwnum/cwnom;
- if (typei == 0 && typej == 0) {
- if (NijC < pCCdom[0][0]) NijC=pCCdom[0][0];
- if (NijC > pCCdom[0][1]) NijC=pCCdom[0][1];
- if (NijH < pCCdom[1][0]) NijH=pCCdom[1][0];
- if (NijH > pCCdom[1][1]) NijH=pCCdom[1][1];
+ cw2 = (.5*(1.0-cw));
+ ekijl = epsilonT[ktype][ltype];
+ Ec = 256.0*ekijl/405.0;
+ Vtors = (Ec*(pow(cw2,5.0)))-(ekijl/10.0);
- if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) {
- Pij = PCCf[(int) NijC][(int) NijH];
- dN2[0] = PCCdfdx[(int) NijC][(int) NijH];
- dN2[1] = PCCdfdy[(int) NijC][(int) NijH];
- done = 1;
- }
- if (done == 0) {
- x = (int) (floor(NijC));
- y = (int) (floor(NijH));
- for (i = 0; i<16; i++) coeffs[i] = pCC[x][y][i];
- Pij = Spbicubic(NijC,NijH,coeffs,dN2);
- }
- }
+ if (eflag) evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
- // if inputs are out of bounds set them back to a point in bounds
-
- if (typei == 0 && typej == 1){
- if (NijC < pCHdom[0][0]) NijC=pCHdom[0][0];
- if (NijC > pCHdom[0][1]) NijC=pCHdom[0][1];
- if (NijH < pCHdom[1][0]) NijH=pCHdom[1][0];
- if (NijH > pCHdom[1][1]) NijH=pCHdom[1][1];
-
- if (fabs(NijC-floor(NijC)) < TOL && fabs(NijH-floor(NijH)) < TOL) {
- Pij = PCHf[(int) NijC][(int) NijH];
- dN2[0] = PCHdfdx[(int) NijC][(int) NijH];
- dN2[1] = PCHdfdy[(int) NijC][(int) NijH];
- done = 1;
- }
- if (done == 0) {
- x = (int) (floor(NijC));
- y = (int) (floor(NijH));
- for (i = 0; i<16; i++) coeffs[i] = pCH[x][y][i];
- Pij = Spbicubic(NijC,NijH,coeffs,dN2);
- }
- }
-
- if (typei == 1 && typej == 0) {
- Pij = 0.0;
- dN2[0] = 0.0;
- dN2[1] = 0.0;
- }
+ dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
+ dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
+ dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]);
+ tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]);
+ tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]);
+ tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]);
- if (typei == 1 && typej == 1) {
- Pij = 0.0;
- dN2[0] = 0.0;
- dN2[1] = 0.0;
- }
- return Pij;
-}
+ dndij[0] = dndij[0]+tmpvec[0];
+ dndij[1] = dndij[1]+tmpvec[1];
+ dndij[2] = dndij[2]+tmpvec[2];
-/* ----------------------------------------------------------------------
- PiRC spline
-------------------------------------------------------------------------- */
+ dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]);
+ dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]);
+ dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]);
-double PairAIREBO::piRCSpline(double Nij, double Nji, double Nijconj,
- int typei, int typej, double dN3[3])
-{
- int x,y,z,i,done;
- double piRC,coeffs[64];
- x=0;
- y=0;
- z=0;
- i=0;
-
- done=0;
-
- for (i=0; i<64; i++) coeffs[i]=0.0;
-
- if (typei==0 && typej==0) {
- //if the inputs are out of bounds set them back to a point in bounds
- if (Nij<piCCdom[0][0]) Nij=piCCdom[0][0];
- if (Nij>piCCdom[0][1]) Nij=piCCdom[0][1];
- if (Nji<piCCdom[1][0]) Nji=piCCdom[1][0];
- if (Nji>piCCdom[1][1]) Nji=piCCdom[1][1];
- if (Nijconj<piCCdom[2][0]) Nijconj=piCCdom[2][0];
- if (Nijconj>piCCdom[2][1]) Nijconj=piCCdom[2][1];
-
- if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
- fabs(Nijconj-floor(Nijconj))<TOL) {
- piRC=piCCf[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[0]=piCCdfdx[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[1]=piCCdfdy[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[2]=piCCdfdz[(int) Nij][(int) Nji][(int) Nijconj];
- done=1;
- }
+ dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]);
+ dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]);
+ dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]);
- if (done==0) {
- for (i=0; i<piCCdom[0][1]; i++)
- if (Nij>=(double) i && Nij<=(double) i+1 || Nij==(double) i) x=i;
- for (i=0; i<piCCdom[1][1]; i++)
- if (Nji>=(double) i && Nji<=(double) i+1 || Nji==(double) i) y=i;
- for (i=0; i<piCCdom[2][1]; i++)
- if (Nijconj>=(double) i && Nijconj<=(double) i+1 ||
- Nijconj==(double) i) z=i;
-
- for (i=0; i<64; i++) coeffs[i]=piCC[x][y][z][i];
- piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
- }
- }
-
-
- // CH interaction
-
- if (typei==0 && typej==1 || typei==1 && typej==0) {
- // if the inputs are out of bounds set them back to a point in bounds
-
- if (Nij<piCHdom[0][0] || Nij>piCHdom[0][1] ||
- Nji<piCHdom[1][0] || Nji>piCHdom[1][1] ||
- Nijconj<piCHdom[2][0] || Nijconj>piCHdom[2][1]) {
- if (Nij<piCHdom[0][0]) Nij=piCHdom[0][0];
- if (Nij>piCHdom[0][1]) Nij=piCHdom[0][1];
- if (Nji<piCHdom[1][0]) Nji=piCHdom[1][0];
- if (Nji>piCHdom[1][1]) Nji=piCHdom[1][1];
- if (Nijconj<piCHdom[2][0]) Nijconj=piCHdom[2][0];
- if (Nijconj>piCHdom[2][1]) Nijconj=piCHdom[2][1];
- }
+ dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21);
+ dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21);
+ dcidjk = (-rjk)/(r23*r21);
+ dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34);
+ dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34);
+ dcjdil = (-ril)/(r23*r34);
- if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
- fabs(Nijconj-floor(Nijconj))<TOL) {
- piRC=piCHf[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[0]=piCHdfdx[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[1]=piCHdfdy[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[2]=piCHdfdz[(int) Nij][(int) Nji][(int) Nijconj];
- done=1;
- }
+ dsidij = (-cos321/sin321)*dcidij;
+ dsidik = (-cos321/sin321)*dcidik;
+ dsidjk = (-cos321/sin321)*dcidjk;
- if (done==0) {
- for (i=0; i<piCHdom[0][1]; i++)
- if (Nij>=i && Nij<=i+1) x=i;
- for (i=0; i<piCHdom[1][1]; i++)
- if (Nji>=i && Nji<=i+1) y=i;
- for (i=0; i<piCHdom[2][1]; i++)
- if (Nijconj>=i && Nijconj<=i+1) z=i;
+ dsjdji = (-cos234/sin234)*dcjdji;
+ dsjdjl = (-cos234/sin234)*dcjdjl;
+ dsjdil = (-cos234/sin234)*dcjdil;
- for (i=0; i<64; i++) coeffs[i]=piCH[x][y][z][i];
- piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
- }
- }
-
- if (typei==1 && typej==1) {
- if (Nij<piHHdom[0][0] || Nij>piHHdom[0][1] ||
- Nji<piHHdom[1][0] || Nji>piHHdom[1][1] ||
- Nijconj<piHHdom[2][0] || Nijconj>piHHdom[2][1]) {
- Nij=0.0;
- Nji=0.0;
- Nijconj=0.0;
- }
- if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
- fabs(Nijconj-floor(Nijconj))<TOL) {
- piRC=piHHf[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[0]=piHHdfdx[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[1]=piHHdfdy[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[2]=piHHdfdz[(int) Nij][(int) Nji][(int) Nijconj];
- done=1;
- }
- if (done==0) {
- for (i=0; i<piHHdom[0][1]; i++)
- if (Nij>=i && Nij<=i+1) x=i;
- for (i=0; i<piHHdom[1][1]; i++)
- if (Nji>=i && Nji<=i+1) y=i;
- for (i=0; i<piHHdom[2][1]; i++)
- if (Nijconj>=i && Nijconj<=i+1) z=i;
-
- for (i=0; i<64; i++) coeffs[i]=piHH[x][y][z][i];
- piRC=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
- }
- }
+ dxidij = (r21*sin321)+(r23*r21*dsidij);
+ dxidik = (r23*sin321)+(r23*r21*dsidik);
+ dxidjk = (r23*r21*dsidjk);
- return piRC;
-}
+ dxjdji = (r34*sin234)+(r23*r34*dsjdji);
+ dxjdjl = (r23*sin234)+(r23*r34*dsjdjl);
+ dxjdil = (r23*r34*dsjdil);
-/* ----------------------------------------------------------------------
- Tij spline
-------------------------------------------------------------------------- */
+ ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji);
+ ddndik = dxidik*cross234mag;
+ ddndjk = dxidjk*cross234mag;
+ ddndjl = cross321mag*dxjdjl;
+ ddndil = cross321mag*dxjdil;
+ dcwddn = -cwnum/(cwnom*cwnom);
+ dcwdn = 1.0/cwnom;
+ dvpdcw = (-1.0)*Ec*(-.5)*5.0*pow(cw2,4.0) *
+ w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
-double PairAIREBO::TijSpline(double Nij, double Nji,
- double Nijconj, double dN3[3])
-{
- int x,y,z,i,done;
- double Tijf,coeffs[64];
-
- x=0;
- y=0;
- z=0;
- i=0;
- Tijf=0.0;
- done=0;
- for (i=0; i<64; i++) coeffs[i]=0.0;
-
- //if the inputs are out of bounds set them back to a point in bounds
-
- if (Nij<Tijdom[0][0]) Nij=Tijdom[0][0];
- if (Nij>Tijdom[0][1]) Nij=Tijdom[0][1];
- if (Nji<Tijdom[1][0]) Nji=Tijdom[1][0];
- if (Nji>Tijdom[1][1]) Nji=Tijdom[1][1];
- if (Nijconj<Tijdom[2][0]) Nijconj=Tijdom[2][0];
- if (Nijconj>Tijdom[2][1]) Nijconj=Tijdom[2][1];
-
- if (fabs(Nij-floor(Nij))<TOL && fabs(Nji-floor(Nji))<TOL &&
- fabs(Nijconj-floor(Nijconj))<TOL) {
- Tijf=Tf[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[0]=Tdfdx[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[1]=Tdfdy[(int) Nij][(int) Nji][(int) Nijconj];
- dN3[2]=Tdfdz[(int) Nij][(int) Nji][(int) Nijconj];
- done=1;
- }
+ Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
+ Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
+ Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
+ fi[0] = Ftmp[0];
+ fi[1] = Ftmp[1];
+ fi[2] = Ftmp[2];
+ fj[0] = -Ftmp[0];
+ fj[1] = -Ftmp[1];
+ fj[2] = -Ftmp[2];
- if (done==0) {
- for (i=0; i<Tijdom[0][1]; i++)
- if (Nij>=i && Nij<=i+1) x=i;
- for (i=0; i<Tijdom[1][1]; i++)
- if (Nji>=i && Nji<=i+1) y=i;
- for (i=0; i<Tijdom[2][1]; i++)
- if (Nijconj>=i && Nijconj<=i+1) z=i;
+ Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
+ Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
+ Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
+ fi[0] += Ftmp[0];
+ fi[1] += Ftmp[1];
+ fi[2] += Ftmp[2];
+ fk[0] = -Ftmp[0];
+ fk[1] = -Ftmp[1];
+ fk[2] = -Ftmp[2];
- for (i=0; i<64; i++) coeffs[i]=Tijc[x][y][z][i];
- Tijf=Sptricubic(Nij,Nji,Nijconj,coeffs,dN3);
- }
+ Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
+ Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
+ Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
+ fj[0] += Ftmp[0];
+ fj[1] += Ftmp[1];
+ fj[2] += Ftmp[2];
+ fk[0] -= Ftmp[0];
+ fk[1] -= Ftmp[1];
+ fk[2] -= Ftmp[2];
- return Tijf;
-}
+ Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
+ Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
+ Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
+ fj[0] += Ftmp[0];
+ fj[1] += Ftmp[1];
+ fj[2] += Ftmp[2];
+ fl[0] = -Ftmp[0];
+ fl[1] = -Ftmp[1];
+ fl[2] = -Ftmp[2];
-/* ----------------------------------------------------------------------
- add pages to REBO neighbor list
-------------------------------------------------------------------------- */
+ Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
+ Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
+ Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
+ fi[0] += Ftmp[0];
+ fi[1] += Ftmp[1];
+ fi[2] += Ftmp[2];
+ fl[0] -= Ftmp[0];
+ fl[1] -= Ftmp[1];
+ fl[2] -= Ftmp[2];
-void PairAIREBO::add_pages()
-{
- int toppage = maxpage;
- maxpage += PGDELTA;
+ // coordination forces
- pages = (int **)
- memory->srealloc(pages,maxpage*sizeof(int *),"AIREBO:pages");
- for (int i = toppage; i < maxpage; i++)
- memory->create(pages[i],pgsize,"AIREBO:pages[i]");
-}
+ fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
+ fi[0] -= del21[0]*fpair;
+ fi[1] -= del21[1]*fpair;
+ fi[2] -= del21[2]*fpair;
+ fk[0] += del21[0]*fpair;
+ fk[1] += del21[1]*fpair;
+ fk[2] += del21[2]*fpair;
-/* ----------------------------------------------------------------------
- read AIREBO potential file
-------------------------------------------------------------------------- */
+ fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
+ fi[0] -= del23[0]*fpair;
+ fi[1] -= del23[1]*fpair;
+ fi[2] -= del23[2]*fpair;
+ fj[0] += del23[0]*fpair;
+ fj[1] += del23[1]*fpair;
+ fj[2] += del23[2]*fpair;
-void PairAIREBO::read_file(char *filename)
-{
- int i,j,k,l,limit;
- char s[MAXLINE];
-
- // REBO Parameters (AIREBO)
-
- double rcmin_CC,rcmin_CH,rcmin_HH,rcmax_CC,rcmax_CH,
- rcmax_HH,rcmaxp_CC,rcmaxp_CH,rcmaxp_HH;
- double Q_CC,Q_CH,Q_HH,alpha_CC,alpha_CH,alpha_HH,A_CC,A_CH,A_HH;
- double BIJc_CC1,BIJc_CC2,BIJc_CC3,BIJc_CH1,BIJc_CH2,BIJc_CH3,
- BIJc_HH1,BIJc_HH2,BIJc_HH3;
- double Beta_CC1,Beta_CC2,Beta_CC3,Beta_CH1,Beta_CH2,Beta_CH3,
- Beta_HH1,Beta_HH2,Beta_HH3;
- double rho_CC,rho_CH,rho_HH;
-
- // LJ Parameters (AIREBO)
-
- double rcLJmin_CC,rcLJmin_CH,rcLJmin_HH,rcLJmax_CC,rcLJmax_CH,
- rcLJmax_HH,bLJmin_CC;
- double bLJmin_CH,bLJmin_HH,bLJmax_CC,bLJmax_CH,bLJmax_HH,
- epsilon_CC,epsilon_CH,epsilon_HH;
- double sigma_CC,sigma_CH,sigma_HH,epsilonT_CCCC,epsilonT_CCCH,epsilonT_HCCH;
-
- MPI_Comm_rank(world,&me);
-
- // read file on proc 0
-
- if (me == 0) {
- FILE *fp = fopen(filename,"r");
- if (fp == NULL) {
- char str[128];
- sprintf(str,"Cannot open AIREBO potential file %s",filename);
- error->one(FLERR,str);
- }
+ fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
+ fj[0] -= del34[0]*fpair;
+ fj[1] -= del34[1]*fpair;
+ fj[2] -= del34[2]*fpair;
+ fl[0] += del34[0]*fpair;
+ fl[1] += del34[1]*fpair;
+ fl[2] += del34[2]*fpair;
- // skip initial comment lines
+ // additional cut off function forces
- while (1) {
- fgets(s,MAXLINE,fp);
- if (s[0] != '#') break;
- }
-
- // read parameters
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmin_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmin_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmin_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmax_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmax_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmax_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmaxp_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmaxp_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcmaxp_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&smin);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Nmin);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Nmax);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&NCmin);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&NCmax);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Q_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Q_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Q_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&alpha_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&alpha_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&alpha_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&A_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&A_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&A_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CC1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CC2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CC3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CH1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CH2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_CH3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_HH1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_HH2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&BIJc_HH3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CC1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CC2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CC3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CH1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CH2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_CH3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_HH1);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_HH2);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Beta_HH3);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rho_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rho_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rho_HH);
-
- // LJ parameters
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmin_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmin_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmin_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmax_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmax_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&rcLJmax_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmin_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmin_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmin_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmax_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmax_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&bLJmax_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilon_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilon_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilon_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&sigma_CC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&sigma_CH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&sigma_HH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilonT_CCCC);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilonT_CCCH);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&epsilonT_HCCH);
-
- // gC spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- // number-1 = # of domains for the spline
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit; i++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&gCdom[i]);
- }
- fgets(s,MAXLINE,fp);
- for (i = 0; i < limit-1; i++) {
- for (j = 0; j < 6; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&gC1[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
- for (i = 0; i < limit-1; i++) {
- for (j = 0; j < 6; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&gC2[i][j]);
- }
- }
-
- // gH spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit; i++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&gHdom[i]);
- }
-
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < limit-1; i++) {
- for (j = 0; j < 6; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&gH[i][j]);
- }
- }
-
- // pCC spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/2; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&pCCdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) pCCdom[0][1]; i++) {
- for (j = 0; j < (int) pCCdom[1][1]; j++) {
- for (k = 0; k < 16; k++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&pCC[i][j][k]);
- }
- }
- }
-
- // pCH spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/2; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&pCHdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) pCHdom[0][1]; i++) {
- for (j = 0; j < (int) pCHdom[1][1]; j++) {
- for (k = 0; k < 16; k++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&pCH[i][j][k]);
- }
- }
- }
-
- // piCC cpline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/3; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piCCdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) piCCdom[0][1]; i++) {
- for (j = 0; j < (int) piCCdom[1][1]; j++) {
- for (k = 0; k < (int) piCCdom[2][1]; k++) {
- for (l = 0; l < 64; l = l+1) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piCC[i][j][k][l]);
- }
- }
- }
- }
-
- // piCH spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/3; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piCHdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) piCHdom[0][1]; i++) {
- for (j = 0; j < (int) piCHdom[1][1]; j++) {
- for (k = 0; k < (int) piCHdom[2][1]; k++) {
- for (l = 0; l < 64; l = l+1) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piCH[i][j][k][l]);
- }
- }
- }
- }
-
- // piHH spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/3; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piHHdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) piHHdom[0][1]; i++) {
- for (j = 0; j < (int) piHHdom[1][1]; j++) {
- for (k = 0; k < (int) piHHdom[2][1]; k++) {
- for (l = 0; l < 64; l = l+1) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&piHH[i][j][k][l]);
- }
- }
- }
- }
-
- // Tij spline
-
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
- fgets(s,MAXLINE,fp);
-
- fgets(s,MAXLINE,fp);
- sscanf(s,"%d",&limit);
-
- for (i = 0; i < limit/2; i++) {
- for (j = 0; j < limit/3; j++) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Tijdom[i][j]);
- }
- }
- fgets(s,MAXLINE,fp);
-
- for (i = 0; i < (int) Tijdom[0][1]; i++) {
- for (j = 0; j < (int) Tijdom[1][1]; j++) {
- for (k = 0; k < (int) Tijdom[2][1]; k++) {
- for (l = 0; l < 64; l = l+1) {
- fgets(s,MAXLINE,fp);
- sscanf(s,"%lg",&Tijc[i][j][k][l]);
- }
- }
- }
- }
-
- fclose(fp);
- }
-
- // store read-in values in arrays
-
- if (me == 0) {
-
- // REBO
-
- rcmin[0][0] = rcmin_CC;
- rcmin[0][1] = rcmin_CH;
- rcmin[1][0] = rcmin[0][1];
- rcmin[1][1] = rcmin_HH;
-
- rcmax[0][0] = rcmax_CC;
- rcmax[0][1] = rcmax_CH;
- rcmax[1][0] = rcmax[0][1];
- rcmax[1][1] = rcmax_HH;
-
- rcmaxsq[0][0] = rcmax[0][0]*rcmax[0][0];
- rcmaxsq[1][0] = rcmax[1][0]*rcmax[1][0];
- rcmaxsq[0][1] = rcmax[0][1]*rcmax[0][1];
- rcmaxsq[1][1] = rcmax[1][1]*rcmax[1][1];
-
- rcmaxp[0][0] = rcmaxp_CC;
- rcmaxp[0][1] = rcmaxp_CH;
- rcmaxp[1][0] = rcmaxp[0][1];
- rcmaxp[1][1] = rcmaxp_HH;
-
- Q[0][0] = Q_CC;
- Q[0][1] = Q_CH;
- Q[1][0] = Q[0][1];
- Q[1][1] = Q_HH;
-
- alpha[0][0] = alpha_CC;
- alpha[0][1] = alpha_CH;
- alpha[1][0] = alpha[0][1];
- alpha[1][1] = alpha_HH;
-
- A[0][0] = A_CC;
- A[0][1] = A_CH;
- A[1][0] = A[0][1];
- A[1][1] = A_HH;
-
- rho[0][0] = rho_CC;
- rho[0][1] = rho_CH;
- rho[1][0] = rho[0][1];
- rho[1][1] = rho_HH;
-
- BIJc[0][0][0] = BIJc_CC1;
- BIJc[0][0][1] = BIJc_CC2;
- BIJc[0][0][2] = BIJc_CC3;
- BIJc[0][1][0] = BIJc_CH1;
- BIJc[0][1][1] = BIJc_CH2;
- BIJc[0][1][2] = BIJc_CH3;
- BIJc[1][0][0] = BIJc_CH1;
- BIJc[1][0][1] = BIJc_CH2;
- BIJc[1][0][2] = BIJc_CH3;
- BIJc[1][1][0] = BIJc_HH1;
- BIJc[1][1][1] = BIJc_HH2;
- BIJc[1][1][2] = BIJc_HH3;
-
- Beta[0][0][0] = Beta_CC1;
- Beta[0][0][1] = Beta_CC2;
- Beta[0][0][2] = Beta_CC3;
- Beta[0][1][0] = Beta_CH1;
- Beta[0][1][1] = Beta_CH2;
- Beta[0][1][2] = Beta_CH3;
- Beta[1][0][0] = Beta_CH1;
- Beta[1][0][1] = Beta_CH2;
- Beta[1][0][2] = Beta_CH3;
- Beta[1][1][0] = Beta_HH1;
- Beta[1][1][1] = Beta_HH2;
- Beta[1][1][2] = Beta_HH3;
-
- // LJ
-
- rcLJmin[0][0] = rcLJmin_CC;
- rcLJmin[0][1] = rcLJmin_CH;
- rcLJmin[1][0] = rcLJmin[0][1];
- rcLJmin[1][1] = rcLJmin_HH;
-
- rcLJmax[0][0] = rcLJmax_CC;
- rcLJmax[0][1] = rcLJmax_CH;
- rcLJmax[1][0] = rcLJmax[0][1];
- rcLJmax[1][1] = rcLJmax_HH;
-
- rcLJmaxsq[0][0] = rcLJmax[0][0]*rcLJmax[0][0];
- rcLJmaxsq[1][0] = rcLJmax[1][0]*rcLJmax[1][0];
- rcLJmaxsq[0][1] = rcLJmax[0][1]*rcLJmax[0][1];
- rcLJmaxsq[1][1] = rcLJmax[1][1]*rcLJmax[1][1];
-
- bLJmin[0][0] = bLJmin_CC;
- bLJmin[0][1] = bLJmin_CH;
- bLJmin[1][0] = bLJmin[0][1];
- bLJmin[1][1] = bLJmin_HH;
-
- bLJmax[0][0] = bLJmax_CC;
- bLJmax[0][1] = bLJmax_CH;
- bLJmax[1][0] = bLJmax[0][1];
- bLJmax[1][1] = bLJmax_HH;
-
- epsilon[0][0] = epsilon_CC;
- epsilon[0][1] = epsilon_CH;
- epsilon[1][0] = epsilon[0][1];
- epsilon[1][1] = epsilon_HH;
-
- sigma[0][0] = sigma_CC;
- sigma[0][1] = sigma_CH;
- sigma[1][0] = sigma[0][1];
- sigma[1][1] = sigma_HH;
-
- // torsional
-
- thmin = -1.0;
- thmax = -0.995;
- epsilonT[0][0] = epsilonT_CCCC;
- epsilonT[0][1] = epsilonT_CCCH;
- epsilonT[1][0] = epsilonT[0][1];
- epsilonT[1][1] = epsilonT_HCCH;
- }
-
- // broadcast read-in and setup values
-
- MPI_Bcast(&thmin,1,MPI_DOUBLE,0,world);
- MPI_Bcast(&thmax,1,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&smin,1,MPI_DOUBLE,0,world);
- MPI_Bcast(&Nmin,1,MPI_DOUBLE,0,world);
- MPI_Bcast(&Nmax,1,MPI_DOUBLE,0,world);
- MPI_Bcast(&NCmin,1,MPI_DOUBLE,0,world);
- MPI_Bcast(&NCmax,1,MPI_DOUBLE,0,world);
-
-
- MPI_Bcast(&rcmin[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcmax[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcmaxsq[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcmaxp[0][0],4,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&Q[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&alpha[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&A[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rho[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&BIJc[0][0][0],12,MPI_DOUBLE,0,world);
- MPI_Bcast(&Beta[0][0][0],12,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcLJmaxsq[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&rcLJmin[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&rcLJmax[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&bLJmin[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&bLJmax[0][0],4,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&epsilon[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&sigma[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&epsilonT[0][0],4,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&gCdom[0],5,MPI_DOUBLE,0,world);
- MPI_Bcast(&gC1[0][0],24,MPI_DOUBLE,0,world);
- MPI_Bcast(&gC2[0][0],24,MPI_DOUBLE,0,world);
- MPI_Bcast(&gHdom[0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&gH[0][0],18,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&pCCdom[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&pCHdom[0][0],4,MPI_DOUBLE,0,world);
- MPI_Bcast(&pCC[0][0][0],256,MPI_DOUBLE,0,world);
- MPI_Bcast(&pCH[0][0][0],256,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&piCCdom[0][0],6,MPI_DOUBLE,0,world);
- MPI_Bcast(&piCHdom[0][0],6,MPI_DOUBLE,0,world);
- MPI_Bcast(&piHHdom[0][0],6,MPI_DOUBLE,0,world);
- MPI_Bcast(&piCC[0][0][0][0],9216,MPI_DOUBLE,0,world);
- MPI_Bcast(&piCH[0][0][0][0],9216,MPI_DOUBLE,0,world);
- MPI_Bcast(&piHH[0][0][0][0],9216,MPI_DOUBLE,0,world);
-
- MPI_Bcast(&Tijdom[0][0],6,MPI_DOUBLE,0,world);
- MPI_Bcast(&Tijc[0][0][0][0],9216,MPI_DOUBLE,0,world);
-}
+ fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
+ fpair = fcpc*dcidij/rij;
+ fi[0] += fpair*del23[0];
+ fi[1] += fpair*del23[1];
+ fi[2] += fpair*del23[2];
+ fj[0] -= fpair*del23[0];
+ fj[1] -= fpair*del23[1];
+ fj[2] -= fpair*del23[2];
-// ----------------------------------------------------------------------
-// generic Spline functions
-// ----------------------------------------------------------------------
+ fpair = fcpc*dcidik/rik;
+ fi[0] += fpair*del21[0];
+ fi[1] += fpair*del21[1];
+ fi[2] += fpair*del21[2];
+ fk[0] -= fpair*del21[0];
+ fk[1] -= fpair*del21[1];
+ fk[2] -= fpair*del21[2];
-/* ----------------------------------------------------------------------
- fifth order spline evaluation
-------------------------------------------------------------------------- */
+ fpair = fcpc*dcidjk/rjk;
+ fj[0] += fpair*deljk[0];
+ fj[1] += fpair*deljk[1];
+ fj[2] += fpair*deljk[2];
+ fk[0] -= fpair*deljk[0];
+ fk[1] -= fpair*deljk[1];
+ fk[2] -= fpair*deljk[2];
-double PairAIREBO::Sp5th(double x, double coeffs[6], double *df)
-{
- double f, d;
- const double x2 = x*x;
- const double x3 = x2*x;
-
- f = coeffs[0];
- f += coeffs[1]*x;
- d = coeffs[1];
- f += coeffs[2]*x2;
- d += 2.0*coeffs[2]*x;
- f += coeffs[3]*x3;
- d += 3.0*coeffs[3]*x2;
- f += coeffs[4]*x2*x2;
- d += 4.0*coeffs[4]*x3;
- f += coeffs[5]*x2*x3;
- d += 5.0*coeffs[5]*x2*x2;
-
- *df = d;
- return f;
-}
+ fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
+ fpair = fcpc*dcjdji/rij;
+ fi[0] += fpair*del23[0];
+ fi[1] += fpair*del23[1];
+ fi[2] += fpair*del23[2];
+ fj[0] -= fpair*del23[0];
+ fj[1] -= fpair*del23[1];
+ fj[2] -= fpair*del23[2];
-/* ----------------------------------------------------------------------
- bicubic spline evaluation
-------------------------------------------------------------------------- */
+ fpair = fcpc*dcjdjl/rjl;
+ fj[0] += fpair*del34[0];
+ fj[1] += fpair*del34[1];
+ fj[2] += fpair*del34[2];
+ fl[0] -= fpair*del34[0];
+ fl[1] -= fpair*del34[1];
+ fl[2] -= fpair*del34[2];
-double PairAIREBO::Spbicubic(double x, double y,
- double coeffs[16], double df[2])
-{
- double f,xn,yn,xn1,yn1,c;
- int i,j;
-
- f = 0.0;
- df[0] = 0.0;
- df[1] = 0.0;
-
- xn = 1.0;
- for (i = 0; i < 4; i++) {
- yn = 1.0;
- for (j = 0; j < 4; j++) {
- c = coeffs[i*4+j];
-
- f += c*xn*yn;
- if (i > 0) df[0] += c * ((double) i) * xn1 * yn;
- if (j > 0) df[1] += c * ((double) j) * xn * yn1;
-
- yn1 = yn;
- yn *= y;
- }
- xn1 = xn;
- xn *= x;
- }
+ fpair = fcpc*dcjdil/ril;
+ fi[0] += fpair*delil[0];
+ fi[1] += fpair*delil[1];
+ fi[2] += fpair*delil[2];
+ fl[0] -= fpair*delil[0];
+ fl[1] -= fpair*delil[1];
+ fl[2] -= fpair*delil[2];
- return f;
-}
+ // sum per-atom forces into atom force array
-/* ----------------------------------------------------------------------
- tricubic spline evaluation
-------------------------------------------------------------------------- */
+ f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
+ f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
+ f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
+ f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
-double PairAIREBO::Sptricubic(double x, double y, double z,
- double coeffs[64], double df[3])
-{
- double f,ir,jr,kr,xn,yn,zn,xn1,yn1,zn1,c;
- int i,j,k;
-
- f = 0.0;
- df[0] = 0.0;
- df[1] = 0.0;
- df[2] = 0.0;
-
- xn = 1.0;
- for (i = 0; i < 4; i++) {
- ir = (double) i;
- yn = 1.0;
- for (j = 0; j < 4; j++) {
- jr = (double) j;
- zn = 1.0;
- for (k = 0; k < 4; k++) {
- kr = (double) k;
- c = coeffs[16*i+4*j+k];
- f += c*xn*yn*zn;
- if (i > 0) df[0] += c * ir * xn1 * yn * zn;
- if (j > 0) df[1] += c * jr * xn * yn1 * zn;
- if (k > 0) df[2] += c * kr * xn * yn * zn1;
- zn1 = zn;
- zn *= z;
+ if (evflag) {
+ delkl[0] = delil[0] - del21[0];
+ delkl[1] = delil[1] - del21[1];
+ delkl[2] = delil[2] - del21[2];
+ ev_tally4_thr(this,i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl,thr);
+ }
+ }
}
- yn1 = yn;
- yn *= y;
}
- xn1 = xn;
- xn *= x;
}
-
- return f;
}
/* ----------------------------------------------------------------------
- initialize spline knot values
+ create REBO neighbor list from main neighbor list
+ REBO neighbor list stores neighbors of ghost atoms
------------------------------------------------------------------------- */
-void PairAIREBO::spline_init()
+void PairAIREBOOMP::REBO_neigh_thr()
{
- int i,j,k;
-
- for (i = 0; i < 5; i++) {
- for (j = 0; j < 5; j++) {
- PCCf[i][j] = 0.0;
- PCCdfdx[i][j] = 0.0;
- PCCdfdy[i][j] = 0.0;
- PCHf[i][j] = 0.0;
- PCHdfdx[i][j] = 0.0;
- PCHdfdy[i][j] = 0.0;
- }
- }
-
- PCCf[0][2] = -0.00050;
- PCCf[0][3] = 0.0161253646;
- PCCf[1][1] = -0.010960;
- PCCf[1][2] = 0.00632624824;
- PCCf[2][0] = -0.0276030;
- PCCf[2][1] = 0.00317953083;
-
- PCHf[0][1] = 0.209336733;
- PCHf[0][2] = -0.0644496154;
- PCHf[0][3] = -0.303927546;
- PCHf[1][0] = 0.010;
- PCHf[1][1] = -0.125123401;
- PCHf[1][2] = -0.298905246;
- PCHf[2][0] = -0.122042146;
- PCHf[2][1] = -0.300529172;
- PCHf[3][0] = -0.307584705;
-
- for (i = 0; i < 5; i++) {
- for (j = 0; j < 5; j++) {
- for (k = 0; k < 10; k++) {
- piCCf[i][j][k] = 0.0;
- piCCdfdx[i][j][k] = 0.0;
- piCCdfdy[i][j][k] = 0.0;
- piCCdfdz[i][j][k] = 0.0;
- piCHf[i][j][k] = 0.0;
- piCHdfdx[i][j][k] = 0.0;
- piCHdfdy[i][j][k] = 0.0;
- piCHdfdz[i][j][k] = 0.0;
- piHHf[i][j][k] = 0.0;
- piHHdfdx[i][j][k] = 0.0;
- piHHdfdy[i][j][k] = 0.0;
- piHHdfdz[i][j][k] = 0.0;
- Tf[i][j][k] = 0.0;
- Tdfdx[i][j][k] = 0.0;
- Tdfdy[i][j][k] = 0.0;
- Tdfdz[i][j][k] = 0.0;
- }
- }
- }
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
- for (i = 3; i < 10; i++) piCCf[0][0][i] = 0.0049586079;
- piCCf[1][0][1] = 0.021693495;
- piCCf[0][1][1] = 0.021693495;
- for (i = 2; i < 10; i++) piCCf[1][0][i] = 0.0049586079;
- for (i = 2; i < 10; i++) piCCf[0][1][i] = 0.0049586079;
- piCCf[1][1][1] = 0.05250;
- piCCf[1][1][2] = -0.002088750;
- for (i = 3; i < 10; i++) piCCf[1][1][i] = -0.00804280;
- piCCf[2][0][1] = 0.024698831850;
- piCCf[0][2][1] = 0.024698831850;
- piCCf[2][0][2] = -0.00597133450;
- piCCf[0][2][2] = -0.00597133450;
- for (i = 3; i < 10; i++) piCCf[2][0][i] = 0.0049586079;
- for (i = 3; i < 10; i++) piCCf[0][2][i] = 0.0049586079;
- piCCf[2][1][1] = 0.00482478490;
- piCCf[1][2][1] = 0.00482478490;
- piCCf[2][1][2] = 0.0150;
- piCCf[1][2][2] = 0.0150;
- piCCf[2][1][3] = -0.010;
- piCCf[1][2][3] = -0.010;
- piCCf[2][1][4] = -0.01168893870;
- piCCf[1][2][4] = -0.01168893870;
- piCCf[2][1][5] = -0.013377877400;
- piCCf[1][2][5] = -0.013377877400;
- piCCf[2][1][6] = -0.015066816000;
- piCCf[1][2][6] = -0.015066816000;
- for (i = 7; i < 10; i++) piCCf[2][1][i] = -0.015066816000;
- for (i = 7; i < 10; i++) piCCf[1][2][i] = -0.015066816000;
- piCCf[2][2][1] = 0.0472247850;
- piCCf[2][2][2] = 0.0110;
- piCCf[2][2][3] = 0.0198529350;
- piCCf[2][2][4] = 0.01654411250;
- piCCf[2][2][5] = 0.013235290;
- piCCf[2][2][6] = 0.00992646749999 ;
- piCCf[2][2][7] = 0.006617644999;
- piCCf[2][2][8] = 0.00330882250;
- piCCf[3][0][1] = -0.05989946750;
- piCCf[0][3][1] = -0.05989946750;
- piCCf[3][0][2] = -0.05989946750;
- piCCf[0][3][2] = -0.05989946750;
- for (i = 3; i < 10; i++) piCCf[3][0][i] = 0.0049586079;
- for (i = 3; i < 10; i++) piCCf[0][3][i] = 0.0049586079;
- piCCf[3][1][2] = -0.0624183760;
- piCCf[1][3][2] = -0.0624183760;
- for (i = 3; i < 10; i++) piCCf[3][1][i] = -0.0624183760;
- for (i = 3; i < 10; i++) piCCf[1][3][i] = -0.0624183760;
- piCCf[3][2][1] = -0.02235469150;
- piCCf[2][3][1] = -0.02235469150;
- for (i = 2; i < 10; i++) piCCf[3][2][i] = -0.02235469150;
- for (i = 2; i < 10; i++) piCCf[2][3][i] = -0.02235469150;
-
- piCCdfdx[2][1][1] = -0.026250;
- piCCdfdx[2][1][5] = -0.0271880;
- piCCdfdx[2][1][6] = -0.0271880;
- for (i = 7; i < 10; i++) piCCdfdx[2][1][i] = -0.0271880;
- piCCdfdx[1][3][2] = 0.0187723882;
- for (i = 2; i < 10; i++) piCCdfdx[2][3][i] = 0.031209;
-
- piCCdfdy[1][2][1] = -0.026250;
- piCCdfdy[1][2][5] = -0.0271880;
- piCCdfdy[1][2][6] = -0.0271880;
- for (i = 7; i < 10; i++) piCCdfdy[1][2][i] = -0.0271880;
- piCCdfdy[3][1][2] = 0.0187723882;
- for (i = 2; i < 10; i++) piCCdfdy[3][2][i] = 0.031209;
-
- piCCdfdz[1][1][2] = -0.0302715;
- piCCdfdz[2][1][4] = -0.0100220;
- piCCdfdz[1][2][4] = -0.0100220;
- piCCdfdz[2][1][5] = -0.0100220;
- piCCdfdz[1][2][5] = -0.0100220;
- for (i = 4; i < 9; i++) piCCdfdz[2][2][i] = -0.0033090;
-
- // make top end of piCC flat instead of zero
- i = 4;
- for (j = 0; j < 4; j++){
- for (k = 1; k < 11; k++){
- piCCf[i][j][k] = piCCf[i-1][j][k];
- }
- }
- for (i = 0; i < 4; i++){ // also enforces some symmetry
- for (j = i+1; j < 5; j++){
- for (k = 1; k < 11; k++){
- piCCf[i][j][k] = piCCf[j][i][k];
- }
- }
- }
- for (k = 1; k < 11; k++) piCCf[4][4][k] = piCCf[3][4][k];
- k = 10;
- for (i = 0; i < 5; i++){
- for (j = 0; j < 5; j++){
- piCCf[i][j][k] = piCCf[i][j][k-1];
- }
+ if (atom->nmax > maxlocal) {
+ maxlocal = atom->nmax;
+ memory->destroy(REBO_numneigh);
+ memory->sfree(REBO_firstneigh);
+ memory->destroy(nC);
+ memory->destroy(nH);
+ memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh");
+ REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),
+ "AIREBO:firstneigh");
+ memory->create(nC,maxlocal,"AIREBO:nC");
+ memory->create(nH,maxlocal,"AIREBO:nH");
}
- piCHf[1][1][1] = -0.050;
- piCHf[1][1][2] = -0.050;
- piCHf[1][1][3] = -0.30;
- for (i = 4; i < 10; i++) piCHf[1][1][i] = -0.050;
- for (i = 5; i < 10; i++) piCHf[2][0][i] = -0.004523893758064;
- for (i = 5; i < 10; i++) piCHf[0][2][i] = -0.004523893758064;
- piCHf[2][1][2] = -0.250;
- piCHf[1][2][2] = -0.250;
- piCHf[2][1][3] = -0.250;
- piCHf[1][2][3] = -0.250;
- piCHf[3][1][1] = -0.10;
- piCHf[1][3][1] = -0.10;
- piCHf[3][1][2] = -0.125;
- piCHf[1][3][2] = -0.125;
- piCHf[3][1][3] = -0.125;
- piCHf[1][3][3] = -0.125;
- for (i = 4; i < 10; i++) piCHf[3][1][i] = -0.10;
- for (i = 4; i < 10; i++) piCHf[1][3][i] = -0.10;
-
- // make top end of piCH flat instead of zero
- // also enforces some symmetry
-
- i = 4;
- for (j = 0; j < 4; j++){
- for (k = 1; k < 11; k++){
- piCHf[i][j][k] = piCHf[i-1][j][k];
- }
- }
- for (i = 0; i < 4; i++){
- for (j = i+1; j < 5; j++){
- for (k = 1; k < 11; k++){
- piCHf[i][j][k] = piCHf[j][i][k];
- }
+ if (nthreads > maxpage)
+ add_pages(nthreads - maxpage);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+ int i,j,ii,jj,n,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int *neighptr;
+
+ double **x = atom->x;
+ int *type = atom->type;
+
+ const int allnum = list->inum + list->gnum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ const int iidelta = 1 + allnum/nthreads;
+ const int iifrom = tid*iidelta;
+ int iito = iifrom + iidelta;
+ if (iito > allnum)
+ iito = allnum;
+
+ // store all REBO neighs of owned and ghost atoms
+ // scan full neighbor list of I
+
+ int npage = tid;
+ int npnt = 0;
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if (pgsize - npnt < oneatom) {
+ npnt = 0;
+ npage += nthreads;
+ if (npage >= maxpage) add_pages(nthreads);
}
- }
- for (k = 1; k < 11; k++) piCHf[4][4][k] = piCHf[3][4][k];
- k = 10;
- for (i = 0; i < 5; i++){
- for (j = 0; j < 5; j++){
- piCHf[i][j][k] = piCHf[i][j][k-1];
+ neighptr = &(pages[npage][npnt]);
+ n = 0;
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = map[type[i]];
+ nC[i] = nH[i] = 0.0;
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ if (rsq < rcmaxsq[itype][jtype]) {
+ neighptr[n++] = j;
+ if (jtype == 0)
+ nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+ else
+ nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+ }
}
- }
- piHHf[1][1][1] = 0.124915958;
+ REBO_firstneigh[i] = neighptr;
+ REBO_numneigh[i] = n;
+ npnt += n;
- Tf[2][2][1] = -0.035140;
- for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480;
+ if (npnt >= pgsize)
+ error->one(FLERR,"REBO list overflow, boost neigh_modify one or page");
+ }
+ }
}
-/* ----------------------------------------------------------------------
- memory usage of local atom-based arrays
-------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------- */
-double PairAIREBO::memory_usage()
+double PairAIREBOOMP::memory_usage()
{
- double bytes = 0.0;
- bytes += maxlocal * sizeof(int);
- bytes += maxlocal * sizeof(int *);
- bytes += maxpage * neighbor->pgsize * sizeof(int);
- bytes += 3 * maxlocal * sizeof(double);
+ double bytes = memory_usage_thr();
+ bytes += PairAIREBO::memory_usage();
+
return bytes;
}
diff --git a/src/USER-OMP/pair_airebo_omp.h b/src/USER-OMP/pair_airebo_omp.h
new file mode 100644
index 000000000..9ba598fa8
--- /dev/null
+++ b/src/USER-OMP/pair_airebo_omp.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(airebo/omp,PairAIREBOOMP)
+
+#else
+
+#ifndef LMP_PAIR_AIREBO_OMP_H
+#define LMP_PAIR_AIREBO_OMP_H
+
+#include "pair_airebo.h"
+#include "thr_omp.h"
+
+namespace LAMMPS_NS {
+
+class PairAIREBOOMP : public PairAIREBO, public ThrOMP {
+
+ public:
+ PairAIREBOOMP(class LAMMPS *);
+
+ virtual void compute(int, int);
+ virtual double memory_usage();
+
+ protected:
+ double bondorder_thr(int i, int j, double rij[3], double rijmag,
+ double VA, int vflag_atom, ThrData * const thr);
+ double bondorderLJ_thr(int i, int j, double rij[3], double rijmag,
+ double VA, double rij0[3], double rijmag0,
+ int vflag_atom, ThrData * const thr);
+
+ void FREBO_thr(int ifrom, int ito, int evflag, int eflag,
+ int vflag_atom, ThrData * const thr);
+ void FLJ_thr(int ifrom, int ito, int evflag, int eflag,
+ int vflag_atom, ThrData * const thr);
+ void TORSION_thr(int ifrom, int ito, int evflag, int eflag, ThrData * const thr);
+ void REBO_neigh_thr();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-OMP/pair_born_coul_long_omp.cpp b/src/USER-OMP/pair_born_coul_long_omp.cpp
index c277a080c..cf409f3cf 100644
--- a/src/USER-OMP/pair_born_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_born_coul_long_omp.cpp
@@ -1,199 +1,195 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_born_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairBornCoulLongOMP::PairBornCoulLongOMP(LAMMPS *lmp) :
- PairBornCoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairBornCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBornCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBornCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBornCoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,r,rexp,forcecoul,forceborn,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
if (rsq < cut_coulsq) {
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ born3[itype][jtype]*r2inv*r6inv;
} else forceborn = 0.0;
fpair = (forcecoul + factor_lj*forceborn)*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = prefactor*erfc;
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv
+ d[itype][jtype]*r6inv*r2inv - offset[itype][jtype];
evdwl *= factor_lj;
}
} else evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairBornCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBornCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_born_coul_long_omp.h b/src/USER-OMP/pair_born_coul_long_omp.h
index d6ccbfc68..3271c566a 100644
--- a/src/USER-OMP/pair_born_coul_long_omp.h
+++ b/src/USER-OMP/pair_born_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(born/coul/long/omp,PairBornCoulLongOMP)
#else
#ifndef LMP_PAIR_BORN_COUL_LONG_OMP_H
#define LMP_PAIR_BORN_COUL_LONG_OMP_H
#include "pair_born_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBornCoulLongOMP : public PairBornCoulLong, public ThrOMP {
public:
PairBornCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_born_omp.cpp b/src/USER-OMP/pair_born_omp.cpp
index c39d205c9..d9dbf0d29 100644
--- a/src/USER-OMP/pair_born_omp.cpp
+++ b/src/USER-OMP/pair_born_omp.cpp
@@ -1,163 +1,159 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_born_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairBornOMP::PairBornOMP(LAMMPS *lmp) :
- PairBorn(lmp), ThrOMP(lmp, PAIR)
+ PairBorn(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBornOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBornOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBornOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,r,rexp,forceborn,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
r = sqrt(rsq);
rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ born3[itype][jtype]*r2inv*r6inv;
fpair = factor_lj*forceborn*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv
+ d[itype][jtype]*r6inv*r2inv - offset[itype][jtype];
evdwl *= factor_lj;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairBornOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBorn::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_born_omp.h
index b24de4a57..726064472 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_born_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(born/omp,PairBornOMP)
#else
#ifndef LMP_PAIR_BORN_OMP_H
#define LMP_PAIR_BORN_OMP_H
#include "pair_born.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBornOMP : public PairBorn, public ThrOMP {
public:
PairBornOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.cpp b/src/USER-OMP/pair_buck_coul_cut_omp.cpp
index ac47d478a..235f1c4f2 100644
--- a/src/USER-OMP/pair_buck_coul_cut_omp.cpp
+++ b/src/USER-OMP/pair_buck_coul_cut_omp.cpp
@@ -1,182 +1,177 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_buck_coul_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairBuckCoulCutOMP::PairBuckCoulCutOMP(LAMMPS *lmp) :
- PairBuckCoulCut(lmp), ThrOMP(lmp, PAIR)
+ PairBuckCoulCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBuckCoulCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
-
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBuckCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBuckCoulCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
if (rsq < cut_coulsq[itype][jtype])
forcecoul = qqrd2e * qtmp*q[j]/r;
else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
rexp = exp(-r*rhoinv[itype][jtype]);
forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
} else forcebuck = 0.0;
fpair = (forcecoul + factor_lj*forcebuck)*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype])
ecoul = factor_coul * qqrd2e * qtmp*q[j]/r;
else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
offset[itype][jtype];
evdwl *= factor_lj;
}
} else evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairBuckCoulCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBuckCoulCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.h b/src/USER-OMP/pair_buck_coul_cut_omp.h
index a77f3bad2..8fee0808c 100644
--- a/src/USER-OMP/pair_buck_coul_cut_omp.h
+++ b/src/USER-OMP/pair_buck_coul_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(buck/coul/cut/omp,PairBuckCoulCutOMP)
#else
#ifndef LMP_PAIR_BUCK_COUL_CUT_OMP_H
#define LMP_PAIR_BUCK_COUL_CUT_OMP_H
#include "pair_buck_coul_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBuckCoulCutOMP : public PairBuckCoulCut, public ThrOMP {
public:
PairBuckCoulCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.cpp b/src/USER-OMP/pair_buck_coul_long_omp.cpp
index 6e7398ca4..083b9acc6 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_buck_coul_long_omp.cpp
@@ -1,198 +1,195 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_buck_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairBuckCoulLongOMP::PairBuckCoulLongOMP(LAMMPS *lmp) :
- PairBuckCoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairBuckCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBuckCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
// reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBuckCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBuckCoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,r,rexp,forcecoul,forcebuck,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
if (rsq < cut_coulsq) {
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
rexp = exp(-r*rhoinv[itype][jtype]);
forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
} else forcebuck = 0.0;
fpair = (forcecoul + factor_lj*forcebuck)*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = prefactor*erfc;
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
offset[itype][jtype];
evdwl *= factor_lj;
}
} else evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairBuckCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBuckCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_buck_coul_long_omp.h b/src/USER-OMP/pair_buck_coul_long_omp.h
index 2c87904de..a47e809ee 100644
--- a/src/USER-OMP/pair_buck_coul_long_omp.h
+++ b/src/USER-OMP/pair_buck_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(buck/coul/long/omp,PairBuckCoulLongOMP)
#else
#ifndef LMP_PAIR_BUCK_COUL_LONG_OMP_H
#define LMP_PAIR_BUCK_COUL_LONG_OMP_H
#include "pair_buck_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBuckCoulLongOMP : public PairBuckCoulLong, public ThrOMP {
public:
PairBuckCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_buck_coul_omp.cpp b/src/USER-OMP/pair_buck_coul_omp.cpp
index bd171f628..97299feee 100644
--- a/src/USER-OMP/pair_buck_coul_omp.cpp
+++ b/src/USER-OMP/pair_buck_coul_omp.cpp
@@ -1,230 +1,226 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_buck_coul_omp.h"
#include "atom.h"
#include "comm.h"
#include "math_vector.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairBuckCoulOMP::PairBuckCoulOMP(LAMMPS *lmp) :
- PairBuckCoul(lmp), ThrOMP(lmp, PAIR)
+ PairBuckCoul(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBuckCoulOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBuckCoulOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBuckCoulOMP::eval(int iifrom, int iito, ThrData * const thr)
{
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double qqrd2e = force->qqrd2e;
- double *x0 = x[0];
+ const double *x0 = x[0];
double *f0 = f[0], *fi = f0;
int *ilist = list->ilist;
// loop over neighbors of my atoms
int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
int *jneigh, *jneighn, typei, typej, ni;
double qi, qri, *cutsqi, *cut_bucksqi,
*buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti;
double r, rsq, r2inv, force_coul, force_buck;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
vector xi, d;
for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms
i = ilist[ii]; fi = f0+3*i;
if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants
offseti = offset[typei = type[i]];
buck1i = buck1[typei]; buck2i = buck2[typei];
buckai = buck_a[typei]; buckci = buck_c[typei], rhoinvi = rhoinv[typei];
cutsqi = cutsq[typei]; cut_bucksqi = cut_bucksq[typei];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
for (; jneigh<jneighn; ++jneigh) { // loop over neighbors
j = *jneigh;
ni = sbmask(j);
j &= NEIGHMASK;
- { register double *xj = x0+(j+(j<<1));
+ { const register double *xj = x0+(j+(j<<1));
d[0] = xi[0] - xj[0]; // pair vector
d[1] = xi[1] - xj[1];
d[2] = xi[2] - xj[2]; }
if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue;
r2inv = 1.0/rsq;
r = sqrt(rsq);
if (order1 && (rsq < cut_coulsq)) { // coulombic
if (!ncoultablebits || rsq <= tabinnersq) { // series real space
register double x = g_ewald*r;
register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x);
if (ni == 0) {
s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (EFLAG) ecoul = t;
} else { // special case
register double f = s*(1.0-special_coul[ni])/r;
s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-f;
if (EFLAG) ecoul = t-f;
} // table real space
} else {
register union_int_float_t t;
t.f = rsq;
register const int k = (t.i & ncoulmask) >> ncoulshiftbits;
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni == 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]);
}
else { // special case
t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f);
if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f);
}
}
} else force_coul = ecoul = 0.0;
if (rsq < cut_bucksqi[typej]) { // buckingham
register double rn = r2inv*r2inv*r2inv,
expr = exp(-r*rhoinvi[typej]);
if (order6) { // long-range
register double x2 = g2*rsq, a2 = 1.0/x2;
x2 = a2*exp(-x2)*buckci[typej];
if (ni == 0) {
force_buck =
r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (EFLAG) evdwl = expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2;
} else { // special case
register double f = special_lj[ni], t = rn*(1.0-f);
force_buck = f*r*expr*buck1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej];
if (EFLAG) evdwl = f*expr*buckai[typej] -
g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej];
}
} else { // cut
if (ni == 0) {
force_buck = r*expr*buck1i[typej]-rn*buck2i[typej];
if (EFLAG) evdwl = expr*buckai[typej] -
rn*buckci[typej]-offseti[typej];
} else { // special case
register double f = special_lj[ni];
force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]);
if (EFLAG)
evdwl = f*(expr*buckai[typej]-rn*buckci[typej]-offseti[typej]);
}
}
} else force_buck = evdwl = 0.0;
fpair = (force_coul+force_buck)*r2inv;
if (NEWTON_PAIR || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fpair; fj[2] -= f;
} else {
fi[0] += d[0]*fpair;
fi[1] += d[1]*fpair;
fi[2] += d[2]*fpair;
}
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,d[0],d[1],d[2],tid);
+ evdwl,ecoul,fpair,d[0],d[1],d[2],thr);
}
}
}
/* ---------------------------------------------------------------------- */
double PairBuckCoulOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBuckCoul::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_buck_coul_omp.h b/src/USER-OMP/pair_buck_coul_omp.h
index dbff9b419..823f64a4a 100644
--- a/src/USER-OMP/pair_buck_coul_omp.h
+++ b/src/USER-OMP/pair_buck_coul_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(buck/coul/omp,PairBuckCoulOMP)
#else
#ifndef LMP_PAIR_BUCK_COUL_OMP_H
#define LMP_PAIR_BUCK_COUL_OMP_H
#include "pair_buck_coul.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBuckCoulOMP : public PairBuckCoul, public ThrOMP {
public:
PairBuckCoulOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_buck_omp.cpp b/src/USER-OMP/pair_buck_omp.cpp
index 66d8730ab..5806a3e79 100644
--- a/src/USER-OMP/pair_buck_omp.cpp
+++ b/src/USER-OMP/pair_buck_omp.cpp
@@ -1,165 +1,161 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_buck_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairBuckOMP::PairBuckOMP(LAMMPS *lmp) :
- PairBuck(lmp), ThrOMP(lmp, PAIR)
+ PairBuck(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairBuckOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairBuckOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairBuckOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,r,rexp,forcebuck,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
r = sqrt(rsq);
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
r = sqrt(rsq);
rexp = exp(-r*rhoinv[itype][jtype]);
forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
fpair = factor_lj*forcebuck*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
offset[itype][jtype];
evdwl *= factor_lj;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairBuckOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairBuck::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_buck_omp.h b/src/USER-OMP/pair_buck_omp.h
index 40b6702e6..c73e3f0d0 100644
--- a/src/USER-OMP/pair_buck_omp.h
+++ b/src/USER-OMP/pair_buck_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(buck/omp,PairBuckOMP)
#else
#ifndef LMP_PAIR_BUCK_OMP_H
#define LMP_PAIR_BUCK_OMP_H
#include "pair_buck.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairBuckOMP : public PairBuck, public ThrOMP {
public:
PairBuckOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_cdeam_omp.cpp b/src/USER-OMP/pair_cdeam_omp.cpp
index 01bd5f6ea..287b39ceb 100644
--- a/src/USER-OMP/pair_cdeam_omp.cpp
+++ b/src/USER-OMP/pair_cdeam_omp.cpp
@@ -1,545 +1,529 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "pair_cdeam_omp.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
// This is for debugging purposes. The ASSERT() macro is used in the code to check
// if everything runs as expected. Change this to #if 0 if you don't need the checking.
#if 0
#define ASSERT(cond) ((!(cond)) ? my_failure(error,__FILE__,__LINE__) : my_noop())
inline void my_noop() {}
inline void my_failure(Error* error, const char* file, int line) {
char str[1024];
sprintf(str,"Assertion failure: File %s, line %i", file, line);
error->one(FLERR,str);
}
#else
#define ASSERT(cond)
#endif
/* ---------------------------------------------------------------------- */
PairCDEAMOMP::PairCDEAMOMP(LAMMPS *lmp, int _cdeamVersion) :
- PairCDEAM(lmp,_cdeamVersion), PairEAM(lmp), ThrOMP(lmp, PAIR)
+ PairEAM(lmp), PairCDEAM(lmp,_cdeamVersion), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairCDEAMOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow energy and fp arrays if necessary
// need to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(rho);
memory->destroy(rhoB);
memory->destroy(D_values);
memory->destroy(fp);
nmax = atom->nmax;
memory->create(rho,nthreads*nmax,"pair:rho");
memory->create(rhoB,nthreads*nmax,"pair:mu");
memory->create(D_values,nthreads*nmax,"pair:D_values");
memory->create(fp,nmax,"pair:fp");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, *rho_t, *rhoB_t, *D_values_t;
-
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- if (force->newton_pair) {
- rho_t = rho + tid*nall;
- rhoB_t = rhoB + tid*nall;
- D_values_t = D_values + tid*nall;
- } else {
- rho_t = rho + tid*atom->nlocal;
- rhoB_t = rhoB + tid*atom->nlocal;
- D_values_t = D_values + tid*atom->nlocal;
- }
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (force->newton_pair)
+ thr->init_cdeam(nall, rho, rhoB, D_values);
+ else
+ thr->init_cdeam(atom->nlocal, rho, rhoB, D_values);
switch (cdeamVersion) {
case 1:
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<1,1,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0,1>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<1,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1,1>(ifrom, ito, thr);
+ else eval<1,0,0,1>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<0,0,0,1>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1,1>(ifrom, ito, thr);
+ else eval<0,0,0,1>(ifrom, ito, thr);
}
break;
case 2:
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<1,1,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1,2>(ifrom, ito, thr);
+ else eval<1,1,0,2>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<1,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1,2>(ifrom, ito, thr);
+ else eval<1,0,0,2>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
- else eval<0,0,0,2>(f, rho_t, rhoB_t, D_values_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1,2>(ifrom, ito, thr);
+ else eval<0,0,0,2>(ifrom, ito, thr);
}
break;
default:
#if defined(_OPENMP)
#pragma omp master
#endif
error->all(FLERR,"unsupported eam/cd pair style variant");
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR, int CDEAMVERSION>
-void PairCDEAMOMP::eval(double **f, double *rho_t, double *rhoB_t,
- double *D_values_t, int iifrom, int iito, int tid)
+void PairCDEAMOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rhoip,rhojp,recip,phi;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const rho_t = thr->get_rho();
+ double * const rhoB_t = thr->get_rhoB();
+ double * const D_values_t = thr->get_D_values();
+ const int tid = thr->get_tid();
+ const int nthreads = comm->nthreads;
+
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- // zero out density
-
- if (NEWTON_PAIR) {
- memset(rho_t, 0, nall*sizeof(double));
- memset(rhoB_t, 0, nall*sizeof(double));
- memset(D_values_t, 0, nall*sizeof(double));
- } else {
- memset(rho_t, 0, nlocal*sizeof(double));
- memset(rhoB_t, 0, nlocal*sizeof(double));
- memset(D_values_t, 0, nlocal*sizeof(double));
- }
-
// Stage I
// Compute rho and rhoB at each local atom site.
// Additionally calculate the D_i values here if we are using the one-site formulation.
// For the two-site formulation we have to calculate the D values in an extra loop (Stage II).
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if(rsq < cutforcesq) {
jtype = type[j];
double r = sqrt(rsq);
const EAMTableIndex index = radiusToTableIndex(r);
double localrho = RhoOfR(index, jtype, itype);
rho_t[i] += localrho;
if(jtype == speciesB) rhoB_t[i] += localrho;
if(NEWTON_PAIR || j < nlocal) {
localrho = RhoOfR(index, itype, jtype);
rho_t[j] += localrho;
if(itype == speciesB) rhoB_t[j] += localrho;
}
if(CDEAMVERSION == 1 && itype != jtype) {
// Note: if the i-j interaction is not concentration dependent (because either
// i or j are not species A or B) then its contribution to D_i and D_j should
// be ignored.
// This if-clause is only required for a ternary.
if((itype == speciesA && jtype == speciesB)
|| (jtype == speciesA && itype == speciesB)) {
double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r);
D_values_t[i] += Phi_AB;
if(NEWTON_PAIR || j < nlocal)
D_values_t[j] += Phi_AB;
}
}
}
}
}
// wait until all threads are done with computation
sync_threads();
// communicate and sum densities
if (NEWTON_PAIR) {
// reduce per thread density
- data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
- data_reduce_thr(&(rhoB[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nall, nthreads, 1, tid);
+ data_reduce_thr(rhoB, nall, nthreads, 1, tid);
if (CDEAMVERSION==1)
- data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(D_values, nall, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{ communicationStage = 1;
comm->reverse_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
} else {
// reduce per thread density
- data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
- data_reduce_thr(&(rhoB[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nlocal, nthreads, 1, tid);
+ data_reduce_thr(rhoB, nlocal, nthreads, 1, tid);
if (CDEAMVERSION==1)
- data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(D_values, nlocal, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
}
// fp = derivative of embedding energy at each atom
// phi = embedding energy at each atom
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
EAMTableIndex index = rhoToTableIndex(rho[i]);
fp[i] = FPrimeOfRho(index, type[i]);
if(EFLAG) {
phi = FofRho(index, type[i]);
- if (eflag_global) eng_vdwl_thr[tid] += phi;
- if (eflag_atom) eatom_thr[tid][i] += phi;
+ e_tally_thr(this, i, i, nlocal, NEWTON_PAIR, phi, 0.0, thr);
}
}
// wait until all theads are done with computation
sync_threads();
// Communicate derivative of embedding function and densities
// and D_values (this for one-site formulation only).
#if defined(_OPENMP)
#pragma omp master
#endif
{ communicationStage = 2;
comm->forward_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
// The electron densities may not drop to zero because then the concentration would no longer be defined.
// But the concentration is not needed anyway if there is no interaction with another atom, which is the case
// if the electron density is exactly zero. That's why the following lines have been commented out.
//
//for(i = 0; i < nlocal + atom->nghost; i++) {
// if(rho[i] == 0 && (type[i] == speciesA || type[i] == speciesB))
// error->one(FLERR,"CD-EAM potential routine: Detected atom with zero electron density.");
//}
// Stage II
// This is only required for the original two-site formulation of the CD-EAM potential.
if(CDEAMVERSION == 2) {
// Compute intermediate value D_i for each atom.
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
// This code line is required for ternary alloys.
if(itype != speciesA && itype != speciesB) continue;
double x_i = rhoB[i] / rho[i]; // Concentration at atom i.
for(jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
if(itype == jtype) continue;
// This code line is required for ternary alloys.
if(jtype != speciesA && jtype != speciesB) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if(rsq < cutforcesq) {
double r = sqrt(rsq);
const EAMTableIndex index = radiusToTableIndex(r);
// The concentration independent part of the cross pair potential.
double Phi_AB = PhiOfR(index, itype, jtype, 1.0 / r);
// Average concentration of two sites
double x_ij = 0.5 * (x_i + rhoB[j]/rho[j]);
// Calculate derivative of h(x_ij) polynomial function.
double h_prime = evalHprime(x_ij);
D_values_t[i] += h_prime * Phi_AB / (2.0 * rho[i] * rho[i]);
if(NEWTON_PAIR || j < nlocal)
D_values_t[j] += h_prime * Phi_AB / (2.0 * rho[j] * rho[j]);
}
}
}
if (NEWTON_PAIR) {
- data_reduce_thr(&(D_values[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(D_values, nall, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{ communicationStage = 3;
comm->reverse_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
} else {
- data_reduce_thr(&(D_values[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(D_values, nlocal, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
}
#if defined(_OPENMP)
#pragma omp master
#endif
{ communicationStage = 4;
comm->forward_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
}
// Stage III
// Compute force acting on each atom.
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fxtmp = fytmp = fztmp = 0.0;
jlist = firstneigh[i];
jnum = numneigh[i];
// Concentration at site i
double x_i = -1.0; // The value -1 indicates: no concentration dependence for all interactions of atom i.
// It will be replaced by the concentration at site i if atom i is either A or B.
double D_i, h_prime_i;
// This if-clause is only required for ternary alloys.
if((itype == speciesA || itype == speciesB) && rho[i] != 0.0) {
// Compute local concentration at site i.
x_i = rhoB[i]/rho[i];
ASSERT(x_i >= 0 && x_i<=1.0);
if(CDEAMVERSION == 1) {
// Calculate derivative of h(x_i) polynomial function.
h_prime_i = evalHprime(x_i);
D_i = D_values[i] * h_prime_i / (2.0 * rho[i] * rho[i]);
} else if(CDEAMVERSION == 2) {
D_i = D_values[i];
} else ASSERT(false);
}
for(jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if(rsq < cutforcesq) {
jtype = type[j];
double r = sqrt(rsq);
const EAMTableIndex index = radiusToTableIndex(r);
// rhoip = derivative of (density at atom j due to atom i)
// rhojp = derivative of (density at atom i due to atom j)
// psip needs both fp[i] and fp[j] terms since r_ij appears in two
// terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji)
// hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip
rhoip = RhoPrimeOfR(index, itype, jtype);
rhojp = RhoPrimeOfR(index, jtype, itype);
fpair = fp[i]*rhojp + fp[j]*rhoip;
recip = 1.0/r;
double x_j = -1; // The value -1 indicates: no concentration dependence for this i-j pair
// because atom j is not of species A nor B.
// This code line is required for ternary alloy.
if(jtype == speciesA || jtype == speciesB) {
ASSERT(rho[i] != 0.0);
ASSERT(rho[j] != 0.0);
// Compute local concentration at site j.
x_j = rhoB[j]/rho[j];
ASSERT(x_j >= 0 && x_j<=1.0);
double D_j;
if(CDEAMVERSION == 1) {
// Calculate derivative of h(x_j) polynomial function.
double h_prime_j = evalHprime(x_j);
D_j = D_values[j] * h_prime_j / (2.0 * rho[j] * rho[j]);
} else if(CDEAMVERSION == 2) {
D_j = D_values[j];
} else ASSERT(false);
double t2 = -rhoB[j];
if(itype == speciesB) t2 += rho[j];
fpair += D_j * rhoip * t2;
}
// This if-clause is only required for a ternary alloy.
// Actually we don't need it at all because D_i should be zero anyway if
// atom i has no concentration dependent interactions (because it is not species A or B).
if(x_i != -1.0) {
double t1 = -rhoB[i];
if(jtype == speciesB) t1 += rho[i];
fpair += D_i * rhojp * t1;
}
double phip;
double phi = PhiOfR(index, itype, jtype, recip, phip);
if(itype == jtype || x_i == -1.0 || x_j == -1.0) {
// Case of no concentration dependence.
fpair += phip;
} else {
// We have a concentration dependence for the i-j interaction.
double h;
if(CDEAMVERSION == 1) {
// Calculate h(x_i) polynomial function.
double h_i = evalH(x_i);
// Calculate h(x_j) polynomial function.
double h_j = evalH(x_j);
h = 0.5 * (h_i + h_j);
} else if(CDEAMVERSION == 2) {
// Average concentration.
double x_ij = 0.5 * (x_i + x_j);
// Calculate h(x_ij) polynomial function.
h = evalH(x_ij);
} else ASSERT(false);
fpair += h * phip;
phi *= h;
}
// Divide by r_ij and negate to get forces from gradient.
fpair /= -r;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if(NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if(EFLAG) evdwl = phi;
if(EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
- fpair,delx,dely,delz,tid);
+ fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairCDEAMOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairCDEAM::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_cdeam_omp.h b/src/USER-OMP/pair_cdeam_omp.h
index 85b124cb1..46f460f8f 100644
--- a/src/USER-OMP/pair_cdeam_omp.h
+++ b/src/USER-OMP/pair_cdeam_omp.h
@@ -1,66 +1,65 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(eam/cd/omp,PairCDEAM_OneSiteOMP)
PairStyle(eam/cd/old/omp,PairCDEAM_TwoSiteOMP)
#else
#ifndef LMP_PAIR_CDEAM_OMP_H
#define LMP_PAIR_CDEAM_OMP_H
#include "pair_cdeam.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairCDEAMOMP : public PairCDEAM, public ThrOMP {
public:
PairCDEAMOMP(class LAMMPS *, int);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR, int CDEAMVERSION>
- void eval(double **f, double *rho_t, double *rhoB_t, double *D_values_t,
- int iifrom, int iito, int tid);
+ void eval(int iifrom, int iito, ThrData * const thr);
};
/// The one-site concentration formulation of CD-EAM.
class PairCDEAM_OneSiteOMP : public PairCDEAMOMP
{
public:
/// Constructor.
PairCDEAM_OneSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 1) {}
};
/// The two-site concentration formulation of CD-EAM.
class PairCDEAM_TwoSiteOMP : public PairCDEAMOMP
{
public:
/// Constructor.
PairCDEAM_TwoSiteOMP(class LAMMPS* lmp) : PairEAM(lmp), PairCDEAMOMP(lmp, 2) {}
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_colloid_omp.cpp b/src/USER-OMP/pair_colloid_omp.cpp
index c8bc74407..7bfe1c04d 100644
--- a/src/USER-OMP/pair_colloid_omp.cpp
+++ b/src/USER-OMP/pair_colloid_omp.cpp
@@ -1,223 +1,219 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_colloid_omp.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairColloidOMP::PairColloidOMP(LAMMPS *lmp) :
- PairColloid(lmp), ThrOMP(lmp, PAIR)
+ PairColloid(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairColloidOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairColloidOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairColloidOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,r2inv,r6inv,forcelj,factor_lj;
double c1,c2,fR,dUR,dUA,K[9],h[4],g[4];
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq >= cutsq[itype][jtype]) continue;
switch(form[itype][jtype]) {
case SMALL_SMALL:
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
if (EFLAG)
evdwl = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
offset[itype][jtype];
break;
case SMALL_LARGE:
c2 = a2[itype][jtype];
K[1] = c2*c2;
K[2] = rsq;
K[0] = K[1] - rsq;
K[4] = rsq*rsq;
K[3] = K[1] - K[2];
K[3] *= K[3]*K[3];
K[6] = K[3]*K[3];
fR = sigma3[itype][jtype]*a12[itype][jtype]*c2*K[1]/K[3];
fpair = 4.0/15.0*fR*factor_lj *
(2.0*(K[1]+K[2]) * (K[1]*(5.0*K[1]+22.0*K[2])+5.0*K[4]) *
sigma6[itype][jtype]/K[6]-5.0) / K[0];
if (EFLAG)
evdwl = 2.0/9.0*fR *
(1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) *
sigma6[itype][jtype]/K[6]) - offset[itype][jtype];
if (rsq <= K[1]) error->one(FLERR,"Overlapping small/large in pair colloid");
break;
case LARGE_LARGE:
r = sqrt(rsq);
c1 = a1[itype][jtype];
c2 = a2[itype][jtype];
K[0] = c1*c2;
K[1] = c1+c2;
K[2] = c1-c2;
K[3] = K[1]+r;
K[4] = K[1]-r;
K[5] = K[2]+r;
K[6] = K[2]-r;
K[7] = 1.0/(K[3]*K[4]);
K[8] = 1.0/(K[5]*K[6]);
g[0] = pow(K[3],-7.0);
g[1] = pow(K[4],-7.0);
g[2] = pow(K[5],-7.0);
g[3] = pow(K[6],-7.0);
h[0] = ((K[3]+5.0*K[1])*K[3]+30.0*K[0])*g[0];
h[1] = ((K[4]+5.0*K[1])*K[4]+30.0*K[0])*g[1];
h[2] = ((K[5]+5.0*K[2])*K[5]-30.0*K[0])*g[2];
h[3] = ((K[6]+5.0*K[2])*K[6]-30.0*K[0])*g[3];
g[0] *= 42.0*K[0]/K[3]+6.0*K[1]+K[3];
g[1] *= 42.0*K[0]/K[4]+6.0*K[1]+K[4];
g[2] *= -42.0*K[0]/K[5]+6.0*K[2]+K[5];
g[3] *= -42.0*K[0]/K[6]+6.0*K[2]+K[6];
fR = a12[itype][jtype]*sigma6[itype][jtype]/r/37800.0;
evdwl = fR * (h[0]-h[1]-h[2]+h[3]);
dUR = evdwl/r + 5.0*fR*(g[0]+g[1]-g[2]-g[3]);
dUA = -a12[itype][jtype]/3.0*r*((2.0*K[0]*K[7]+1.0)*K[7] +
(2.0*K[0]*K[8]-1.0)*K[8]);
fpair = factor_lj * (dUR+dUA)/r;
if (EFLAG)
evdwl += a12[itype][jtype]/6.0 *
(2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - offset[itype][jtype];
if (r <= K[1]) error->one(FLERR,"Overlapping large/large in pair colloid");
break;
}
if (EFLAG) evdwl *= factor_lj;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairColloidOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairColloid::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_colloid_omp.h b/src/USER-OMP/pair_colloid_omp.h
index a0be13cbb..cde7e9b65 100644
--- a/src/USER-OMP/pair_colloid_omp.h
+++ b/src/USER-OMP/pair_colloid_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(colloid/omp,PairColloidOMP)
#else
#ifndef LMP_PAIR_COLLOID_OMP_H
#define LMP_PAIR_COLLOID_OMP_H
#include "pair_colloid.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairColloidOMP : public PairColloid, public ThrOMP {
public:
PairColloidOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp
new file mode 100644
index 000000000..80607b722
--- /dev/null
+++ b/src/USER-OMP/pair_comb_omp.cpp
@@ -0,0 +1,647 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_comb_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "group.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairCombOMP::PairCombOMP(LAMMPS *lmp) :
+ PairComb(lmp), ThrOMP(lmp, THR_PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCombOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+ // grow coordination array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->destroy(NCo);
+ memory->destroy(bbij);
+ nmax = atom->nmax;
+ memory->create(NCo,nmax,"pair:NCo");
+ memory->create(bbij,nmax,nmax,"pair:bbij");
+ }
+
+ // Build short range neighbor list
+ Short_neigh_thr();
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (vflag_atom) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (vflag_atom) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else eval<0,0,0>(ifrom, ito, thr);
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
+void PairCombOMP::eval(int iifrom, int iito, ThrData * const thr)
+{
+ int i,j,k,ii,jj,kk,jnum,iparam_i;
+ int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,rsq1,rsq2;
+ double delr1[3],delr2[3],fi[3],fj[3],fk[3];
+ double zeta_ij,prefactor;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ int mr1,mr2,mr3;
+ int rsc,inty;
+ double elp_ij,filp[3],fjlp[3],fklp[3];
+ double iq,jq;
+ double yaself;
+ double potal,fac11,fac11e;
+ double vionij,fvionij,sr1,sr2,sr3,Eov,Fov;
+ int sht_jnum, *sht_jlist;
+
+ evdwl = ecoul = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const tag = atom->tag;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ yaself = vionij = fvionij = Eov = Fov = 0.0;
+
+ double fxtmp,fytmp,fztmp;
+ double fjxtmp,fjytmp,fjztmp;
+
+ // self energy correction term: potal
+
+ potal_calc(potal,fac11,fac11e);
+
+ // loop over full neighbor list of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ itag = tag[i];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ iq = q[i];
+ NCo[i] = 0;
+ iparam_i = elem2param[itype][itype][itype];
+
+ // self energy, only on i atom
+
+ yaself = self(&params[iparam_i],iq,potal);
+
+ if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,yaself,
+ 0.0,0.0,0.0,0.0,0.0,thr);
+
+ // two-body interactions (long and short repulsive)
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ sht_jlist = sht_first[i];
+ sht_jnum = sht_num[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ztmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
+ // Qj calculates 2-body Coulombic
+
+ jtype = map[type[j]];
+ jq = q[j];
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ // long range q-dependent
+
+ if (rsq > params[iparam_ij].lcutsq) continue;
+
+ inty = intype[itype][jtype];
+
+ // polynomial three-point interpolation
+
+ tri_point(rsq, mr1, mr2, mr3, sr1, sr2, sr3, itype);
+
+ // 1/r energy and forces
+
+ direct(inty,mr1,mr2,mr3,rsq,sr1,sr2,sr3,iq,jq,
+ potal,fac11,fac11e,vionij,fvionij);
+
+ // field correction to self energy
+
+ field(&params[iparam_ij],rsq,iq,jq,vionij,fvionij);
+
+ // polarization field
+ // sums up long range forces
+
+ fxtmp += delx*fvionij;
+ fytmp += dely*fvionij;
+ fztmp += delz*fvionij;
+ f[j][0] -= delx*fvionij;
+ f[j][1] -= dely*fvionij;
+ f[j][2] -= delz*fvionij;
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ 0.0,vionij,fvionij,delx,dely,delz,thr);
+
+ // short range q-independent
+
+ if (rsq > params[iparam_ij].cutsq) continue;
+
+ repulsive(&params[iparam_ij],rsq,fpair,EFLAG,evdwl,iq,jq);
+
+ // repulsion is pure two-body, sums up pair repulsive forces
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+
+ // accumulate coordination number information
+
+ if (cor_flag) {
+ int numcoor = 0;
+ for (jj = 0; jj < sht_jnum; jj++) {
+ j = sht_jlist[jj];
+ j &= NEIGHMASK;
+ jtype = map[type[j]];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ if(params[iparam_ij].hfocor > 0.0 ) {
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = vec3_dot(delr1,delr1);
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+ ++numcoor;
+ }
+ }
+ NCo[i] = numcoor;
+ }
+
+ // three-body interactions
+ // half i-j loop
+
+ for (jj = 0; jj < sht_jnum; jj++) {
+ j = sht_jlist[jj];
+ j &= NEIGHMASK;
+
+ jtype = map[type[j]];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ // this Qj for q-dependent BSi
+
+ jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ rsq1 = vec3_dot(delr1,delr1);
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+
+ // accumulate bondorder zeta for each i-j interaction via loop over k
+
+ fjxtmp = fjytmp = fjztmp = 0.0;
+ zeta_ij = 0.0;
+ cuo_flag1 = 0; cuo_flag2 = 0;
+
+ for (kk = 0; kk < sht_jnum; kk++) {
+ k = sht_jlist[kk];
+ if (j == k) continue;
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = vec3_dot(delr2,delr2);
+
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ zeta_ij += zeta(&params[iparam_ijk],rsq1,rsq2,delr1,delr2);
+
+ if (params[iparam_ijk].hfocor == -2.0) cuo_flag1 = 1;
+ if (params[iparam_ijk].hfocor == -1.0) cuo_flag2 = 1;
+ }
+
+ if (cuo_flag1 && cuo_flag2) cuo_flag = 1;
+ else cuo_flag = 0;
+
+ force_zeta(&params[iparam_ij],EFLAG,i,j,rsq1,zeta_ij,
+ iq,jq,fpair,prefactor,evdwl);
+
+ // over-coordination correction for HfO2
+
+ if (cor_flag && NCo[i] != 0)
+ Over_cor(&params[iparam_ij],rsq1,NCo[i],Eov, Fov);
+ evdwl += Eov;
+ fpair += Fov;
+
+ fxtmp += delr1[0]*fpair;
+ fytmp += delr1[1]*fpair;
+ fztmp += delr1[2]*fpair;
+ fjxtmp -= delr1[0]*fpair;
+ fjytmp -= delr1[1]*fpair;
+ fjztmp -= delr1[2]*fpair;
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0,
+ -fpair,-delr1[0],-delr1[1],-delr1[2],thr);
+
+ // attractive term via loop over k (3-body forces)
+
+ for (kk = 0; kk < sht_jnum; kk++) {
+ k = sht_jlist[kk];
+ if (j == k) continue;
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ iparam_ijk = elem2param[itype][jtype][ktype];
+
+ delr2[0] = x[k][0] - xtmp;
+ delr2[1] = x[k][1] - ytmp;
+ delr2[2] = x[k][2] - ztmp;
+ rsq2 = vec3_dot(delr2,delr2);
+ if (rsq2 > params[iparam_ijk].cutsq) continue;
+
+ for (rsc = 0; rsc < 3; rsc++)
+ fi[rsc] = fj[rsc] = fk[rsc] = 0.0;
+
+ attractive(&params[iparam_ijk],prefactor,
+ rsq1,rsq2,delr1,delr2,fi,fj,fk);
+
+ // 3-body LP and BB correction and forces
+
+ elp_ij = elp(&params[iparam_ijk],rsq1,rsq2,delr1,delr2);
+ flp(&params[iparam_ijk],rsq1,rsq2,delr1,delr2,filp,fjlp,fklp);
+
+ fxtmp += fi[0] + filp[0];
+ fytmp += fi[1] + filp[1];
+ fztmp += fi[2] + filp[2];
+ fjxtmp += fj[0] + fjlp[0];
+ fjytmp += fj[1] + fjlp[1];
+ fjztmp += fj[2] + fjlp[2];
+ f[k][0] += fk[0] + fklp[0];
+ f[k][1] += fk[1] + fklp[1];
+ f[k][2] += fk[2] + fklp[2];
+
+ if (EVFLAG)
+ ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+ elp_ij,0.0,0.0,0.0,0.0,0.0, thr);
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,thr);
+ }
+ f[j][0] += fjxtmp;
+ f[j][1] += fjytmp;
+ f[j][2] += fjztmp;
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+
+ if (cuo_flag) params[iparam_i].cutsq *= 0.65;
+ }
+ cuo_flag = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCombOMP::yasu_char(double *qf_fix, int &igroup)
+{
+ int ii;
+ double potal,fac11,fac11e;
+
+ const double * const * const x = atom->x;
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int * const tag = atom->tag;
+
+ const int inum = list->inum;
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
+
+ const int * const mask = atom->mask;
+ const int groupbit = group->bitmask[igroup];
+
+ qf = qf_fix;
+ for (ii = 0; ii < inum; ii++) {
+ const int i = ilist[ii];
+ if (mask[i] & groupbit)
+ qf[i] = 0.0;
+ }
+
+ // communicating charge force to all nodes, first forward then reverse
+
+ comm->forward_comm_pair(this);
+
+ // self energy correction term: potal
+
+ potal_calc(potal,fac11,fac11e);
+
+ // loop over full neighbor list of my atoms
+#if defined(_OPENMP)
+#pragma omp parallel for private(ii) default(none) shared(potal,fac11e)
+#endif
+ for (ii = 0; ii < inum; ii ++) {
+ double fqi,fqj,fqij,fqji,fqjj,delr1[3];
+ double sr1,sr2,sr3;
+ int mr1,mr2,mr3;
+
+ const int i = ilist[ii];
+ const int itag = tag[i];
+
+ if (mask[i] & groupbit) {
+ fqi = fqj = fqij = fqji = fqjj = 0.0; // should not be needed.
+ int itype = map[type[i]];
+ const double xtmp = x[i][0];
+ const double ytmp = x[i][1];
+ const double ztmp = x[i][2];
+ const double iq = q[i];
+ const int iparam_i = elem2param[itype][itype][itype];
+
+ // charge force from self energy
+
+ fqi = qfo_self(&params[iparam_i],iq,potal);
+
+ // two-body interactions
+
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ const int j = jlist[jj] & NEIGHMASK;
+ const int jtag = tag[j];
+
+ if (itag > jtag) {
+ if ((itag+jtag) % 2 == 0) continue;
+ } else if (itag < jtag) {
+ if ((itag+jtag) % 2 == 1) continue;
+ } else {
+ if (x[j][2] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+ if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+ }
+
+ const int jtype = map[type[j]];
+ double jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ double rsq1 = vec3_dot(delr1,delr1);
+
+ const int iparam_ij = elem2param[itype][jtype][jtype];
+
+ // long range q-dependent
+
+ if (rsq1 > params[iparam_ij].lcutsq) continue;
+
+ const int inty = intype[itype][jtype];
+
+ // polynomial three-point interpolation
+
+ tri_point(rsq1,mr1,mr2,mr3,sr1,sr2,sr3,itype);
+
+ // 1/r charge forces
+
+ qfo_direct(inty,mr1,mr2,mr3,rsq1,sr1,sr2,sr3,fac11e,fqij);
+
+ // field correction to self energy and charge force
+
+ qfo_field(&params[iparam_ij],rsq1,iq,jq,fqji,fqjj);
+ fqi += jq * fqij + fqji;
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ qf[j] += (iq * fqij + fqjj);
+ }
+
+ // three-body interactions
+
+ for (int jj = 0; jj < jnum; jj++) {
+ const int j = jlist[jj] & NEIGHMASK;
+ const int jtype = map[type[j]];
+ const double jq = q[j];
+
+ delr1[0] = x[j][0] - xtmp;
+ delr1[1] = x[j][1] - ytmp;
+ delr1[2] = x[j][2] - ztmp;
+ double rsq1 = vec3_dot(delr1,delr1);
+
+ const int iparam_ij = elem2param[itype][jtype][jtype];
+
+ if (rsq1 > params[iparam_ij].cutsq) continue;
+
+ // charge force in Aij and Bij
+
+ qfo_short(&params[iparam_ij],i,j,rsq1,iq,jq,fqij,fqjj);
+ fqi += fqij;
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+ qf[j] += fqjj;
+ }
+
+#if defined(_OPENMP) && 0
+#pragma omp atomic
+#endif
+ qf[i] += fqi;
+ }
+ }
+
+ comm->reverse_comm_pair(this);
+
+ // sum charge force on each node and return it
+
+ double eneg = 0.0;
+ for (ii = 0; ii < inum; ii++) {
+ const int i = ilist[ii];
+ if (mask[i] & groupbit)
+ eneg += qf[i];
+ }
+ double enegtot;
+ MPI_Allreduce(&eneg,&enegtot,1,MPI_DOUBLE,MPI_SUM,world);
+ return enegtot;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairCombOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairComb::memory_usage();
+
+ return bytes;
+}
+/* ---------------------------------------------------------------------- */
+
+void PairCombOMP::Short_neigh_thr()
+{
+
+ if (atom->nmax > nmax) {
+ nmax = int(1.0 * atom->nmax);
+ memory->sfree(sht_num);
+ memory->sfree(sht_first);
+ memory->create(sht_num,nmax,"pair:sht_num");
+ sht_first = (int **) memory->smalloc(nmax*sizeof(int *),
+ "pair:sht_first");
+ }
+
+ const int nthreads = comm->nthreads;
+ if (nthreads > maxpage)
+ add_pages(nthreads - maxpage);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+ int nj,npntj,*neighptrj,itype,jtype;
+ int iparam_ij,*ilist,*jlist,*numneigh,**firstneigh;
+ int jnum,i,j,ii,jj;
+ double xtmp,ytmp,ztmp,rsq,delrj[3];
+ double **x = atom->x;
+ int *type = atom->type;
+
+ const int inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ const int iidelta = 1 + inum/nthreads;
+ const int iifrom = tid*iidelta;
+ int iito = iifrom + iidelta;
+ if (iito > inum) iito = inum;
+
+ int npage = tid;
+ npntj = 0;
+
+ for (ii = iifrom; ii < iito; ii++) {
+ i = ilist[ii];
+ itype = type[i];
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ if(pgsize - npntj < oneatom) {
+ npntj = 0;
+ npage++;
+ if (npage == maxpage) add_pages(nthreads);
+ }
+
+ neighptrj = &pages[npage][npntj];
+ nj = 0;
+
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+ jtype = type[j];
+ iparam_ij = elem2param[itype][jtype][jtype];
+
+ delrj[0] = xtmp - x[j][0];
+ delrj[1] = ytmp - x[j][1];
+ delrj[2] = ztmp - x[j][2];
+ rsq = vec3_dot(delrj,delrj);
+
+ if (rsq > cutmin) continue;
+ neighptrj[nj++] = j;
+ }
+ sht_first[i] = neighptrj;
+ sht_num[i] = nj;
+ npntj += nj;
+ }
+ }
+}
diff --git a/src/USER-OMP/pair_tersoff_omp.h b/src/USER-OMP/pair_comb_omp.h
similarity index 71%
copy from src/USER-OMP/pair_tersoff_omp.h
copy to src/USER-OMP/pair_comb_omp.h
index 5e5dc066d..85011064e 100644
--- a/src/USER-OMP/pair_tersoff_omp.h
+++ b/src/USER-OMP/pair_comb_omp.h
@@ -1,43 +1,47 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(tersoff/omp,PairTersoffOMP)
+PairStyle(comb/omp,PairCombOMP)
#else
-#ifndef LMP_PAIR_TERSOFF_OMP_H
-#define LMP_PAIR_TERSOFF_OMP_H
+#ifndef LMP_PAIR_COMB_OMP_H
+#define LMP_PAIR_COMB_OMP_H
-#include "pair_tersoff.h"
+#include "pair_comb.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairTersoffOMP : public PairTersoff, public ThrOMP {
+class PairCombOMP : public PairComb, public ThrOMP {
public:
- PairTersoffOMP(class LAMMPS *);
+ PairCombOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
+ virtual double yasu_char(double *, int &);
+
private:
template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
+
+ void Short_neigh_thr();
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_coul_cut_omp.cpp b/src/USER-OMP/pair_coul_cut_omp.cpp
index bb19db3d2..a8473eec3 100644
--- a/src/USER-OMP/pair_coul_cut_omp.cpp
+++ b/src/USER-OMP/pair_coul_cut_omp.cpp
@@ -1,162 +1,158 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_coul_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairCoulCutOMP::PairCoulCutOMP(LAMMPS *lmp) :
- PairCoulCut(lmp), ThrOMP(lmp, PAIR)
+ PairCoulCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairCoulCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairCoulCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
double rsq,r2inv,rinv,forcecoul,factor_coul;
int *ilist,*jlist,*numneigh,**firstneigh;
ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
forcecoul = qqrd2e * scale[itype][jtype] * qtmp*q[j]*rinv;
fpair = factor_coul*forcecoul * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG)
ecoul = factor_coul * qqrd2e * scale[itype][jtype] * qtmp*q[j]*rinv;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- 0.0,ecoul,fpair,delx,dely,delz,tid);
+ 0.0,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairCoulCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairCoulCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_coul_cut_omp.h b/src/USER-OMP/pair_coul_cut_omp.h
index eca9958ff..3499ee4ae 100644
--- a/src/USER-OMP/pair_coul_cut_omp.h
+++ b/src/USER-OMP/pair_coul_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(coul/cut/omp,PairCoulCutOMP)
#else
#ifndef LMP_PAIR_COUL_CUT_OMP_H
#define LMP_PAIR_COUL_CUT_OMP_H
#include "pair_coul_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairCoulCutOMP : public PairCoulCut, public ThrOMP {
public:
PairCoulCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_coul_debye_omp.cpp b/src/USER-OMP/pair_coul_debye_omp.cpp
index 1c2e7b8e0..73e579262 100644
--- a/src/USER-OMP/pair_coul_debye_omp.cpp
+++ b/src/USER-OMP/pair_coul_debye_omp.cpp
@@ -1,163 +1,159 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_coul_debye_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairCoulDebyeOMP::PairCoulDebyeOMP(LAMMPS *lmp) :
- PairCoulDebye(lmp), ThrOMP(lmp, PAIR)
+ PairCoulDebye(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairCoulDebyeOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairCoulDebyeOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
double rsq,r2inv,r,rinv,forcecoul,factor_coul,screening;
int *ilist,*jlist,*numneigh,**firstneigh;
ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
rinv = 1.0/r;
screening = exp(-kappa*r);
forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv);
fpair = factor_coul*forcecoul * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG)
ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- 0.0,ecoul,fpair,delx,dely,delz,tid);
+ 0.0,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairCoulDebyeOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairCoulDebye::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_coul_debye_omp.h b/src/USER-OMP/pair_coul_debye_omp.h
index 7ad599bb1..f016de8b5 100644
--- a/src/USER-OMP/pair_coul_debye_omp.h
+++ b/src/USER-OMP/pair_coul_debye_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(coul/debye/omp,PairCoulDebyeOMP)
#else
#ifndef LMP_PAIR_COUL_DEBYE_OMP_H
#define LMP_PAIR_COUL_DEBYE_OMP_H
#include "pair_coul_debye.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairCoulDebyeOMP : public PairCoulDebye, public ThrOMP {
public:
PairCoulDebyeOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_coul_debye_omp.cpp b/src/USER-OMP/pair_coul_diel_omp.cpp
similarity index 63%
copy from src/USER-OMP/pair_coul_debye_omp.cpp
copy to src/USER-OMP/pair_coul_diel_omp.cpp
index 1c2e7b8e0..e1e869024 100644
--- a/src/USER-OMP/pair_coul_debye_omp.cpp
+++ b/src/USER-OMP/pair_coul_diel_omp.cpp
@@ -1,163 +1,165 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_coul_debye_omp.h"
+#include "pair_coul_diel_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
-PairCoulDebyeOMP::PairCoulDebyeOMP(LAMMPS *lmp) :
- PairCoulDebye(lmp), ThrOMP(lmp, PAIR)
+PairCoulDielOMP::PairCoulDielOMP(LAMMPS *lmp) :
+ PairCoulDiel(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
-void PairCoulDebyeOMP::compute(int eflag, int vflag)
+void PairCoulDielOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairCoulDielOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
- double rsq,r2inv,r,rinv,forcecoul,factor_coul,screening;
+ double rsq,r,rarg,th,depsdr,epsr,forcecoul,factor_coul;
int *ilist,*jlist,*numneigh,**firstneigh;
ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
+
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
- r2inv = 1.0/rsq;
r = sqrt(rsq);
- rinv = 1.0/r;
- screening = exp(-kappa*r);
- forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv);
- fpair = factor_coul*forcecoul * r2inv;
-
+ rarg = (r-rme[itype][jtype])/sigmae[itype][jtype];
+ th=tanh(rarg);
+ epsr=a_eps+b_eps*th;
+ depsdr=b_eps * (1.0 - th*th) / sigmae[itype][jtype];
+
+ forcecoul = qqrd2e*qtmp*q[j]*((eps_s*(epsr+r*depsdr)/epsr/epsr) -1.)/rsq;
+ fpair = factor_coul*forcecoul/r;
+
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
- if (EFLAG)
- ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening;
+ if (EFLAG) {
+ ecoul = (qqrd2e*qtmp*q[j]*((eps_s/epsr) -1.)/r) - offset[itype][jtype];
+ ecoul *= factor_coul;
+ }
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- 0.0,ecoul,fpair,delx,dely,delz,tid);
+ 0.0,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-double PairCoulDebyeOMP::memory_usage()
+
+double PairCoulDielOMP::memory_usage()
{
double bytes = memory_usage_thr();
- bytes += PairCoulDebye::memory_usage();
+ bytes += PairCoulDiel::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_coul_diel_omp.h
similarity index 78%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/pair_coul_diel_omp.h
index b24de4a57..2dc0083ae 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_coul_diel_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(born/omp,PairBornOMP)
+PairStyle(coul/diel/omp,PairCoulDielOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_PAIR_COUL_DIEL_OMP_H
+#define LMP_PAIR_COUL_DIEL_OMP_H
-#include "pair_born.h"
+#include "pair_coul_diel.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class PairCoulDielOMP : public PairCoulDiel, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ PairCoulDielOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_coul_long_omp.cpp b/src/USER-OMP/pair_coul_long_omp.cpp
index 3a2e05159..82f070d37 100644
--- a/src/USER-OMP/pair_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_coul_long_omp.cpp
@@ -1,201 +1,197 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairCoulLongOMP::PairCoulLongOMP(LAMMPS *lmp) :
- PairCoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairCoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itable,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
double fraction,table;
double r,r2inv,rsq,forcecoul,factor_coul;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cut_coulsq) {
r2inv = 1.0/rsq;
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * scale[itype][jtype] * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = scale[itype][jtype] * qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = scale[itype][jtype] * qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
fpair = forcecoul * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = scale[itype][jtype] * qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- 0.0,ecoul,fpair,delx,dely,delz,tid);
+ 0.0,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_coul_long_omp.h b/src/USER-OMP/pair_coul_long_omp.h
index 7b63f762f..d7655637d 100644
--- a/src/USER-OMP/pair_coul_long_omp.h
+++ b/src/USER-OMP/pair_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(coul/long/omp,PairCoulLongOMP)
#else
#ifndef LMP_PAIR_COUL_LONG_OMP_H
#define LMP_PAIR_COUL_LONG_OMP_H
#include "pair_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairCoulLongOMP : public PairCoulLong, public ThrOMP {
public:
PairCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_dipole_cut_omp.cpp b/src/USER-OMP/pair_dipole_cut_omp.cpp
index 9ba93b19b..85079dd71 100644
--- a/src/USER-OMP/pair_dipole_cut_omp.cpp
+++ b/src/USER-OMP/pair_dipole_cut_omp.cpp
@@ -1,288 +1,283 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_dipole_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairDipoleCutOMP::PairDipoleCutOMP(LAMMPS *lmp) :
- PairDipoleCut(lmp), ThrOMP(lmp, PAIR)
+ PairDipoleCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairDipoleCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
- else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
- else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces and torques into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairDipoleCutOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+void PairDipoleCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul;
double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv,fx,fy,fz;
double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz;
double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double forcelj,factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- double **mu = atom->mu;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const double * const q = atom->q;
+ const double * const * const mu = atom->mu;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
// atom can have both a charge and dipole
// i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
forcecoulx = forcecouly = forcecoulz = 0.0;
tixcoul = tiycoul = tizcoul = 0.0;
tjxcoul = tjycoul = tjzcoul = 0.0;
if (rsq < cut_coulsq[itype][jtype]) {
if (qtmp != 0.0 && q[j] != 0.0) {
r3inv = r2inv*rinv;
pre1 = qtmp*q[j]*r3inv;
forcecoulx += pre1*delx;
forcecouly += pre1*dely;
forcecoulz += pre1*delz;
}
if (mu[i][3] > 0.0 && mu[j][3] > 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
r7inv = r5inv*r2inv;
pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*r5inv*pdotp - 15.0*r7inv*pidotr*pjdotr;
pre2 = 3.0*r5inv*pjdotr;
pre3 = 3.0*r5inv*pidotr;
pre4 = -1.0*r3inv;
forcecoulx += pre1*delx + pre2*mu[i][0] + pre3*mu[j][0];
forcecouly += pre1*dely + pre2*mu[i][1] + pre3*mu[j][1];
forcecoulz += pre1*delz + pre2*mu[i][2] + pre3*mu[j][2];
crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
}
if (mu[i][3] > 0.0 && q[j] != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pre1 = 3.0*q[j]*r5inv * pidotr;
pre2 = q[j]*r3inv;
forcecoulx += pre2*mu[i][0] - pre1*delx;
forcecouly += pre2*mu[i][1] - pre1*dely;
forcecoulz += pre2*mu[i][2] - pre1*delz;
tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
}
if (mu[j][3] > 0.0 && qtmp != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
pre1 = 3.0*qtmp*r5inv * pjdotr;
pre2 = qtmp*r3inv;
forcecoulx += pre1*delx - pre2*mu[j][0];
forcecouly += pre1*dely - pre2*mu[j][1];
forcecoulz += pre1*delz - pre2*mu[j][2];
tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
}
}
// LJ interaction
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj * r2inv;
} else forcelj = 0.0;
// total force
fq = factor_coul*qqrd2e;
fx = fq*forcecoulx + delx*forcelj;
fy = fq*forcecouly + dely*forcelj;
fz = fq*forcecoulz + delz*forcelj;
// force & torque accumulation
fxtmp += fx;
fytmp += fy;
fztmp += fz;
t1tmp += fq*tixcoul;
t2tmp += fq*tiycoul;
t3tmp += fq*tizcoul;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] += fq*tjxcoul;
torque[j][1] += fq*tjycoul;
torque[j][2] += fq*tjzcoul;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype]) {
ecoul = qtmp*q[j]*rinv;
if (mu[i][3] > 0.0 && mu[j][3] > 0.0)
ecoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr;
if (mu[i][3] > 0.0 && q[j] != 0.0)
ecoul += -q[j]*r3inv*pidotr;
if (mu[j][3] > 0.0 && qtmp != 0.0)
ecoul += qtmp*r3inv*pjdotr;
ecoul *= factor_coul*qqrd2e;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid);
+ evdwl,ecoul,fx,fy,fz,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairDipoleCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairDipoleCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_dipole_cut_omp.h b/src/USER-OMP/pair_dipole_cut_omp.h
index 832bd4d3b..b175450c9 100644
--- a/src/USER-OMP/pair_dipole_cut_omp.h
+++ b/src/USER-OMP/pair_dipole_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(dipole/cut/omp,PairDipoleCutOMP)
#else
#ifndef LMP_PAIR_DIPOLE_CUT_OMP_H
#define LMP_PAIR_DIPOLE_CUT_OMP_H
#include "pair_dipole_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairDipoleCutOMP : public PairDipoleCut, public ThrOMP {
public:
PairDipoleCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_dipole_sf_omp.cpp b/src/USER-OMP/pair_dipole_sf_omp.cpp
index 9ebc72d41..b920ff5c8 100644
--- a/src/USER-OMP/pair_dipole_sf_omp.cpp
+++ b/src/USER-OMP/pair_dipole_sf_omp.cpp
@@ -1,320 +1,315 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_dipole_sf_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairDipoleSFOMP::PairDipoleSFOMP(LAMMPS *lmp) :
- PairDipoleSF(lmp), ThrOMP(lmp, PAIR)
+ PairDipoleSF(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairDipoleSFOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
- else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
- else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces and torques into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairDipoleSFOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+void PairDipoleSFOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,qtmp,delx,dely,delz,evdwl,ecoul;
double rsq,rinv,r2inv,r6inv,r3inv,r5inv,fx,fy,fz;
double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz;
double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double forcelj,factor_coul,factor_lj;
double presf,afac,bfac,pqfac,qpfac,forceljcut,forceljsf;
double aforcecoulx,aforcecouly,aforcecoulz;
double bforcecoulx,bforcecouly,bforcecoulz;
double rcutlj2inv, rcutcoul2inv,rcutlj6inv;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- double **mu = atom->mu;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const double * const q = atom->q;
+ const double * const * const mu = atom->mu;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_coul = special_coul[sbmask(j)];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
// atom can have both a charge and dipole
// i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
// atom can have both a charge and dipole
// i,j = charge-charge, dipole-dipole, dipole-charge, or charge-dipole
forcecoulx = forcecouly = forcecoulz = 0.0;
tixcoul = tiycoul = tizcoul = 0.0;
tjxcoul = tjycoul = tjzcoul = 0.0;
if (rsq < cut_coulsq[itype][jtype]) {
if (qtmp != 0.0 && q[j] != 0.0) {
pre1 = qtmp*q[j]*rinv*(r2inv-1.0/cut_coulsq[itype][jtype]);
forcecoulx += pre1*delx;
forcecouly += pre1*dely;
forcecoulz += pre1*delz;
}
if (mu[i][3] > 0.0 && mu[j][3] > 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
pdotp = mu[i][0]*mu[j][0] + mu[i][1]*mu[j][1] + mu[i][2]*mu[j][2];
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
afac = 1.0 - rsq*rsq * rcutcoul2inv*rcutcoul2inv;
pre1 = afac * ( pdotp - 3.0 * r2inv * pidotr * pjdotr );
aforcecoulx = pre1*delx;
aforcecouly = pre1*dely;
aforcecoulz = pre1*delz;
bfac = 1.0 - 4.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv) +
3.0*rsq*rsq*rcutcoul2inv*rcutcoul2inv;
presf = 2.0 * r2inv * pidotr * pjdotr;
bforcecoulx = bfac * (pjdotr*mu[i][0]+pidotr*mu[j][0]-presf*delx);
bforcecouly = bfac * (pjdotr*mu[i][1]+pidotr*mu[j][1]-presf*dely);
bforcecoulz = bfac * (pjdotr*mu[i][2]+pidotr*mu[j][2]-presf*delz);
forcecoulx += 3.0 * r5inv * ( aforcecoulx + bforcecoulx );
forcecouly += 3.0 * r5inv * ( aforcecouly + bforcecouly );
forcecoulz += 3.0 * r5inv * ( aforcecoulz + bforcecoulz );
pre2 = 3.0 * bfac * r5inv * pjdotr;
pre3 = 3.0 * bfac * r5inv * pidotr;
pre4 = -bfac * r3inv;
crossx = pre4 * (mu[i][1]*mu[j][2] - mu[i][2]*mu[j][1]);
crossy = pre4 * (mu[i][2]*mu[j][0] - mu[i][0]*mu[j][2]);
crossz = pre4 * (mu[i][0]*mu[j][1] - mu[i][1]*mu[j][0]);
tixcoul += crossx + pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += crossy + pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += crossz + pre2 * (mu[i][0]*dely - mu[i][1]*delx);
tjxcoul += -crossx + pre3 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -crossy + pre3 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -crossz + pre3 * (mu[j][0]*dely - mu[j][1]*delx);
}
if (mu[i][3] > 0.0 && q[j] != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
pre1 = 3.0 * q[j] * r5inv * pidotr * (1-rsq*rcutcoul2inv);
pqfac = 1.0 - 3.0*rsq*rcutcoul2inv +
2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv);
pre2 = q[j] * r3inv * pqfac;
forcecoulx += pre2*mu[i][0] - pre1*delx;
forcecouly += pre2*mu[i][1] - pre1*dely;
forcecoulz += pre2*mu[i][2] - pre1*delz;
tixcoul += pre2 * (mu[i][1]*delz - mu[i][2]*dely);
tiycoul += pre2 * (mu[i][2]*delx - mu[i][0]*delz);
tizcoul += pre2 * (mu[i][0]*dely - mu[i][1]*delx);
}
if (mu[j][3] > 0.0 && qtmp != 0.0) {
r3inv = r2inv*rinv;
r5inv = r3inv*r2inv;
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
pre1 = 3.0 * qtmp * r5inv * pjdotr * (1-rsq*rcutcoul2inv);
qpfac = 1.0 - 3.0*rsq*rcutcoul2inv +
2.0*rsq*sqrt(rsq)*rcutcoul2inv*sqrt(rcutcoul2inv);
pre2 = qtmp * r3inv * qpfac;
forcecoulx += pre1*delx - pre2*mu[j][0];
forcecouly += pre1*dely - pre2*mu[j][1];
forcecoulz += pre1*delz - pre2*mu[j][2];
tjxcoul += -pre2 * (mu[j][1]*delz - mu[j][2]*dely);
tjycoul += -pre2 * (mu[j][2]*delx - mu[j][0]*delz);
tjzcoul += -pre2 * (mu[j][0]*dely - mu[j][1]*delx);
}
}
// LJ interaction
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forceljcut = r6inv*(lj1[itype][jtype]*r6inv-lj2[itype][jtype])*r2inv;
rcutlj2inv = 1.0 / cut_ljsq[itype][jtype];
rcutlj6inv = rcutlj2inv * rcutlj2inv * rcutlj2inv;
forceljsf = (lj1[itype][jtype]*rcutlj6inv - lj2[itype][jtype]) *
rcutlj6inv * rcutlj2inv;
forcelj = factor_lj * (forceljcut - forceljsf);
} else forcelj = 0.0;
// total force
fq = factor_coul*qqrd2e;
fx = fq*forcecoulx + delx*forcelj;
fy = fq*forcecouly + dely*forcelj;
fz = fq*forcecoulz + delz*forcelj;
// force & torque accumulation
fxtmp += fx;
fytmp += fy;
fztmp += fz;
t1tmp += fq*tixcoul;
t2tmp += fq*tiycoul;
t3tmp += fq*tizcoul;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] += fq*tjxcoul;
torque[j][1] += fq*tjycoul;
torque[j][2] += fq*tjzcoul;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype]) {
ecoul = qtmp * q[j] * rinv *
pow((1.0-sqrt(rsq)/sqrt(cut_coulsq[itype][jtype])),2);
if (mu[i][3] > 0.0 && mu[j][3] > 0.0)
ecoul += bfac * (r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr);
if (mu[i][3] > 0.0 && q[j] != 0.0)
ecoul += -q[j] * r3inv * pqfac * pidotr;
if (mu[j][3] > 0.0 && qtmp != 0.0)
ecoul += qtmp * r3inv * qpfac * pjdotr;
ecoul *= factor_coul*qqrd2e;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])+
rcutlj6inv*(6*lj3[itype][jtype]*rcutlj6inv-3*lj4[itype][jtype])*
rsq*rcutlj2inv+
rcutlj6inv*(-7*lj3[itype][jtype]*rcutlj6inv+4*lj4[itype][jtype]);
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fx,fy,fz,delx,dely,delz,tid);
+ evdwl,ecoul,fx,fy,fz,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairDipoleSFOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairDipoleSF::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_dipole_sf_omp.h b/src/USER-OMP/pair_dipole_sf_omp.h
index e601e2d56..89c80fa78 100644
--- a/src/USER-OMP/pair_dipole_sf_omp.h
+++ b/src/USER-OMP/pair_dipole_sf_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(dipole/sf/omp,PairDipoleSFOMP)
#else
#ifndef LMP_PAIR_DIPOLE_SF_OMP_H
#define LMP_PAIR_DIPOLE_SF_OMP_H
#include "pair_dipole_sf.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairDipoleSFOMP : public PairDipoleSF, public ThrOMP {
public:
PairDipoleSFOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_dpd_omp.cpp b/src/USER-OMP/pair_dpd_omp.cpp
index be1e32f37..0d24ce401 100644
--- a/src/USER-OMP/pair_dpd_omp.cpp
+++ b/src/USER-OMP/pair_dpd_omp.cpp
@@ -1,212 +1,212 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_dpd_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "update.h"
#include "random_mars.h"
using namespace LAMMPS_NS;
#define EPSILON 1.0e-10
/* ---------------------------------------------------------------------- */
PairDPDOMP::PairDPDOMP(LAMMPS *lmp) :
- PairDPD(lmp), ThrOMP(lmp, PAIR)
+ PairDPD(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
random_thr = NULL;
}
/* ---------------------------------------------------------------------- */
PairDPDOMP::~PairDPDOMP()
{
if (random_thr) {
for (int i=1; i < comm->nthreads; ++i)
delete random_thr[i];
delete[] random_thr;
random_thr = NULL;
}
}
/* ---------------------------------------------------------------------- */
void PairDPDOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
if (!random_thr)
random_thr = new RanMars*[nthreads];
-
+
+ // to ensure full compatibility with the serial DPD style
+ // we use is random number generator instance for thread 0
random_thr[0] = random;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+ // generate a random number generator instance for
+ // all threads != 0. make sure we use unique seeds.
if (random_thr && tid > 0)
random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me
+ comm->nprocs*tid);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairDPDOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairDPDOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
double rsq,r,rinv,dot,wd,randnum,factor_dpd;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- double **v = atom->v;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
- double dtinvsqrt = 1.0/sqrt(update->dt);
+ const double * const * const x = atom->x;
+ const double * const * const v = atom->v;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double *special_lj = force->special_lj;
+ const double dtinvsqrt = 1.0/sqrt(update->dt);
double fxtmp,fytmp,fztmp;
- RanMars &rng = *random_thr[tid];
+ RanMars &rng = *random_thr[thr->get_tid()];
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
vxtmp = v[i][0];
vytmp = v[i][1];
vztmp = v[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_dpd = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
if (r < EPSILON) continue; // r can be 0.0 in DPD systems
rinv = 1.0/r;
delvx = vxtmp - v[j][0];
delvy = vytmp - v[j][1];
delvz = vztmp - v[j][2];
dot = delx*delvx + dely*delvy + delz*delvz;
wd = 1.0 - r/cut[itype][jtype];
randnum = rng.gaussian();
// conservative force = a0 * wd
// drag force = -gamma * wd^2 * (delx dot delv) / r
// random force = sigma * wd * rnd * dtinvsqrt;
fpair = a0[itype][jtype]*wd;
fpair -= gamma[itype][jtype]*wd*wd*dot*rinv;
fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt;
fpair *= factor_dpd*rinv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
// unshifted eng of conservative term:
// evdwl = -a0[itype][jtype]*r * (1.0-0.5*r/cut[itype][jtype]);
// eng shifted to 0.0 at cutoff
evdwl = 0.5*a0[itype][jtype]*cut[itype][jtype] * wd*wd;
evdwl *= factor_dpd;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairDPDOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairDPD::memory_usage();
bytes += comm->nthreads * sizeof(RanMars*);
bytes += comm->nthreads * sizeof(RanMars);
return bytes;
}
diff --git a/src/USER-OMP/pair_dpd_omp.h b/src/USER-OMP/pair_dpd_omp.h
index 9385e5444..c3802f8e6 100644
--- a/src/USER-OMP/pair_dpd_omp.h
+++ b/src/USER-OMP/pair_dpd_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(dpd/omp,PairDPDOMP)
#else
#ifndef LMP_PAIR_DPD_OMP_H
#define LMP_PAIR_DPD_OMP_H
#include "pair_dpd.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairDPDOMP : public PairDPD, public ThrOMP {
public:
PairDPDOMP(class LAMMPS *);
virtual ~PairDPDOMP();
virtual void compute(int, int);
virtual double memory_usage();
protected:
class RanMars **random_thr;
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_dpd_tstat_omp.cpp b/src/USER-OMP/pair_dpd_tstat_omp.cpp
index 7e3fb8b39..50a1bf439 100644
--- a/src/USER-OMP/pair_dpd_tstat_omp.cpp
+++ b/src/USER-OMP/pair_dpd_tstat_omp.cpp
@@ -1,214 +1,214 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_dpd_tstat_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "update.h"
#include "random_mars.h"
using namespace LAMMPS_NS;
#define EPSILON 1.0e-10
/* ---------------------------------------------------------------------- */
PairDPDTstatOMP::PairDPDTstatOMP(LAMMPS *lmp) :
- PairDPDTstat(lmp), ThrOMP(lmp, PAIR)
+ PairDPDTstat(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
random_thr = NULL;
}
/* ---------------------------------------------------------------------- */
PairDPDTstatOMP::~PairDPDTstatOMP()
{
if (random_thr) {
for (int i=1; i < comm->nthreads; ++i)
delete random_thr[i];
delete[] random_thr;
random_thr = NULL;
}
}
/* ---------------------------------------------------------------------- */
void PairDPDTstatOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
if (!random_thr)
random_thr = new RanMars*[nthreads];
+ // to ensure full compatibility with the serial DPD style
+ // we use is random number generator instance for thread 0
random_thr[0] = random;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+ // generate a random number generator instance for
+ // all threads != 0. make sure we use unique seeds.
if (random_thr && tid > 0)
random_thr[tid] = new RanMars(Pair::lmp, seed + comm->me
+ comm->nprocs*tid);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairDPDTstatOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairDPDTstatOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
double rsq,r,rinv,dot,wd,randnum,factor_dpd;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- double **v = atom->v;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
- double dtinvsqrt = 1.0/sqrt(update->dt);
+ const double * const * const x = atom->x;
+ const double * const * const v = atom->v;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double *special_lj = force->special_lj;
+ const double dtinvsqrt = 1.0/sqrt(update->dt);
double fxtmp,fytmp,fztmp;
- RanMars &rng = *random_thr[tid];
+ RanMars &rng = *random_thr[thr->get_tid()];
// adjust sigma if target T is changing
if (t_start != t_stop) {
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
temperature = t_start + delta * (t_stop-t_start);
double boltz = force->boltz;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++)
sigma[i][j] = sigma[j][i] = sqrt(2.0*boltz*temperature*gamma[i][j]);
}
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
vxtmp = v[i][0];
vytmp = v[i][1];
vztmp = v[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_dpd = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
if (r < EPSILON) continue; // r can be 0.0 in DPD systems
rinv = 1.0/r;
delvx = vxtmp - v[j][0];
delvy = vytmp - v[j][1];
delvz = vztmp - v[j][2];
dot = delx*delvx + dely*delvy + delz*delvz;
wd = 1.0 - r/cut[itype][jtype];
randnum = rng.gaussian();
// drag force = -gamma * wd^2 * (delx dot delv) / r
// random force = sigma * wd * rnd * dtinvsqrt;
fpair = -gamma[itype][jtype]*wd*wd*dot*rinv;
fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt;
fpair *= factor_dpd*rinv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- 0.0,0.0,fpair,delx,dely,delz,tid);
+ 0.0,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairDPDTstatOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairDPDTstat::memory_usage();
bytes += comm->nthreads * sizeof(RanMars*);
bytes += comm->nthreads * sizeof(RanMars);
return bytes;
}
diff --git a/src/USER-OMP/pair_dpd_tstat_omp.h b/src/USER-OMP/pair_dpd_tstat_omp.h
index 14f640a92..87c9de550 100644
--- a/src/USER-OMP/pair_dpd_tstat_omp.h
+++ b/src/USER-OMP/pair_dpd_tstat_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(dpd/tstat/omp,PairDPDTstatOMP)
#else
#ifndef LMP_PAIR_DPD_TSTAT_OMP_H
#define LMP_PAIR_DPD_TSTAT_OMP_H
#include "pair_dpd_tstat.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairDPDTstatOMP : public PairDPDTstat, public ThrOMP {
public:
PairDPDTstatOMP(class LAMMPS *);
virtual ~PairDPDTstatOMP();
virtual void compute(int, int);
virtual double memory_usage();
protected:
class RanMars **random_thr;
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_eam_omp.cpp b/src/USER-OMP/pair_eam_omp.cpp
index 0ae4d54fb..c014eb75e 100644
--- a/src/USER-OMP/pair_eam_omp.cpp
+++ b/src/USER-OMP/pair_eam_omp.cpp
@@ -1,303 +1,298 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "pair_eam_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairEAMOMP::PairEAMOMP(LAMMPS *lmp) :
- PairEAM(lmp), ThrOMP(lmp, PAIR)
+ PairEAM(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairEAMOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow energy and fp arrays if necessary
// need to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(rho);
memory->destroy(fp);
nmax = atom->nmax;
memory->create(rho,nthreads*nmax,"pair:rho");
memory->create(fp,nmax,"pair:fp");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, *rho_t;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
if (force->newton_pair)
- rho_t = rho + tid*nall;
- else rho_t = rho + tid*atom->nlocal;
+ thr->init_eam(nall, rho);
+ else
+ thr->init_eam(atom->nlocal, rho);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, rho_t, ifrom, ito, tid);
- else eval<1,1,0>(f, rho_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, rho_t, ifrom, ito, tid);
- else eval<1,0,0>(f, rho_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, rho_t, ifrom, ito, tid);
- else eval<0,0,0>(f, rho_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairEAMOMP::eval(double **f, double *rho_t,
- int iifrom, int iito, int tid)
+void PairEAMOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,m,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi;
double *coeff;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const rho_t = thr->get_rho();
+ const int tid = thr->get_tid();
+ const int nthreads = comm->nthreads;
+
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- // zero out density
-
- if (NEWTON_PAIR) memset(rho_t, 0, nall*sizeof(double));
- else memset(rho_t, 0, nlocal*sizeof(double));
-
// rho = density at each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq) {
jtype = type[j];
p = sqrt(rsq)*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
coeff = rhor_spline[type2rhor[jtype][itype]][m];
rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
if (NEWTON_PAIR || j < nlocal) {
coeff = rhor_spline[type2rhor[itype][jtype]][m];
rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
}
}
}
}
// wait until all threads are done with computation
sync_threads();
// communicate and sum densities
if (NEWTON_PAIR) {
// reduce per thread density
- data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nall, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{ comm->reverse_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
} else {
- data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nlocal, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
}
// fp = derivative of embedding energy at each atom
// phi = embedding energy at each atom
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
p = rho[i]*rdrho + 1.0;
m = static_cast<int> (p);
m = MAX(1,MIN(m,nrho-1));
p -= m;
p = MIN(p,1.0);
coeff = frho_spline[type2frho[type[i]]][m];
fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
if (EFLAG) {
phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
- if (eflag_global) eng_vdwl_thr[tid] += phi;
- if (eflag_atom) eatom_thr[tid][i] += phi;
+ e_tally_thr(this, i, i, nlocal, NEWTON_PAIR, phi, 0.0, thr);
}
}
// wait until all theads are done with computation
sync_threads();
// communicate derivative of embedding function
// MPI communication only on master thread
#if defined(_OPENMP)
#pragma omp master
#endif
{ comm->forward_comm_pair(this); }
// wait until master thread is done with communication
sync_threads();
// compute forces on each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fxtmp = fytmp = fztmp = 0.0;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq) {
jtype = type[j];
r = sqrt(rsq);
p = r*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
// rhoip = derivative of (density at atom j due to atom i)
// rhojp = derivative of (density at atom i due to atom j)
// phi = pair potential energy
// phip = phi'
// z2 = phi * r
// z2p = (phi * r)' = (phi' r) + phi
// psip needs both fp[i] and fp[j] terms since r_ij appears in two
// terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji)
// hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip
coeff = rhor_spline[type2rhor[itype][jtype]][m];
rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = rhor_spline[type2rhor[jtype][itype]][m];
rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = z2r_spline[type2z2r[itype][jtype]][m];
z2p = (coeff[0]*p + coeff[1])*p + coeff[2];
z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
recip = 1.0/r;
phi = z2*recip;
phip = z2p*recip - phi*recip;
psip = fp[i]*rhojp + fp[j]*rhoip + phip;
fpair = -psip*recip;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) evdwl = phi;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairEAMOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairEAM::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_eam_omp.h b/src/USER-OMP/pair_eam_omp.h
index 1184cb34b..6b0f1274f 100644
--- a/src/USER-OMP/pair_eam_omp.h
+++ b/src/USER-OMP/pair_eam_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(eam/omp,PairEAMOMP)
#else
#ifndef LMP_PAIR_EAM_OMP_H
#define LMP_PAIR_EAM_OMP_H
#include "pair_eam.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairEAMOMP : public PairEAM, public ThrOMP {
public:
PairEAMOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double *rho_t, int iifrom, int iito, int tid);
+ void eval(int iifrom, int iito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_edip_omp.cpp b/src/USER-OMP/pair_edip_omp.cpp
index 65b05c814..f0d6d47ce 100644
--- a/src/USER-OMP/pair_edip_omp.cpp
+++ b/src/USER-OMP/pair_edip_omp.cpp
@@ -1,485 +1,483 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_edip_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairEDIPOMP::PairEDIPOMP(LAMMPS *lmp) :
- PairEDIP(lmp), ThrOMP(lmp, PAIR)
+ PairEDIP(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairEDIPOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = vflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (vflag_atom) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (vflag_atom) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
- } else eval<0,0,0>(f, ifrom, ito, tid);
+ } else eval<0,0,0>(ifrom, ito, thr);
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
-void PairEDIPOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairEDIPOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,k,ii,inum,jnum;
int itype,jtype,ktype,ijparam,ikparam,ijkparam;
double xtmp,ytmp,ztmp,evdwl;
int *ilist,*jlist,*numneigh,**firstneigh;
register int preForceCoord_counter;
double invR_ij;
double invR_ik;
double directorCos_ij_x;
double directorCos_ij_y;
double directorCos_ij_z;
double directorCos_ik_x;
double directorCos_ik_y;
double directorCos_ik_z;
double cosTeta;
int interpolIDX;
double interpolTMP;
double interpolDeltaX;
double interpolY1;
double interpolY2;
double invRMinusCutoffA;
double sigmaInvRMinusCutoffA;
double gammInvRMinusCutoffA;
double cosTetaDiff;
double cosTetaDiffCosTetaDiff;
double cutoffFunction_ij;
double exp2B_ij;
double exp2BDerived_ij;
double pow2B_ij;
double pow2BDerived_ij;
double exp3B_ij;
double exp3BDerived_ij;
double exp3B_ik;
double exp3BDerived_ik;
double qFunction;
double qFunctionDerived;
double tauFunction;
double tauFunctionDerived;
double expMinusBetaZeta_iZeta_i;
double qFunctionCosTetaDiffCosTetaDiff;
double expMinusQFunctionCosTetaDiffCosTetaDiff;
double zeta_i;
double zeta_iDerived;
double zeta_iDerivedInvR_ij;
double forceModCoord_factor;
double forceModCoord;
double forceModCoord_ij;
double forceMod2B;
double forceMod3B_factor1_ij;
double forceMod3B_factor2_ij;
double forceMod3B_factor2;
double forceMod3B_factor1_ik;
double forceMod3B_factor2_ik;
double potentia3B_factor;
double potential2B_factor;
+ const int tid = thr->get_tid();
+
double *pre_thrInvR_ij = preInvR_ij + tid * leadDimInteractionList;
double *pre_thrExp3B_ij = preExp3B_ij + tid * leadDimInteractionList;
double *pre_thrExp3BDerived_ij = preExp3BDerived_ij + tid * leadDimInteractionList;
double *pre_thrExp2B_ij = preExp2B_ij + tid * leadDimInteractionList;
double *pre_thrExp2BDerived_ij = preExp2BDerived_ij + tid * leadDimInteractionList;
double *pre_thrPow2B_ij = prePow2B_ij + tid * leadDimInteractionList;
double *pre_thrForceCoord = preForceCoord + tid * leadDimInteractionList;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over full neighbor list of my atoms
for (ii = iifrom; ii < iito; ii++) {
zeta_i = 0.0;
int numForceCoordPairs = 0;
i = ilist[ii];
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
jlist = firstneigh[i];
jnum = numneigh[i];
// pre-loop to compute environment coordination f(Z)
for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
j = jlist[neighbor_j];
j &= NEIGHMASK;
double dr_ij[3], r_ij;
dr_ij[0] = xtmp - x[j][0];
dr_ij[1] = ytmp - x[j][1];
dr_ij[2] = ztmp - x[j][2];
r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
jtype = map[type[j]];
ijparam = elem2param[itype][jtype][jtype];
if (r_ij > params[ijparam].cutsq) continue;
r_ij = sqrt(r_ij);
invR_ij = 1.0 / r_ij;
pre_thrInvR_ij[neighbor_j] = invR_ij;
invRMinusCutoffA = 1.0 / (r_ij - cutoffA);
sigmaInvRMinusCutoffA = sigma * invRMinusCutoffA;
gammInvRMinusCutoffA = gamm * invRMinusCutoffA;
interpolDeltaX = r_ij - GRIDSTART;
interpolTMP = (interpolDeltaX * GRIDDENSITY);
interpolIDX = (int) interpolTMP;
interpolY1 = exp3B[interpolIDX];
interpolY2 = exp3B[interpolIDX+1];
exp3B_ij = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
exp3BDerived_ij = - exp3B_ij * gammInvRMinusCutoffA * invRMinusCutoffA;
pre_thrExp3B_ij[neighbor_j] = exp3B_ij;
pre_thrExp3BDerived_ij[neighbor_j] = exp3BDerived_ij;
interpolY1 = exp2B[interpolIDX];
interpolY2 = exp2B[interpolIDX+1];
exp2B_ij = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
exp2BDerived_ij = - exp2B_ij * sigmaInvRMinusCutoffA * invRMinusCutoffA;
pre_thrExp2B_ij[neighbor_j] = exp2B_ij;
pre_thrExp2BDerived_ij[neighbor_j] = exp2BDerived_ij;
interpolY1 = pow2B[interpolIDX];
interpolY2 = pow2B[interpolIDX+1];
pow2B_ij = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
pre_thrPow2B_ij[neighbor_j] = pow2B_ij;
// zeta and its derivative
if (r_ij < cutoffC) zeta_i += 1.0;
else {
interpolY1 = cutoffFunction[interpolIDX];
interpolY2 = cutoffFunction[interpolIDX+1];
cutoffFunction_ij = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
zeta_i += cutoffFunction_ij;
interpolY1 = cutoffFunctionDerived[interpolIDX];
interpolY2 = cutoffFunctionDerived[interpolIDX+1];
zeta_iDerived = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
zeta_iDerivedInvR_ij = zeta_iDerived * invR_ij;
preForceCoord_counter=numForceCoordPairs*5;
pre_thrForceCoord[preForceCoord_counter+0]=zeta_iDerivedInvR_ij;
pre_thrForceCoord[preForceCoord_counter+1]=dr_ij[0];
pre_thrForceCoord[preForceCoord_counter+2]=dr_ij[1];
pre_thrForceCoord[preForceCoord_counter+3]=dr_ij[2];
pre_thrForceCoord[preForceCoord_counter+4]=j;
numForceCoordPairs++;
}
}
// quantities depending on zeta_i
interpolDeltaX = zeta_i;
interpolTMP = (interpolDeltaX * GRIDDENSITY);
interpolIDX = (int) interpolTMP;
interpolY1 = expMinusBetaZeta_iZeta_iGrid[interpolIDX];
interpolY2 = expMinusBetaZeta_iZeta_iGrid[interpolIDX+1];
expMinusBetaZeta_iZeta_i = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
interpolY1 = qFunctionGrid[interpolIDX];
interpolY2 = qFunctionGrid[interpolIDX+1];
qFunction = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
interpolY1 = tauFunctionGrid[interpolIDX];
interpolY2 = tauFunctionGrid[interpolIDX+1];
tauFunction = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
interpolY1 = tauFunctionDerivedGrid[interpolIDX];
interpolY2 = tauFunctionDerivedGrid[interpolIDX+1];
tauFunctionDerived = interpolY1 + (interpolY2 - interpolY1) *
(interpolTMP-interpolIDX);
qFunctionDerived = -mu * qFunction;
forceModCoord_factor = 2.0 * beta * zeta_i * expMinusBetaZeta_iZeta_i;
forceModCoord = 0.0;
// two-body interactions, skip half of them
for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
double dr_ij[3], r_ij, f_ij[3];
j = jlist[neighbor_j];
j &= NEIGHMASK;
dr_ij[0] = x[j][0] - xtmp;
dr_ij[1] = x[j][1] - ytmp;
dr_ij[2] = x[j][2] - ztmp;
r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
jtype = map[type[j]];
ijparam = elem2param[itype][jtype][jtype];
if (r_ij > params[ijparam].cutsq) continue;
r_ij = sqrt(r_ij);
invR_ij = pre_thrInvR_ij[neighbor_j];
pow2B_ij = pre_thrPow2B_ij[neighbor_j];
potential2B_factor = pow2B_ij - expMinusBetaZeta_iZeta_i;
exp2B_ij = pre_thrExp2B_ij[neighbor_j];
pow2BDerived_ij = - rho * invR_ij * pow2B_ij;
forceModCoord += (forceModCoord_factor*exp2B_ij);
exp2BDerived_ij = pre_thrExp2BDerived_ij[neighbor_j];
forceMod2B = exp2BDerived_ij * potential2B_factor +
exp2B_ij * pow2BDerived_ij;
directorCos_ij_x = invR_ij * dr_ij[0];
directorCos_ij_y = invR_ij * dr_ij[1];
directorCos_ij_z = invR_ij * dr_ij[2];
exp3B_ij = pre_thrExp3B_ij[neighbor_j];
exp3BDerived_ij = pre_thrExp3BDerived_ij[neighbor_j];
f_ij[0] = forceMod2B * directorCos_ij_x;
f_ij[1] = forceMod2B * directorCos_ij_y;
f_ij[2] = forceMod2B * directorCos_ij_z;
f[j][0] -= f_ij[0];
f[j][1] -= f_ij[1];
f[j][2] -= f_ij[2];
f[i][0] += f_ij[0];
f[i][1] += f_ij[1];
f[i][2] += f_ij[2];
// potential energy
evdwl = (exp2B_ij * potential2B_factor);
if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, evdwl, 0.0,
- -forceMod2B*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid);
+ -forceMod2B*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2],thr);
// three-body Forces
for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) {
double dr_ik[3], r_ik, f_ik[3];
k = jlist[neighbor_k];
k &= NEIGHMASK;
ktype = map[type[k]];
ikparam = elem2param[itype][ktype][ktype];
ijkparam = elem2param[itype][jtype][ktype];
dr_ik[0] = x[k][0] - xtmp;
dr_ik[1] = x[k][1] - ytmp;
dr_ik[2] = x[k][2] - ztmp;
r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
if (r_ik > params[ikparam].cutsq) continue;
r_ik = sqrt(r_ik);
invR_ik = pre_thrInvR_ij[neighbor_k];
directorCos_ik_x = invR_ik * dr_ik[0];
directorCos_ik_y = invR_ik * dr_ik[1];
directorCos_ik_z = invR_ik * dr_ik[2];
cosTeta = directorCos_ij_x * directorCos_ik_x +
directorCos_ij_y * directorCos_ik_y +
directorCos_ij_z * directorCos_ik_z;
cosTetaDiff = cosTeta + tauFunction;
cosTetaDiffCosTetaDiff = cosTetaDiff * cosTetaDiff;
qFunctionCosTetaDiffCosTetaDiff = cosTetaDiffCosTetaDiff * qFunction;
expMinusQFunctionCosTetaDiffCosTetaDiff =
exp(-qFunctionCosTetaDiffCosTetaDiff);
potentia3B_factor = lambda *
((1.0 - expMinusQFunctionCosTetaDiffCosTetaDiff) +
eta * qFunctionCosTetaDiffCosTetaDiff);
exp3B_ik = pre_thrExp3B_ij[neighbor_k];
exp3BDerived_ik = pre_thrExp3BDerived_ij[neighbor_k];
forceMod3B_factor1_ij = - exp3BDerived_ij * exp3B_ik *
potentia3B_factor;
forceMod3B_factor2 = 2.0 * lambda * exp3B_ij * exp3B_ik *
qFunction * cosTetaDiff *
(eta + expMinusQFunctionCosTetaDiffCosTetaDiff);
forceMod3B_factor2_ij = forceMod3B_factor2 * invR_ij;
f_ij[0] = forceMod3B_factor1_ij * directorCos_ij_x +
forceMod3B_factor2_ij *
(cosTeta * directorCos_ij_x - directorCos_ik_x);
f_ij[1] = forceMod3B_factor1_ij * directorCos_ij_y +
forceMod3B_factor2_ij *
(cosTeta * directorCos_ij_y - directorCos_ik_y);
f_ij[2] = forceMod3B_factor1_ij * directorCos_ij_z +
forceMod3B_factor2_ij *
(cosTeta * directorCos_ij_z - directorCos_ik_z);
forceMod3B_factor1_ik = - exp3BDerived_ik * exp3B_ij *
potentia3B_factor;
forceMod3B_factor2_ik = forceMod3B_factor2 * invR_ik;
f_ik[0] = forceMod3B_factor1_ik * directorCos_ik_x +
forceMod3B_factor2_ik *
(cosTeta * directorCos_ik_x - directorCos_ij_x);
f_ik[1] = forceMod3B_factor1_ik * directorCos_ik_y +
forceMod3B_factor2_ik *
(cosTeta * directorCos_ik_y - directorCos_ij_y);
f_ik[2] = forceMod3B_factor1_ik * directorCos_ik_z +
forceMod3B_factor2_ik *
(cosTeta * directorCos_ik_z - directorCos_ij_z);
forceModCoord += (forceMod3B_factor2 *
(tauFunctionDerived - 0.5 * mu * cosTetaDiff));
f[j][0] += f_ij[0];
f[j][1] += f_ij[1];
f[j][2] += f_ij[2];
f[k][0] += f_ik[0];
f[k][1] += f_ik[1];
f[k][2] += f_ik[2];
f[i][0] -= f_ij[0] + f_ik[0];
f[i][1] -= f_ij[1] + f_ik[1];
f[i][2] -= f_ij[2] + f_ik[2];
// potential energy
evdwl = (exp3B_ij * exp3B_ik * potentia3B_factor);
- if (evflag) ev_tally3(i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik);
+ if (evflag) ev_tally3_thr(this,i,j,k,evdwl,0.0,f_ij,f_ik,dr_ij,dr_ik,thr);
}
}
// forces due to environment coordination f(Z)
for (int idx = 0; idx < numForceCoordPairs; idx++) {
double dr_ij[3], f_ij[3];
preForceCoord_counter = idx * 5;
zeta_iDerivedInvR_ij=pre_thrForceCoord[preForceCoord_counter+0];
dr_ij[0]=pre_thrForceCoord[preForceCoord_counter+1];
dr_ij[1]=pre_thrForceCoord[preForceCoord_counter+2];
dr_ij[2]=pre_thrForceCoord[preForceCoord_counter+3];
j = static_cast<int> (pre_thrForceCoord[preForceCoord_counter+4]);
forceModCoord_ij = forceModCoord * zeta_iDerivedInvR_ij;
f_ij[0] = forceModCoord_ij * dr_ij[0];
f_ij[1] = forceModCoord_ij * dr_ij[1];
f_ij[2] = forceModCoord_ij * dr_ij[2];
f[j][0] -= f_ij[0];
f[j][1] -= f_ij[1];
f[j][2] -= f_ij[2];
f[i][0] += f_ij[0];
f[i][1] += f_ij[1];
f[i][2] += f_ij[2];
// potential energy
evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, 0.0, 0.0,
- forceModCoord_ij, dr_ij[0], dr_ij[1], dr_ij[2],tid);
+ forceModCoord_ij, dr_ij[0], dr_ij[1], dr_ij[2],thr);
}
}
}
/* ---------------------------------------------------------------------- */
double PairEDIPOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairEDIP::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_edip_omp.h b/src/USER-OMP/pair_edip_omp.h
index 55c34db34..55e10c83b 100644
--- a/src/USER-OMP/pair_edip_omp.h
+++ b/src/USER-OMP/pair_edip_omp.h
@@ -1,43 +1,43 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(edip/omp,PairEDIPOMP)
#else
#ifndef LMP_PAIR_EDIP_OMP_H
#define LMP_PAIR_EDIP_OMP_H
#include "pair_edip.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairEDIPOMP : public PairEDIP, public ThrOMP {
public:
PairEDIPOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_eim_omp.cpp b/src/USER-OMP/pair_eim_omp.cpp
index d31ad2012..7184adb78 100644
--- a/src/USER-OMP/pair_eim_omp.cpp
+++ b/src/USER-OMP/pair_eim_omp.cpp
@@ -1,365 +1,353 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "pair_eim_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairEIMOMP::PairEIMOMP(LAMMPS *lmp) :
- PairEIM(lmp), ThrOMP(lmp, PAIR)
+ PairEIM(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairEIMOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow energy and fp arrays if necessary
// need to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(rho);
memory->destroy(fp);
nmax = atom->nmax;
memory->create(rho,nthreads*nmax,"pair:rho");
memory->create(fp,nthreads*nmax,"pair:fp");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, *rho_t, *fp_t;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- if (force->newton_pair) {
- rho_t = rho + tid*nall;
- fp_t = fp + tid*nall;
- } else {
- rho_t = rho + tid*atom->nlocal;
- fp_t = fp + tid*atom->nlocal;
- }
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (force->newton_pair)
+ thr->init_eim(nall, rho, fp);
+ else
+ thr->init_eim(atom->nlocal, rho, fp);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, rho_t, fp_t, ifrom, ito, tid);
- else eval<1,1,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, rho_t, fp_t, ifrom, ito, tid);
- else eval<1,0,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, rho_t, fp_t, ifrom, ito, tid);
- else eval<0,0,0>(f, rho_t, fp_t, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairEIMOMP::eval(double **f, double *rho_t, double *fp_t,
- int iifrom, int iito, int tid)
+void PairEIMOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,m,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,p,rhoip,rhojp,phip,phi,coul,coulp,recip,psip;
double *coeff;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- int nall = nlocal + atom->nghost;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const rho_t = thr->get_rho();
+ double * const fp_t = thr->get_fp();
+ const int tid = thr->get_tid();
+ const int nthreads = comm->nthreads;
+
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const int nall = nlocal + atom->nghost;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- // zero out density and fp
-
- if (NEWTON_PAIR) {
- memset(rho_t, 0, nall*sizeof(double));
- memset(fp_t, 0, nall*sizeof(double));
- } else {
- memset(rho_t, 0, nlocal*sizeof(double));
- memset(fp_t, 0, nlocal*sizeof(double));
- }
-
// rho = density at each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq[itype][jtype]) {
p = sqrt(rsq)*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
coeff = Fij_spline[type2Fij[itype][jtype]][m];
rho_t[i] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
if (NEWTON_PAIR || j < nlocal) {
coeff = Fij_spline[type2Fij[jtype][itype]][m];
rho_t[j] += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
}
}
}
}
// wait until all threads are done with computation
sync_threads();
// communicate and sum densities
if (NEWTON_PAIR) {
// reduce per thread density
- data_reduce_thr(&(rho[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nall, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{
rhofp = 1;
comm->reverse_comm_pair(this);
}
} else {
- data_reduce_thr(&(rho[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(rho, nlocal, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
}
#if defined(_OPENMP)
#pragma omp master
#endif
{
rhofp = 1;
comm->forward_comm_pair(this);
}
// wait until master is finished communicating
sync_threads();
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq[itype][jtype]) {
p = sqrt(rsq)*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
coeff = Gij_spline[type2Gij[itype][jtype]][m];
fp_t[i] += rho[j]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]);
if (NEWTON_PAIR || j < nlocal) {
fp_t[j] += rho[i]*(((coeff[3]*p + coeff[4])*p + coeff[5])*p +
coeff[6]);
}
}
}
}
// wait until all threads are done with computation
sync_threads();
// communicate and sum modified densities
if (NEWTON_PAIR) {
// reduce per thread density
- data_reduce_thr(&(fp[0]), nall, comm->nthreads, 1, tid);
+ data_reduce_thr(fp, nall, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{
rhofp = 2;
comm->reverse_comm_pair(this);
}
} else {
- data_reduce_thr(&(fp[0]), nlocal, comm->nthreads, 1, tid);
+ data_reduce_thr(fp, nlocal, nthreads, 1, tid);
// wait until reduction is complete
sync_threads();
}
#if defined(_OPENMP)
#pragma omp master
#endif
{
rhofp = 2;
comm->forward_comm_pair(this);
}
// wait until master is finished communicating
sync_threads();
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
itype = type[i];
if (EFLAG) {
phi = 0.5*rho[i]*fp[i];
- if (eflag_global) eng_vdwl_thr[tid] += phi;
- if (eflag_atom) eatom_thr[tid][i] += phi;
+ e_tally_thr(this, i, i, nlocal, NEWTON_PAIR, phi, 0.0, thr);
}
}
// compute forces on each atom
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
fxtmp = fytmp = fztmp = 0.0;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = type[j];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cutforcesq[itype][jtype]) {
r = sqrt(rsq);
p = r*rdr + 1.0;
m = static_cast<int> (p);
m = MIN(m,nr-1);
p -= m;
p = MIN(p,1.0);
// rhoip = derivative of (density at atom j due to atom i)
// rhojp = derivative of (density at atom i due to atom j)
// phi = pair potential energy
// phip = phi'
coeff = Fij_spline[type2Fij[jtype][itype]][m];
rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = Fij_spline[type2Fij[itype][jtype]][m];
rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
coeff = phiij_spline[type2phiij[itype][jtype]][m];
phip = (coeff[0]*p + coeff[1])*p + coeff[2];
phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coeff = Gij_spline[type2Gij[itype][jtype]][m];
coul = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
coulp = (coeff[0]*p + coeff[1])*p + coeff[2];
psip = phip + (rho[i]*rho[j]-q0[itype]*q0[jtype])*coulp +
fp[i]*rhojp + fp[j]*rhoip;
recip = 1.0/r;
fpair = -psip*recip;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) evdwl = phi-q0[itype]*q0[jtype]*coul;
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairEIMOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairEIM::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_eim_omp.h b/src/USER-OMP/pair_eim_omp.h
index 3693492e0..ad273e28e 100644
--- a/src/USER-OMP/pair_eim_omp.h
+++ b/src/USER-OMP/pair_eim_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(eim/omp,PairEIMOMP)
#else
#ifndef LMP_PAIR_EIM_OMP_H
#define LMP_PAIR_EIM_OMP_H
#include "pair_eim.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairEIMOMP : public PairEIM, public ThrOMP {
public:
PairEIMOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double *rho_t, double *fp_t, int iifrom, int iito, int tid);
+ void eval(int iifrom, int iito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_morse_omp.cpp b/src/USER-OMP/pair_gauss_cut_omp.cpp
similarity index 64%
copy from src/USER-OMP/pair_morse_omp.cpp
copy to src/USER-OMP/pair_gauss_cut_omp.cpp
index a53e35a97..5499fab3b 100644
--- a/src/USER-OMP/pair_morse_omp.cpp
+++ b/src/USER-OMP/pair_gauss_cut_omp.cpp
@@ -1,160 +1,156 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_morse_omp.h"
+#include "pair_gauss_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
-PairMorseOMP::PairMorseOMP(LAMMPS *lmp) :
- PairMorse(lmp), ThrOMP(lmp, PAIR)
+PairGaussCutOMP::PairGaussCutOMP(LAMMPS *lmp) :
+ PairGaussCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
-void PairMorseOMP::compute(int eflag, int vflag)
+void PairGaussCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairMorseOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairGaussCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
- double rsq,r,dr,dexp,factor_lj;
+ double rsq,r,rexp,ugauss,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
+
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
- dr = r - r0[itype][jtype];
- dexp = exp(-alpha[itype][jtype] * dr);
- fpair = factor_lj * morse1[itype][jtype] * (dexp*dexp - dexp) / r;
+ rexp = (r-rmh[itype][jtype])/sigmah[itype][jtype];
+ ugauss = pgauss[itype][jtype]*exp(-0.5*rexp*rexp);
+ fpair = factor_lj*rexp/r*ugauss/sigmah[itype][jtype];
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
- evdwl = d0[itype][jtype] * (dexp*dexp - 2.0*dexp) -
- offset[itype][jtype];
+ evdwl = ugauss - offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-double PairMorseOMP::memory_usage()
+double PairGaussCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
- bytes += PairMorse::memory_usage();
+ bytes += PairGaussCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_gauss_cut_omp.h
similarity index 78%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/pair_gauss_cut_omp.h
index b24de4a57..d3da26abe 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_gauss_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(born/omp,PairBornOMP)
+PairStyle(gauss/cut/omp,PairGaussCutOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_PAIR_GAUSS_CUT_OMP_H
+#define LMP_PAIR_GAUSS_CUT_OMP_H
-#include "pair_born.h"
+#include "pair_gauss_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class PairGaussCutOMP : public PairGaussCut, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ PairGaussCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_gauss_omp.cpp b/src/USER-OMP/pair_gauss_omp.cpp
index e8b255d0b..4f2667071 100644
--- a/src/USER-OMP/pair_gauss_omp.cpp
+++ b/src/USER-OMP/pair_gauss_omp.cpp
@@ -1,170 +1,169 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gauss_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EPSILON 1.0e-10
/* ---------------------------------------------------------------------- */
PairGaussOMP::PairGaussOMP(LAMMPS *lmp) :
- PairGauss(lmp), ThrOMP(lmp, PAIR)
+ PairGauss(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairGaussOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
+ double occ = 0.0;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag) reduction(+:occ)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) occ = eval<1,1,1>(ifrom, ito, thr);
+ else occ = eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) occ = eval<1,0,1>(ifrom, ito, thr);
+ else occ = eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) occ = eval<0,0,1>(ifrom, ito, thr);
+ else occ = eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
+ if (eflag_global) pvector[0] = occ;
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairGaussOMP::eval(double **f, int iifrom, int iito, int tid)
+double PairGaussOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double r,rsq,r2inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
int occ = 0;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
// define a Gaussian well to be occupied if
// the site it interacts with is within the force maximum
if (EFLAG)
if (eflag_global && rsq < 0.5/b[itype][jtype]) occ++;
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
forcelj = - 2.0*a[itype][jtype]*b[itype][jtype] * rsq *
exp(-b[itype][jtype]*rsq);
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = -(a[itype][jtype]*exp(-b[itype][jtype]*rsq) -
offset[itype][jtype]);
evdwl *= factor_lj;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
- if (eflag_global) pvector[0] = occ;
+ return occ;
}
/* ---------------------------------------------------------------------- */
double PairGaussOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGauss::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_gauss_omp.h b/src/USER-OMP/pair_gauss_omp.h
index 7f8fc9a85..81d9d0ce3 100644
--- a/src/USER-OMP/pair_gauss_omp.h
+++ b/src/USER-OMP/pair_gauss_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gauss/omp,PairGaussOMP)
#else
#ifndef LMP_PAIR_GAUSS_OMP_H
#define LMP_PAIR_GAUSS_OMP_H
#include "pair_gauss.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairGaussOMP : public PairGauss, public ThrOMP {
public:
PairGaussOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ double eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_gayberne_omp.cpp b/src/USER-OMP/pair_gayberne_omp.cpp
index ff115e8ef..d8ec6c9b3 100644
--- a/src/USER-OMP/pair_gayberne_omp.cpp
+++ b/src/USER-OMP/pair_gayberne_omp.cpp
@@ -1,227 +1,229 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gayberne_omp.h"
#include "math_extra.h"
#include "atom.h"
#include "comm.h"
#include "atom_vec_ellipsoid.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGayBerneOMP::PairGayBerneOMP(LAMMPS *lmp) :
- PairGayBerne(lmp), ThrOMP(lmp, PAIR)
+ PairGayBerne(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairGayBerneOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
- else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
- else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces and torques into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairGayBerneOMP::eval(double **f, double **tor, int iifrom, int iito, int tid)
+void PairGayBerneOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
double fforce[3],ttor[3],rtor[3],r12[3];
double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
int *ilist,*jlist,*numneigh,**firstneigh;
double *iquat,*jquat;
- double **x = atom->x;
- int *ellipsoid = atom->ellipsoid;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const tor = thr->get_torque();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
+ const int * const ellipsoid = atom->ellipsoid;
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itype = type[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
if (form[itype][itype] == ELLIPSE_ELLIPSE) {
iquat = bonus[ellipsoid[i]].quat;
MathExtra::quat_to_mat_trans(iquat,a1);
MathExtra::diag_times3(well[itype],a1,temp);
MathExtra::transpose_times3(a1,temp,b1);
MathExtra::diag_times3(shape2[itype],a1,temp);
MathExtra::transpose_times3(a1,temp,g1);
}
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
// r12 = center to center vector
r12[0] = x[j][0]-x[i][0];
r12[1] = x[j][1]-x[i][1];
r12[2] = x[j][2]-x[i][2];
rsq = MathExtra::dot3(r12,r12);
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
switch (form[itype][jtype]) {
case SPHERE_SPHERE:
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= -r2inv;
if (EFLAG)
one_eng = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
offset[itype][jtype];
fforce[0] = r12[0]*forcelj;
fforce[1] = r12[1]*forcelj;
fforce[2] = r12[2]*forcelj;
ttor[0] = ttor[1] = ttor[2] = 0.0;
rtor[0] = rtor[1] = rtor[2] = 0.0;
break;
case SPHERE_ELLIPSE:
jquat = bonus[ellipsoid[j]].quat;
MathExtra::quat_to_mat_trans(jquat,a2);
MathExtra::diag_times3(well[jtype],a2,temp);
MathExtra::transpose_times3(a2,temp,b2);
MathExtra::diag_times3(shape2[jtype],a2,temp);
MathExtra::transpose_times3(a2,temp,g2);
one_eng = gayberne_lj(j,i,a2,b2,g2,r12,rsq,fforce,rtor);
ttor[0] = ttor[1] = ttor[2] = 0.0;
break;
case ELLIPSE_SPHERE:
one_eng = gayberne_lj(i,j,a1,b1,g1,r12,rsq,fforce,ttor);
rtor[0] = rtor[1] = rtor[2] = 0.0;
break;
default:
jquat = bonus[ellipsoid[j]].quat;
MathExtra::quat_to_mat_trans(jquat,a2);
MathExtra::diag_times3(well[jtype],a2,temp);
MathExtra::transpose_times3(a2,temp,b2);
MathExtra::diag_times3(shape2[jtype],a2,temp);
MathExtra::transpose_times3(a2,temp,g2);
one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
fforce,ttor,rtor);
break;
}
fforce[0] *= factor_lj;
fforce[1] *= factor_lj;
fforce[2] *= factor_lj;
ttor[0] *= factor_lj;
ttor[1] *= factor_lj;
ttor[2] *= factor_lj;
- f[i][0] += fforce[0];
- f[i][1] += fforce[1];
- f[i][2] += fforce[2];
- tor[i][0] += ttor[0];
- tor[i][1] += ttor[1];
- tor[i][2] += ttor[2];
+ fxtmp += fforce[0];
+ fytmp += fforce[1];
+ fztmp += fforce[2];
+ t1tmp += ttor[0];
+ t2tmp += ttor[1];
+ t3tmp += ttor[2];
if (NEWTON_PAIR || j < nlocal) {
rtor[0] *= factor_lj;
rtor[1] *= factor_lj;
rtor[2] *= factor_lj;
f[j][0] -= fforce[0];
f[j][1] -= fforce[1];
f[j][2] -= fforce[2];
tor[j][0] += rtor[0];
tor[j][1] += rtor[1];
tor[j][2] += rtor[2];
}
if (EFLAG) evdwl = factor_lj*one_eng;
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
evdwl,0.0,fforce[0],fforce[1],fforce[2],
- -r12[0],-r12[1],-r12[2],tid);
+ -r12[0],-r12[1],-r12[2],thr);
}
}
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ tor[i][0] += t1tmp;
+ tor[i][1] += t2tmp;
+ tor[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairGayBerneOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGayBerne::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_gayberne_omp.h b/src/USER-OMP/pair_gayberne_omp.h
index 737b4ec67..0bd0b8b08 100644
--- a/src/USER-OMP/pair_gayberne_omp.h
+++ b/src/USER-OMP/pair_gayberne_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gayberne/omp,PairGayBerneOMP)
#else
#ifndef LMP_PAIR_GAYBERNE_OMP_H
#define LMP_PAIR_GAYBERNE_OMP_H
#include "pair_gayberne.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairGayBerneOMP : public PairGayBerne, public ThrOMP {
public:
PairGayBerneOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.cpp b/src/USER-OMP/pair_gran_hertz_history_omp.cpp
index 1866833af..23b8b8f5c 100644
--- a/src/USER-OMP/pair_gran_hertz_history_omp.cpp
+++ b/src/USER-OMP/pair_gran_hertz_history_omp.cpp
@@ -1,298 +1,293 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gran_hertz_history_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "update.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHertzHistoryOMP::PairGranHertzHistoryOMP(LAMMPS *lmp) :
- PairGranHertzHistory(lmp), ThrOMP(lmp, PAIR)
+ PairGranHertzHistory(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairGranHertzHistoryOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int shearupdate = (update->ntimestep > laststep) ? 1 : 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag)
- if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid);
- else eval<1,0>(f, torque, ifrom, ito, tid);
+ if (shearupdate) eval<1,1>(ifrom, ito, thr);
+ else eval<1,0>(ifrom, ito, thr);
else
- if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0>(f, torque, ifrom, ito, tid);
+ if (shearupdate) eval<0,1>(ifrom, ito, thr);
+ else eval<0,0>(ifrom, ito, thr);
- // reduce per thread forces and torque into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
-
laststep = update->ntimestep;
}
template <int EVFLAG, int SHEARUPDATE>
-void PairGranHertzHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+void PairGranHertzHistoryOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3;
double shrmag,rsht,polyhertz;
int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch;
double *shear,*allshear,**firstshear;
- double **x = atom->x;
- double **v = atom->v;
- double **omega = atom->omega;
- double *radius = atom->radius;
- double *rmass = atom->rmass;
- double *mass = atom->mass;
- int *type = atom->type;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ const double * const * const v = atom->v;
+ const double * const * const omega = atom->omega;
+ const double * const radius = atom->radius;
+ const double * const rmass = atom->rmass;
+ const double * const mass = atom->mass;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const int * const type = atom->type;
+ const int * const mask = atom->mask;
+ const int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
firsttouch = list->listgranhistory->firstneigh;
firstshear = list->listgranhistory->firstdouble;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
touch = firsttouch[i];
allshear = firstshear[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq >= radsum*radsum) {
// unset non-touching neighbors
touch[jj] = 0;
shear = &allshear[3*jj];
shear[0] = 0.0;
shear[1] = 0.0;
shear[2] = 0.0;
} else {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal force = Hertzian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
polyhertz = sqrt((radsum-r)*radi*radj / radsum);
ccel *= polyhertz;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// shear history effects
touch[jj] = 1;
shear = &allshear[3*jj];
if (SHEARUPDATE) {
shear[0] += vtr1*dt;
shear[1] += vtr2*dt;
shear[2] += vtr3*dt;
}
shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
shear[2]*shear[2]);
// rotate shear displacements
rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
rsht *= rsqinv;
if (SHEARUPDATE) {
shear[0] -= rsht*delx;
shear[1] -= rsht*dely;
shear[2] -= rsht*delz;
}
// tangential forces = shear + tangential velocity damping
fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1);
fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2);
fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3);
// rescale frictional displacements and forces if needed
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
fn = xmu * fabs(ccel*r);
if (fs > fn) {
if (shrmag != 0.0) {
const double fnfs = fn/fs;
const double mgkt = meff*gammat/kt;
shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1;
shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2;
shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3;
fs1 *= fnfs;
fs2 *= fnfs;
fs3 *= fnfs;
} else fs1 = fs2 = fs3 = 0.0;
}
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
fxtmp += fx;
fytmp += fy;
fztmp += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
t1tmp -= radi*tor1;
t2tmp -= radi*tor2;
t3tmp -= radi*tor3;
if (j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0,
- 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairGranHertzHistoryOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGranHertzHistory::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.h b/src/USER-OMP/pair_gran_hertz_history_omp.h
index 66d7bc0fa..956e05709 100644
--- a/src/USER-OMP/pair_gran_hertz_history_omp.h
+++ b/src/USER-OMP/pair_gran_hertz_history_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hertz/history/omp,PairGranHertzHistoryOMP)
#else
#ifndef LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
#define LMP_PAIR_GRAN_HERTZ_HISTORY_OMP_H
#include "pair_gran_hertz_history.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairGranHertzHistoryOMP : public PairGranHertzHistory, public ThrOMP {
public:
PairGranHertzHistoryOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int SHEARUPDATE>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.cpp b/src/USER-OMP/pair_gran_hooke_history_omp.cpp
index ad0537b51..5212b30ce 100644
--- a/src/USER-OMP/pair_gran_hooke_history_omp.cpp
+++ b/src/USER-OMP/pair_gran_hooke_history_omp.cpp
@@ -1,301 +1,296 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gran_hooke_history_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "update.h"
#include "string.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHookeHistoryOMP::PairGranHookeHistoryOMP(LAMMPS *lmp) :
- PairGranHookeHistory(lmp), ThrOMP(lmp, PAIR)
+ PairGranHookeHistory(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
// trigger use of OpenMP version of FixShearHistory
suffix = new char[4];
memcpy(suffix,"omp",4);
}
/* ---------------------------------------------------------------------- */
void PairGranHookeHistoryOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int shearupdate = (update->ntimestep > laststep) ? 1 : 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag)
- if (shearupdate) eval<1,1>(f, torque, ifrom, ito, tid);
- else eval<1,0>(f, torque, ifrom, ito, tid);
+ if (shearupdate) eval<1,1>(ifrom, ito, thr);
+ else eval<1,0>(ifrom, ito, thr);
else
- if (shearupdate) eval<0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0>(f, torque, ifrom, ito, tid);
+ if (shearupdate) eval<0,1>(ifrom, ito, thr);
+ else eval<0,0>(ifrom, ito, thr);
- // reduce per thread forces and torque into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
-
laststep = update->ntimestep;
}
template <int EVFLAG, int SHEARUPDATE>
-void PairGranHookeHistoryOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+void PairGranHookeHistoryOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
+ double myshear[3];
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3;
double shrmag,rsht;
int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch;
double *shear,*allshear,**firstshear;
- double **x = atom->x;
- double **v = atom->v;
- double **omega = atom->omega;
- double *radius = atom->radius;
- double *rmass = atom->rmass;
- double *mass = atom->mass;
- int *type = atom->type;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ const double * const * const v = atom->v;
+ const double * const * const omega = atom->omega;
+ const double * const radius = atom->radius;
+ const double * const rmass = atom->rmass;
+ const double * const mass = atom->mass;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const int * const type = atom->type;
+ const int * const mask = atom->mask;
+ const int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
firsttouch = listgranhistory->firstneigh;
firstshear = listgranhistory->firstdouble;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
touch = firsttouch[i];
allshear = firstshear[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq >= radsum*radsum) {
// unset non-touching neighbors
touch[jj] = 0;
- shear = &allshear[3*jj];
- shear[0] = 0.0;
- shear[1] = 0.0;
- shear[2] = 0.0;
+ myshear[0] = 0.0;
+ myshear[1] = 0.0;
+ myshear[2] = 0.0;
} else {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal forces = Hookian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
- itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// shear history effects
touch[jj] = 1;
- shear = &allshear[3*jj];
+ memcpy(myshear,allshear + 3*jj, 3*sizeof(double));
if (SHEARUPDATE) {
- shear[0] += vtr1*dt;
- shear[1] += vtr2*dt;
- shear[2] += vtr3*dt;
+ myshear[0] += vtr1*dt;
+ myshear[1] += vtr2*dt;
+ myshear[2] += vtr3*dt;
}
- shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] +
- shear[2]*shear[2]);
+ shrmag = sqrt(myshear[0]*myshear[0] + myshear[1]*myshear[1] +
+ myshear[2]*myshear[2]);
// rotate shear displacements
- rsht = shear[0]*delx + shear[1]*dely + shear[2]*delz;
+ rsht = myshear[0]*delx + myshear[1]*dely + myshear[2]*delz;
rsht *= rsqinv;
if (SHEARUPDATE) {
- shear[0] -= rsht*delx;
- shear[1] -= rsht*dely;
- shear[2] -= rsht*delz;
+ myshear[0] -= rsht*delx;
+ myshear[1] -= rsht*dely;
+ myshear[2] -= rsht*delz;
}
// tangential forces = shear + tangential velocity damping
- fs1 = - (kt*shear[0] + meff*gammat*vtr1);
- fs2 = - (kt*shear[1] + meff*gammat*vtr2);
- fs3 = - (kt*shear[2] + meff*gammat*vtr3);
+ fs1 = - (kt*myshear[0] + meff*gammat*vtr1);
+ fs2 = - (kt*myshear[1] + meff*gammat*vtr2);
+ fs3 = - (kt*myshear[2] + meff*gammat*vtr3);
// rescale frictional displacements and forces if needed
fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3);
fn = xmu * fabs(ccel*r);
if (fs > fn) {
if (shrmag != 0.0) {
const double fnfs = fn/fs;
const double mgkt = meff*gammat/kt;
- shear[0] = fnfs * (shear[0] + mgkt*vtr1) - mgkt*vtr1;
- shear[1] = fnfs * (shear[1] + mgkt*vtr2) - mgkt*vtr2;
- shear[2] = fnfs * (shear[2] + mgkt*vtr3) - mgkt*vtr3;
+ myshear[0] = fnfs * (myshear[0] + mgkt*vtr1) - mgkt*vtr1;
+ myshear[1] = fnfs * (myshear[1] + mgkt*vtr2) - mgkt*vtr2;
+ myshear[2] = fnfs * (myshear[2] + mgkt*vtr3) - mgkt*vtr3;
fs1 *= fnfs;
fs2 *= fnfs;
fs3 *= fnfs;
} else fs1 = fs2 = fs3 = 0.0;
}
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
fxtmp += fx;
fytmp += fy;
fztmp += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
t1tmp -= radi*tor1;
t2tmp -= radi*tor2;
t3tmp -= radi*tor3;
if (j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,/* newton_pair */ 0,
- 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,thr);
}
+ memcpy(allshear + 3*jj, myshear, 3*sizeof(double));
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairGranHookeHistoryOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGranHookeHistory::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.h b/src/USER-OMP/pair_gran_hooke_history_omp.h
index 33325025f..7588469e7 100644
--- a/src/USER-OMP/pair_gran_hooke_history_omp.h
+++ b/src/USER-OMP/pair_gran_hooke_history_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hooke/history/omp,PairGranHookeHistoryOMP)
#else
#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H
#define LMP_PAIR_GRAN_HOOKE_HISTORY_OMP_H
#include "pair_gran_hooke_history.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairGranHookeHistoryOMP : public PairGranHookeHistory, public ThrOMP {
public:
PairGranHookeHistoryOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int SHEARUPDATE>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_gran_hooke_omp.cpp b/src/USER-OMP/pair_gran_hooke_omp.cpp
index d6991fa45..fda9295b7 100644
--- a/src/USER-OMP/pair_gran_hooke_omp.cpp
+++ b/src/USER-OMP/pair_gran_hooke_omp.cpp
@@ -1,240 +1,236 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_gran_hooke_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairGranHookeOMP::PairGranHookeOMP(LAMMPS *lmp) :
- PairGranHooke(lmp), ThrOMP(lmp, PAIR)
+ PairGranHooke(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairGranHookeOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag)
- if (force->newton_pair) eval<1,1>(f, torque, ifrom, ito, tid);
- else eval<1,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1>(ifrom, ito, thr);
+ else eval<1,0>(ifrom, ito, thr);
else
- if (force->newton_pair) eval<0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,1>(ifrom, ito, thr);
+ else eval<0,0>(ifrom, ito, thr);
- // reduce per thread forces and torque into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
}
template <int EVFLAG, int NEWTON_PAIR>
-void PairGranHookeOMP::eval(double **f, double **torque, int iifrom, int iito, int tid)
+void PairGranHookeOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv,rsqinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel;
double meff,damp,ccel,tor1,tor2,tor3;
double fn,fs,ft,fs1,fs2,fs3;
int *ilist,*jlist,*numneigh,**firstneigh;
- double **x = atom->x;
- double **v = atom->v;
- double **omega = atom->omega;
- double *radius = atom->radius;
- double *rmass = atom->rmass;
- double *mass = atom->mass;
- int *type = atom->type;
- int *mask = atom->mask;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ const double * const * const v = atom->v;
+ const double * const * const omega = atom->omega;
+ const double * const radius = atom->radius;
+ const double * const rmass = atom->rmass;
+ const double * const mass = atom->mass;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const int * const type = atom->type;
+ const int * const mask = atom->mask;
+ const int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
radsum = radi + radj;
if (rsq < radsum*radsum) {
r = sqrt(rsq);
rinv = 1.0/r;
rsqinv = 1.0/rsq;
// relative translational velocity
vr1 = v[i][0] - v[j][0];
vr2 = v[i][1] - v[j][1];
vr3 = v[i][2] - v[j][2];
// normal component
vnnr = vr1*delx + vr2*dely + vr3*delz;
vn1 = delx*vnnr * rsqinv;
vn2 = dely*vnnr * rsqinv;
vn3 = delz*vnnr * rsqinv;
// tangential component
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// relative rotational velocity
wr1 = (radi*omega[i][0] + radj*omega[j][0]) * rinv;
wr2 = (radi*omega[i][1] + radj*omega[j][1]) * rinv;
wr3 = (radi*omega[i][2] + radj*omega[j][2]) * rinv;
// normal forces = Hookian contact + normal velocity damping
if (rmass) {
meff = rmass[i]*rmass[j] / (rmass[i]+rmass[j]);
if (mask[i] & freeze_group_bit) meff = rmass[j];
if (mask[j] & freeze_group_bit) meff = rmass[i];
} else {
itype = type[i];
jtype = type[j];
meff = mass[itype]*mass[jtype] / (mass[itype]+mass[jtype]);
if (mask[i] & freeze_group_bit) meff = mass[jtype];
if (mask[j] & freeze_group_bit) meff = mass[itype];
}
damp = meff*gamman*vnnr*rsqinv;
ccel = kn*(radsum-r)*rinv - damp;
// relative velocities
vtr1 = vt1 - (delz*wr2-dely*wr3);
vtr2 = vt2 - (delx*wr3-delz*wr1);
vtr3 = vt3 - (dely*wr1-delx*wr2);
vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3;
vrel = sqrt(vrel);
// force normalization
fn = xmu * fabs(ccel*r);
fs = meff*gammat*vrel;
if (vrel != 0.0) ft = MIN(fn,fs) / vrel;
else ft = 0.0;
// tangential force due to tangential velocity damping
fs1 = -ft*vtr1;
fs2 = -ft*vtr2;
fs3 = -ft*vtr3;
// forces & torques
fx = delx*ccel + fs1;
fy = dely*ccel + fs2;
fz = delz*ccel + fs3;
fxtmp += fx;
fytmp += fy;
fztmp += fz;
tor1 = rinv * (dely*fs3 - delz*fs2);
tor2 = rinv * (delz*fs1 - delx*fs3);
tor3 = rinv * (delx*fs2 - dely*fs1);
t1tmp -= radi*tor1;
t2tmp -= radi*tor2;
t3tmp -= radi*tor3;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fx;
f[j][1] -= fy;
f[j][2] -= fz;
torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3;
}
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
- 0.0,0.0,fx,fy,fz,delx,dely,delz,tid);
+ 0.0,0.0,fx,fy,fz,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
torque[i][0] += t1tmp;
torque[i][1] += t2tmp;
torque[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairGranHookeOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairGranHooke::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_gran_hooke_omp.h b/src/USER-OMP/pair_gran_hooke_omp.h
index f2b093778..b275992bf 100644
--- a/src/USER-OMP/pair_gran_hooke_omp.h
+++ b/src/USER-OMP/pair_gran_hooke_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(gran/hooke/omp,PairGranHookeOMP)
#else
#ifndef LMP_PAIR_GRAN_HOOKE_OMP_H
#define LMP_PAIR_GRAN_HOOKE_OMP_H
#include "pair_gran_hooke.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairGranHookeOMP : public PairGranHooke, public ThrOMP {
public:
PairGranHookeOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int NEWTON_PAIR>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
index 012fd596b..5da3f2bdf 100644
--- a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
+++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp
@@ -1,299 +1,296 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_hbond_dreiding_lj_omp.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
PairHbondDreidingLJOMP::PairHbondDreidingLJOMP(LAMMPS *lmp) :
- PairHbondDreidingLJ(lmp), ThrOMP(lmp, PAIR)
+ PairHbondDreidingLJ(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
hbcount_thr = hbeng_thr = NULL;
}
/* ---------------------------------------------------------------------- */
PairHbondDreidingLJOMP::~PairHbondDreidingLJOMP()
{
respa_enable = 0;
if (hbcount_thr) {
delete[] hbcount_thr;
delete[] hbeng_thr;
}
}
/* ---------------------------------------------------------------------- */
void PairHbondDreidingLJOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
if (!hbcount_thr) {
hbcount_thr = new double[nthreads];
hbeng_thr = new double[nthreads];
}
for (int i=0; i < nthreads; ++i) {
hbcount_thr[i] = 0.0;
hbeng_thr[i] = 0.0;
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
-
// reduce per thread hbond data
if (eflag_global) {
pvector[0] = 0.0;
pvector[1] = 0.0;
for (int i=0; i < nthreads; ++i) {
pvector[0] += hbcount_thr[i];
pvector[1] += hbeng_thr[i];
}
}
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairHbondDreidingLJOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairHbondDreidingLJOMP::eval(int iifrom, int iito, ThrData * const thr)
{
- int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype;
+ int i,j,k,m,ii,jj,kk,jnum,itype,jtype,ktype;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
double factor_hb,force_angle,force_kernel,evdwl,eng_lj;
double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
double fi[3],fj[3],delr1[3],delr2[3];
double r2inv,r10inv;
double switch1,switch2;
- int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+ int *ilist,*jlist,*numneigh,**firstneigh;
Param *pm;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int **special = atom->special;
- int **nspecial = atom->nspecial;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const double * const special_lj = force->special_lj;
+ const int * const * const nspecial = atom->nspecial;
+ const int * const * const special = atom->special;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// ii = loop over donors
// jj = loop over acceptors
// kk = loop over hydrogens bonded to donor
int hbcount = 0;
double hbeng = 0.0;
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itype = type[i];
if (!donor[itype]) continue;
- klist = special[i];
- knum = nspecial[i][0];
+ const int * const klist = special[i];
+ const int knum = nspecial[i][0];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_hb = special_lj[sbmask(j)];
j &= NEIGHMASK;
jtype = type[j];
if (!acceptor[jtype]) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
for (kk = 0; kk < knum; kk++) {
k = atom->map(klist[kk]);
if (k < 0) continue;
ktype = type[k];
m = type2param[itype][jtype][ktype];
if (m < 0) continue;
pm = &params[m];
if (rsq < pm->cut_outersq) {
delr1[0] = xtmp - x[k][0];
delr1[1] = ytmp - x[k][1];
delr1[2] = ztmp - x[k][2];
domain->minimum_image(delr1);
rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
r1 = sqrt(rsq1);
delr2[0] = x[j][0] - x[k][0];
delr2[1] = x[j][1] - x[k][1];
delr2[2] = x[j][2] - x[k][2];
domain->minimum_image(delr2);
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2];
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
ac = acos(c);
if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// LJ-specific kernel
r2inv = 1.0/rsq;
r10inv = r2inv*r2inv*r2inv*r2inv*r2inv;
force_kernel = r10inv*(pm->lj1*r2inv - pm->lj2)*r2inv *
pow(c,pm->ap);
force_angle = pm->ap * r10inv*(pm->lj3*r2inv - pm->lj4) *
pow(c,pm->ap-1)*s;
eng_lj = r10inv*(pm->lj3*r2inv - pm->lj4);
if (rsq > pm->cut_innersq) {
switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) *
(pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) /
pm->denom_vdw;
switch2 = 12.0*rsq * (pm->cut_outersq-rsq) *
(rsq-pm->cut_innersq) / pm->denom_vdw;
force_kernel = force_kernel*switch1 + eng_lj*switch2;
eng_lj *= switch1;
}
if (EFLAG) {
evdwl = eng_lj * pow(c,pm->ap);
evdwl *= factor_hb;
}
a = factor_hb*force_angle/s;
b = factor_hb*force_kernel;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
vx1 = a11*delr1[0] + a12*delr2[0];
vx2 = a22*delr2[0] + a12*delr1[0];
vy1 = a11*delr1[1] + a12*delr2[1];
vy2 = a22*delr2[1] + a12*delr1[1];
vz1 = a11*delr1[2] + a12*delr2[2];
vz2 = a22*delr2[2] + a12*delr1[2];
fi[0] = vx1 + b*delx;
fi[1] = vy1 + b*dely;
fi[2] = vz1 + b*delz;
fj[0] = vx2 - b*delx;
fj[1] = vy2 - b*dely;
fj[2] = vz2 - b*delz;
fxtmp += fi[0];
fytmp += fi[1];
fztmp += fi[2];
f[j][0] += fj[0];
f[j][1] += fj[1];
f[j][2] += fj[2];
f[k][0] -= vx1 + vx2;
f[k][1] -= vy1 + vy2;
f[k][2] -= vz1 + vz2;
// KIJ instead of IJK b/c delr1/delr2 are both with respect to k
- if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid);
+ if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,thr);
if (EFLAG) {
hbcount++;
hbeng += evdwl;
}
}
}
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
+ const int tid = thr->get_tid();
hbcount_thr[tid] = static_cast<double>(hbcount);
hbeng_thr[tid] = hbeng;
}
/* ---------------------------------------------------------------------- */
double PairHbondDreidingLJOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += comm->nthreads * 2 * sizeof(double);
bytes += PairHbondDreidingLJ::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.h b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h
index 1aef78490..937391684 100644
--- a/src/USER-OMP/pair_hbond_dreiding_lj_omp.h
+++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(hbond/dreiding/lj/omp,PairHbondDreidingLJOMP)
#else
#ifndef LMP_PAIR_HBOND_DREIDING_LJ_OMP_H
#define LMP_PAIR_HBOND_DREIDING_LJ_OMP_H
#include "pair_hbond_dreiding_lj.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairHbondDreidingLJOMP : public PairHbondDreidingLJ, public ThrOMP {
public:
PairHbondDreidingLJOMP(class LAMMPS *);
virtual ~PairHbondDreidingLJOMP();
virtual void compute(int, int);
virtual double memory_usage();
protected:
double *hbcount_thr, *hbeng_thr;
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
index b6c966f8c..bce4efdd3 100644
--- a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
+++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp
@@ -1,297 +1,294 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_hbond_dreiding_morse_omp.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
PairHbondDreidingMorseOMP::PairHbondDreidingMorseOMP(LAMMPS *lmp) :
- PairHbondDreidingMorse(lmp), ThrOMP(lmp, PAIR)
+ PairHbondDreidingMorse(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
hbcount_thr = hbeng_thr = NULL;
}
/* ---------------------------------------------------------------------- */
PairHbondDreidingMorseOMP::~PairHbondDreidingMorseOMP()
{
respa_enable = 0;
if (hbcount_thr) {
delete[] hbcount_thr;
delete[] hbeng_thr;
}
}
/* ---------------------------------------------------------------------- */
void PairHbondDreidingMorseOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
if (!hbcount_thr) {
hbcount_thr = new double[nthreads];
hbeng_thr = new double[nthreads];
}
for (int i=0; i < nthreads; ++i) {
hbcount_thr[i] = 0.0;
hbeng_thr[i] = 0.0;
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
-
// reduce per thread hbond data
if (eflag_global) {
pvector[0] = 0.0;
pvector[1] = 0.0;
for (int i=0; i < nthreads; ++i) {
pvector[0] += hbcount_thr[i];
pvector[1] += hbeng_thr[i];
}
}
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairHbondDreidingMorseOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairHbondDreidingMorseOMP::eval(int iifrom, int iito, ThrData * const thr)
{
- int i,j,k,m,ii,jj,kk,jnum,knum,itype,jtype,ktype;
+ int i,j,k,m,ii,jj,kk,jnum,itype,jtype,ktype;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq,rsq1,rsq2,r1,r2;
double factor_hb,force_angle,force_kernel,evdwl;
double c,s,a,b,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
double fi[3],fj[3],delr1[3],delr2[3];
double r,dr,dexp,eng_morse,switch1,switch2;
- int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+ int *ilist,*jlist,*numneigh,**firstneigh;
Param *pm;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int **special = atom->special;
- int **nspecial = atom->nspecial;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const double * const special_lj = force->special_lj;
+ const int * const * const nspecial = atom->nspecial;
+ const int * const * const special = atom->special;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// ii = loop over donors
// jj = loop over acceptors
// kk = loop over hydrogens bonded to donor
int hbcount = 0;
double hbeng = 0.0;
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itype = type[i];
if (!donor[itype]) continue;
- klist = special[i];
- knum = nspecial[i][0];
+ const int * const klist = special[i];
+ const int knum = nspecial[i][0];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_hb = special_lj[sbmask(j)];
j &= NEIGHMASK;
jtype = type[j];
if (!acceptor[jtype]) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
for (kk = 0; kk < knum; kk++) {
k = atom->map(klist[kk]);
if (k < 0) continue;
ktype = type[k];
m = type2param[itype][jtype][ktype];
if (m < 0) continue;
pm = &params[m];
if (rsq < pm->cut_outersq) {
delr1[0] = xtmp - x[k][0];
delr1[1] = ytmp - x[k][1];
delr1[2] = ztmp - x[k][2];
domain->minimum_image(delr1);
rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
r1 = sqrt(rsq1);
delr2[0] = x[j][0] - x[k][0];
delr2[1] = x[j][1] - x[k][1];
delr2[2] = x[j][2] - x[k][2];
domain->minimum_image(delr2);
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delr1[0]*delr2[0] + delr1[1]*delr2[1] + delr1[2]*delr2[2];
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
ac = acos(c);
if (ac > pm->cut_angle && ac < (2.0*MY_PI - pm->cut_angle)) {
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// Morse-specific kernel
r = sqrt(rsq);
dr = r - pm->r0;
dexp = exp(-pm->alpha * dr);
force_kernel = pm->morse1*(dexp*dexp - dexp)/r * pow(c,pm->ap);
force_angle = pm->ap * eng_morse * pow(c,pm->ap-1)*s;
eng_morse = pm->d0 * (dexp*dexp - 2.0*dexp);
if (rsq > pm->cut_innersq) {
switch1 = (pm->cut_outersq-rsq) * (pm->cut_outersq-rsq) *
(pm->cut_outersq + 2.0*rsq - 3.0*pm->cut_innersq) /
pm->denom_vdw;
switch2 = 12.0*rsq * (pm->cut_outersq-rsq) *
(rsq-pm->cut_innersq) / pm->denom_vdw;
force_kernel = force_kernel*switch1 + eng_morse*switch2;
eng_morse *= switch1;
}
if (EFLAG) {
evdwl = eng_morse * pow(c,params[m].ap);
evdwl *= factor_hb;
}
a = factor_hb*force_angle/s;
b = factor_hb*force_kernel;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
vx1 = a11*delr1[0] + a12*delr2[0];
vx2 = a22*delr2[0] + a12*delr1[0];
vy1 = a11*delr1[1] + a12*delr2[1];
vy2 = a22*delr2[1] + a12*delr1[1];
vz1 = a11*delr1[2] + a12*delr2[2];
vz2 = a22*delr2[2] + a12*delr1[2];
fi[0] = vx1 + b*delx;
fi[1] = vy1 + b*dely;
fi[2] = vz1 + b*delz;
fj[0] = vx2 - b*delx;
fj[1] = vy2 - b*dely;
fj[2] = vz2 - b*delz;
fxtmp += fi[0];
fytmp += fi[1];
fztmp += fi[2];
f[j][0] += fj[0];
f[j][1] += fj[1];
f[j][2] += fj[2];
f[k][0] -= vx1 + vx2;
f[k][1] -= vy1 + vy2;
f[k][2] -= vz1 + vz2;
// KIJ instead of IJK b/c delr1/delr2 are both with respect to k
- if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,tid);
+ if (EVFLAG) ev_tally3_thr(this,k,i,j,evdwl,0.0,fi,fj,delr1,delr2,thr);
if (EFLAG) {
hbcount++;
hbeng += evdwl;
}
}
}
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
+ const int tid = thr->get_tid();
hbcount_thr[tid] = static_cast<double>(hbcount);
hbeng_thr[tid] = hbeng;
}
/* ---------------------------------------------------------------------- */
double PairHbondDreidingMorseOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += comm->nthreads * 2 * sizeof(double);
bytes += PairHbondDreidingMorse::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.h b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h
index 2a13c618c..d2edd7281 100644
--- a/src/USER-OMP/pair_hbond_dreiding_morse_omp.h
+++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(hbond/dreiding/morse/omp,PairHbondDreidingMorseOMP)
#else
#ifndef LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H
#define LMP_PAIR_HBOND_DREIDING_MORSE_OMP_H
#include "pair_hbond_dreiding_morse.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairHbondDreidingMorseOMP : public PairHbondDreidingMorse, public ThrOMP {
public:
PairHbondDreidingMorseOMP(class LAMMPS *);
virtual ~PairHbondDreidingMorseOMP();
virtual void compute(int, int);
virtual double memory_usage();
protected:
double *hbcount_thr, *hbeng_thr;
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_line_lj_omp.cpp b/src/USER-OMP/pair_line_lj_omp.cpp
new file mode 100644
index 000000000..59982735d
--- /dev/null
+++ b/src/USER-OMP/pair_line_lj_omp.cpp
@@ -0,0 +1,339 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_line_lj_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#include <string.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairLineLJOMP::PairLineLJOMP(LAMMPS *lmp) :
+ PairLineLJ(lmp), ThrOMP(lmp, THR_PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLineLJOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+ const int * const line = atom->line;
+ const int * const type = atom->type;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ nmax = nall;
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ memset(dnum,0,nall*sizeof(int));
+ ndiscrete = 0;
+
+ // need to discretize the system ahead of time
+ // until we find a good way to multi-thread it.
+ for (int i = 0; i < nall; ++i)
+ if (line[i] >= 0)
+ if (dnum[i] == 0)
+ discretize(i,sigma[type[i]][type[i]]);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+void PairLineLJOMP::eval(int iifrom, int iito, ThrData * const thr)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double xi[2],xj[2],fi[2],fj[2],dxi,dxj,dyi,dyj,ti,tj;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const int * const line = atom->line;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq >= cutsq[itype][jtype]) continue;
+
+ // line/line interactions = NxN particles
+
+ evdwl = 0.0;
+ if (line[i] >= 0 && line[j] >= 0) {
+ npi = dnum[i];
+ ifirst = dfirst[i];
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ fi[0] = fi[1] = fj[0] = fj[1] = ti = tj = 0.0;
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ ti += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ tj += fpair*(dxj*dely - dyj*delx);
+ }
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ torque[i][2] += ti;
+ torque[j][2] += tj;
+
+ // line/particle interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[i] >= 0) {
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ fi[0] = fi[1] = fj[0] = fj[1] = ti = tj = 0.0;
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ ti += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ tj += fpair*(dxj*dely - dyj*delx);
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ torque[i][2] += ti;
+ torque[j][2] += tj;
+
+ // particle/line interaction = Nx1 particles
+ // convert line into Np particles based on sigma and line length
+
+ } else if (line[j] >= 0) {
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ fi[0] = fi[1] = fj[0] = fj[1] = ti = tj = 0.0;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ rsq = delx*delx + dely*dely;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ ti += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ tj -= fpair*(dxj*dely - dyj*delx);
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ torque[i][2] += ti;
+ torque[j][2] += tj;
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLineLJOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLineLJ::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_line_lj_omp.h
similarity index 79%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/pair_line_lj_omp.h
index b24de4a57..93b38afaf 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_line_lj_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(born/omp,PairBornOMP)
+PairStyle(line/lj/omp,PairLineLJOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_PAIR_LINE_LJ_OMP_H
+#define LMP_PAIR_LINE_LJ_OMP_H
-#include "pair_born.h"
+#include "pair_line_lj.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class PairLineLJOMP : public PairLineLJ, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ PairLineLJOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj96_cut_omp.cpp b/src/USER-OMP/pair_lj96_cut_omp.cpp
index f0998363e..68733c109 100644
--- a/src/USER-OMP/pair_lj96_cut_omp.cpp
+++ b/src/USER-OMP/pair_lj96_cut_omp.cpp
@@ -1,162 +1,158 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj96_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJ96CutOMP::PairLJ96CutOMP(LAMMPS *lmp) :
- PairLJ96Cut(lmp), ThrOMP(lmp, PAIR)
+ PairLJ96Cut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJ96CutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJ96CutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJ96CutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
r3inv = sqrt(r6inv);
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype])
- offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJ96CutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJ96Cut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj96_cut_omp.h b/src/USER-OMP/pair_lj96_cut_omp.h
index 333212303..a8040320c 100644
--- a/src/USER-OMP/pair_lj96_cut_omp.h
+++ b/src/USER-OMP/pair_lj96_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj96/cut/omp,PairLJ96CutOMP)
#else
#ifndef LMP_PAIR_LJ96_CUT_OMP_H
#define LMP_PAIR_LJ96_CUT_OMP_H
#include "pair_lj96_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJ96CutOMP : public PairLJ96Cut, public ThrOMP {
public:
PairLJ96CutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
index 32ad05acd..edfbe1f52 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp
@@ -1,213 +1,208 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_charmm_coul_charmm_implicit_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJCharmmCoulCharmmImplicitOMP::PairLJCharmmCoulCharmmImplicitOMP(LAMMPS *lmp) :
- PairLJCharmmCoulCharmmImplicit(lmp), ThrOMP(lmp, PAIR)
+ PairLJCharmmCoulCharmmImplicit(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCharmmCoulCharmmImplicitOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCharmmCoulCharmmImplicitOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCharmmCoulCharmmImplicitOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double philj,switch1,switch2;
- double invdenom_coul,invdenom_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
- invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
+ const double invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
+ const double invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cut_bothsq) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
forcecoul = 2.0 * qqrd2e * qtmp*q[j]*r2inv;
if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * invdenom_coul;
switch2 = 12.0*rsq * (cut_coulsq-rsq) *
(rsq-cut_coul_innersq) * invdenom_coul;
forcecoul *= switch1 + switch2;
}
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj;
switch2 = 12.0*rsq * (cut_ljsq-rsq) *
(rsq-cut_lj_innersq) * invdenom_lj;
philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
forcelj = forcelj*switch1 + philj*switch2;
}
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = qqrd2e * qtmp*q[j]*r2inv;
if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) *
invdenom_coul;
ecoul *= switch1;
}
ecoul *= factor_coul;
} else ecoul = 0.0;
if (rsq < cut_ljsq) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj;
evdwl *= switch1;
}
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCharmmCoulCharmmImplicitOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCharmmCoulCharmmImplicit::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
index ba016d7d3..dff01ce49 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/charmm/coul/charmm/implicit/omp,PairLJCharmmCoulCharmmImplicitOMP)
#else
#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H
#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_IMPLICIT_OMP_H
#include "pair_lj_charmm_coul_charmm_implicit.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCharmmCoulCharmmImplicitOMP : public PairLJCharmmCoulCharmmImplicit, public ThrOMP {
public:
PairLJCharmmCoulCharmmImplicitOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
index 6dac7a17f..efdcc995d 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp
@@ -1,213 +1,208 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_charmm_coul_charmm_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJCharmmCoulCharmmOMP::PairLJCharmmCoulCharmmOMP(LAMMPS *lmp) :
- PairLJCharmmCoulCharmm(lmp), ThrOMP(lmp, PAIR)
+ PairLJCharmmCoulCharmm(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCharmmCoulCharmmOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCharmmCoulCharmmOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCharmmCoulCharmmOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double philj,switch1,switch2;
- double invdenom_coul,invdenom_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
- invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
- invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
+ const double invdenom_coul = (denom_coul != 0.0) ? 1.0/denom_coul : 0.0;
+ const double invdenom_lj = (denom_lj != 0.0) ? 1.0/denom_lj : 0.0;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cut_bothsq) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) * invdenom_coul;
switch2 = 12.0*rsq * (cut_coulsq-rsq) *
(rsq-cut_coul_innersq) * invdenom_coul;
forcecoul *= switch1 + switch2;
}
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj;
switch2 = 12.0*rsq * (cut_ljsq-rsq) *
(rsq-cut_lj_innersq) * invdenom_lj;
philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
forcelj = forcelj*switch1 + philj*switch2;
}
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) *
invdenom_coul;
ecoul *= switch1;
}
ecoul *= factor_coul;
} else ecoul = 0.0;
if (rsq < cut_ljsq) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) * invdenom_lj;
evdwl *= switch1;
}
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCharmmCoulCharmmOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCharmmCoulCharmm::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
index f2889b05f..0eda030eb 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
+++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/charmm/coul/charmm/omp,PairLJCharmmCoulCharmmOMP)
#else
#ifndef LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H
#define LMP_PAIR_LJ_CHARMM_COUL_CHARMM_OMP_H
#include "pair_lj_charmm_coul_charmm.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCharmmCoulCharmmOMP : public PairLJCharmmCoulCharmm, public ThrOMP {
public:
PairLJCharmmCoulCharmmOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
index c99f27f2e..f9f32ea11 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
@@ -1,234 +1,230 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_charmm_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairLJCharmmCoulLongOMP::PairLJCharmmCoulLongOMP(LAMMPS *lmp) :
- PairLJCharmmCoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairLJCharmmCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCharmmCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCharmmCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCharmmCoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
double philj,switch1,switch2;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
} else forcecoul = 0.0;
if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
switch2 = 12.0*rsq * (cut_ljsq-rsq) *
(rsq-cut_lj_innersq) / denom_lj;
philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
forcelj = forcelj*switch1 + philj*switch2;
}
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
evdwl *= switch1;
}
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCharmmCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCharmmCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
index b14e4c1fe..91b9c01c1 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/charmm/coul/long/omp,PairLJCharmmCoulLongOMP)
#else
#ifndef LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
#define LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
#include "pair_lj_charmm_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCharmmCoulLongOMP : public PairLJCharmmCoulLong, public ThrOMP {
public:
PairLJCharmmCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_pppm_omp.cpp
similarity index 71%
copy from src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
copy to src/USER-OMP/pair_lj_charmm_coul_pppm_omp.cpp
index c99f27f2e..3b1266854 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_charmm_coul_pppm_omp.cpp
@@ -1,234 +1,260 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_lj_charmm_coul_long_omp.h"
+#include "pair_lj_charmm_coul_pppm_omp.h"
+#include "pppm_proxy.h"
#include "atom.h"
#include "comm.h"
+#include "error.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "update.h"
+
+#include <string.h>
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
-PairLJCharmmCoulLongOMP::PairLJCharmmCoulLongOMP(LAMMPS *lmp) :
- PairLJCharmmCoulLong(lmp), ThrOMP(lmp, PAIR)
+PairLJCharmmCoulPPPMOMP::PairLJCharmmCoulPPPMOMP(LAMMPS *lmp) :
+ PairLJCharmmCoulLong(lmp), ThrOMP(lmp, THR_PAIR|THR_PROXY)
{
respa_enable = 0;
+ nproxy=1;
+
+ kspace = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCharmmCoulPPPMOMP::init_style()
+{
+ if (comm->nthreads < 2)
+ error->all(FLERR,"need at least two threads per MPI task for this pair style");
+
+ if (strcmp(force->kspace_style,"pppm/proxy") != 0)
+ error->all(FLERR,"kspace style pppm/proxy is required with this pair style");
+
+ kspace = static_cast<PPPMProxy *>(force->kspace);
+
+ PairLJCharmmCoulLong::init_style();
}
/* ---------------------------------------------------------------------- */
-void PairLJCharmmCoulLongOMP::compute(int eflag, int vflag)
+void PairLJCharmmCoulPPPMOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads, nproxy);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
- if (evflag) {
- if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ // thread id 0 runs pppm, the rest the pair style
+ if (tid < nproxy) {
+ if (update->setupflag) kspace->setup_proxy();
+ kspace->compute_proxy(eflag,vflag);
+ } else {
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- } else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
}
-
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+
+ sync_threads();
+ reduce_thr(this, eflag, vflag, thr, nproxy);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCharmmCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCharmmCoulPPPMOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
double philj,switch1,switch2;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
} else forcecoul = 0.0;
if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
switch2 = 12.0*rsq * (cut_ljsq-rsq) *
(rsq-cut_lj_innersq) / denom_lj;
philj = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
forcelj = forcelj*switch1 + philj*switch2;
}
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
evdwl *= switch1;
}
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-double PairLJCharmmCoulLongOMP::memory_usage()
+double PairLJCharmmCoulPPPMOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCharmmCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h b/src/USER-OMP/pair_lj_charmm_coul_pppm_omp.h
similarity index 72%
copy from src/USER-OMP/pair_lj_charmm_coul_long_omp.h
copy to src/USER-OMP/pair_lj_charmm_coul_pppm_omp.h
index b14e4c1fe..1faee2c47 100644
--- a/src/USER-OMP/pair_lj_charmm_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_charmm_coul_pppm_omp.h
@@ -1,48 +1,54 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(lj/charmm/coul/long/omp,PairLJCharmmCoulLongOMP)
+PairStyle(lj/charmm/coul/pppm/omp,PairLJCharmmCoulPPPMOMP)
#else
-#ifndef LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
-#define LMP_PAIR_LJ_CHARMM_COUL_LONG_OMP_H
+#ifndef LMP_PAIR_LJ_CHARMM_COUL_PPPM_OMP_H
+#define LMP_PAIR_LJ_CHARMM_COUL_PPPM_OMP_H
#include "pair_lj_charmm_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCharmmCoulLongOMP : public PairLJCharmmCoulLong, public ThrOMP {
+class PairLJCharmmCoulPPPMOMP : public PairLJCharmmCoulLong, public ThrOMP {
public:
- PairLJCharmmCoulLongOMP(class LAMMPS *);
+ PairLJCharmmCoulPPPMOMP(class LAMMPS *);
+ virtual ~PairLJCharmmCoulPPPMOMP() {};
+
+ virtual void init_style();
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
+
+ class PPPMProxy *kspace;
+ int nproxy;
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
index 032188279..e54c348e6 100644
--- a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
+++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp
@@ -1,185 +1,181 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_class2_coul_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJClass2CoulCutOMP::PairLJClass2CoulCutOMP(LAMMPS *lmp) :
- PairLJClass2CoulCut(lmp), ThrOMP(lmp, PAIR)
+ PairLJClass2CoulCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJClass2CoulCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJClass2CoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJClass2CoulCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj;
double factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
rinv = sqrt(r2inv);
if (rsq < cut_coulsq[itype][jtype]) {
forcecoul = qqrd2e * qtmp*q[j]*rinv;
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r3inv = r2inv*rinv;
r6inv = r3inv*r3inv;
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype])
ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv;
else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
-
+
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJClass2CoulCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJClass2CoulCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
index 5fe489569..b22a29aa1 100644
--- a/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
+++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/class2/coul/cut/omp,PairLJClass2CoulCutOMP)
#else
#ifndef LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
#define LMP_PAIR_LJ_CLASS2_COUL_CUT_OMP_H
#include "pair_lj_class2_coul_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJClass2CoulCutOMP : public PairLJClass2CoulCut, public ThrOMP {
public:
PairLJClass2CoulCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
index 84d26ceb1..20ad947d2 100644
--- a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp
@@ -1,201 +1,197 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_class2_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairLJClass2CoulLongOMP::PairLJClass2CoulLongOMP(LAMMPS *lmp) :
- PairLJClass2CoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairLJClass2CoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJClass2CoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJClass2CoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJClass2CoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
rinv = sqrt(r2inv);
r3inv = r2inv*rinv;
r6inv = r3inv*r3inv;
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = prefactor*erfc;
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJClass2CoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJClass2CoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.h b/src/USER-OMP/pair_lj_class2_coul_long_omp.h
index da4ac3680..b32799bf8 100644
--- a/src/USER-OMP/pair_lj_class2_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/class2/coul/long/omp,PairLJClass2CoulLongOMP)
#else
#ifndef LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H
#define LMP_PAIR_LJ_CLASS2_COUL_LONG_OMP_H
#include "pair_lj_class2_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJClass2CoulLongOMP : public PairLJClass2CoulLong, public ThrOMP {
public:
PairLJClass2CoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_class2_omp.cpp b/src/USER-OMP/pair_lj_class2_omp.cpp
index 4f5d2550f..cff80d3f1 100644
--- a/src/USER-OMP/pair_lj_class2_omp.cpp
+++ b/src/USER-OMP/pair_lj_class2_omp.cpp
@@ -1,162 +1,158 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJClass2OMP::PairLJClass2OMP(LAMMPS *lmp) :
- PairLJClass2(lmp), ThrOMP(lmp, PAIR)
+ PairLJClass2(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJClass2OMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJClass2OMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
r3inv = sqrt(r6inv);
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype])
- offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJClass2OMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJClass2::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_class2_omp.h b/src/USER-OMP/pair_lj_class2_omp.h
index cfe24bb71..317c7376c 100644
--- a/src/USER-OMP/pair_lj_class2_omp.h
+++ b/src/USER-OMP/pair_lj_class2_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/class2/omp,PairLJClass2OMP)
#else
#ifndef LMP_PAIR_LJ_CLASS2_OMP_H
#define LMP_PAIR_LJ_CLASS2_OMP_H
#include "pair_lj_class2.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJClass2OMP : public PairLJClass2, public ThrOMP {
public:
PairLJClass2OMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_coul_omp.cpp b/src/USER-OMP/pair_lj_coul_omp.cpp
index 23e2a8d90..ae15087ba 100644
--- a/src/USER-OMP/pair_lj_coul_omp.cpp
+++ b/src/USER-OMP/pair_lj_coul_omp.cpp
@@ -1,234 +1,230 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_coul_omp.h"
#include "atom.h"
#include "comm.h"
#include "math_vector.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairLJCoulOMP::PairLJCoulOMP(LAMMPS *lmp) :
- PairLJCoul(lmp), ThrOMP(lmp, PAIR)
+ PairLJCoul(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCoulOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCoulOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCoulOMP::eval(int iifrom, int iito, ThrData * const thr)
{
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
- double *x0 = x[0];
+ const double *x0 = x[0];
double *f0 = f[0], *fi = f0;
int *ilist = list->ilist;
// loop over neighbors of my atoms
int i, ii, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
int *jneigh, *jneighn, typei, typej, ni;
double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti;
double rsq, r2inv, force_coul, force_lj;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
vector xi, d;
for (ii = iifrom; ii < iito; ++ii) { // loop over my atoms
i = ilist[ii]; fi = f0+3*i;
if (order1) qri = (qi = q[i])*qqrd2e; // initialize constants
offseti = offset[typei = type[i]];
lj1i = lj1[typei]; lj2i = lj2[typei]; lj3i = lj3[typei]; lj4i = lj4[typei];
cutsqi = cutsq[typei]; cut_ljsqi = cut_ljsq[typei];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
for (; jneigh<jneighn; ++jneigh) { // loop over neighbors
j = *jneigh;
ni = sbmask(j);
j &= NEIGHMASK;
- { register double *xj = x0+(j+(j<<1));
+ { register const double *xj = x0+(j+(j<<1));
d[0] = xi[0] - xj[0]; // pair vector
d[1] = xi[1] - xj[1];
d[2] = xi[2] - xj[2]; }
if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue;
r2inv = 1.0/rsq;
if (order1 && (rsq < cut_coulsq)) { // coulombic
if (!ncoultablebits || rsq <= tabinnersq) { // series real space
register double r = sqrt(rsq), x = g_ewald*r;
register double s = qri*q[j], t = 1.0/(1.0+EWALD_P*x);
if (ni == 0) {
s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (EFLAG) ecoul = t;
}
else { // special case
r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r;
if (EFLAG) ecoul = t-r;
}
} // table real space
else {
register union_int_float_t t;
t.f = rsq;
register const int k = (t.i & ncoulmask)>>ncoulshiftbits;
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni == 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]);
}
else { // special case
t.f = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t.f);
if (EFLAG) ecoul = qiqj*(etable[k]+f*detable[k]-t.f);
}
}
}
else force_coul = ecoul = 0.0;
if (rsq < cut_ljsqi[typej]) { // lj
if (order6) { // long-range lj
register double rn = r2inv*r2inv*r2inv;
register double x2 = g2*rsq, a2 = 1.0/x2;
x2 = a2*exp(-x2)*lj4i[typej];
if (ni == 0) {
force_lj =
(rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (EFLAG)
evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2;
}
else { // special case
register double f = special_lj[ni], t = rn*(1.0-f);
force_lj = f*(rn *= rn)*lj1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej];
if (EFLAG)
evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej];
}
}
else { // cut lj
register double rn = r2inv*r2inv*r2inv;
if (ni == 0) {
force_lj = rn*(rn*lj1i[typej]-lj2i[typej]);
if (EFLAG) evdwl = rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej];
}
else { // special case
register double f = special_lj[ni];
force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]);
if (EFLAG)
evdwl = f * (rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
}
}
}
else force_lj = evdwl = 0.0;
fpair = (force_coul+force_lj)*r2inv;
if (NEWTON_PAIR || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fpair; fj[2] -= f;
}
else {
fi[0] += d[0]*fpair;
fi[1] += d[1]*fpair;
fi[2] += d[2]*fpair;
}
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,d[0],d[1],d[2],tid);
+ evdwl,ecoul,fpair,d[0],d[1],d[2],thr);
}
}
}
/* ---------------------------------------------------------------------- */
double PairLJCoulOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCoul::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_coul_omp.h b/src/USER-OMP/pair_lj_coul_omp.h
index 619e609ba..e2259e16a 100644
--- a/src/USER-OMP/pair_lj_coul_omp.h
+++ b/src/USER-OMP/pair_lj_coul_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/coul/omp,PairLJCoulOMP)
#else
#ifndef LMP_PAIR_LJ_COUL_OMP_H
#define LMP_PAIR_LJ_COUL_OMP_H
#include "pair_lj_coul.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCoulOMP : public PairLJCoul, public ThrOMP {
public:
PairLJCoulOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cubic_omp.cpp b/src/USER-OMP/pair_lj_cubic_omp.cpp
index 4f806bd71..09e44a910 100644
--- a/src/USER-OMP/pair_lj_cubic_omp.cpp
+++ b/src/USER-OMP/pair_lj_cubic_omp.cpp
@@ -1,173 +1,169 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cubic_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
using namespace PairLJCubicConstants;
/* ---------------------------------------------------------------------- */
PairLJCubicOMP::PairLJCubicOMP(LAMMPS *lmp) :
- PairLJCubic(lmp), ThrOMP(lmp, PAIR)
+ PairLJCubic(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCubicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCubicOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCubicOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
double r,t,rmin;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq <= cut_inner_sq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
} else {
r = sqrt(rsq);
rmin = sigma[itype][jtype]*RT6TWO;
t = (r - cut_inner[itype][jtype])/rmin;
forcelj = epsilon[itype][jtype]*(-DPHIDS + A3*t*t/2.0)*r/rmin;
}
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq <= cut_inner_sq[itype][jtype])
evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
else
evdwl = epsilon[itype][jtype]*
(PHIS + DPHIDS*t - A3*t*t*t/6.0);
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCubicOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCubic::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cubic_omp.h b/src/USER-OMP/pair_lj_cubic_omp.h
index 559a6125a..a6ed7d2b9 100644
--- a/src/USER-OMP/pair_lj_cubic_omp.h
+++ b/src/USER-OMP/pair_lj_cubic_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cubic/omp,PairLJCubicOMP)
#else
#ifndef LMP_PAIR_LJ_CUBIC_OMP_H
#define LMP_PAIR_LJ_CUBIC_OMP_H
#include "pair_lj_cubic.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCubicOMP : public PairLJCubic, public ThrOMP {
public:
PairLJCubicOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
index be98ec38f..46114ce61 100644
--- a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp
@@ -1,183 +1,179 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cut_coul_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJCutCoulCutOMP::PairLJCutCoulCutOMP(LAMMPS *lmp) :
- PairLJCutCoulCut(lmp), ThrOMP(lmp, PAIR)
+ PairLJCutCoulCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutCoulCutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,rinv,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq[itype][jtype]) {
rinv = sqrt(r2inv);
forcecoul = qqrd2e * qtmp*q[j]*rinv;
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype])
ecoul = factor_coul * qqrd2e * qtmp*q[j]*rinv;
else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
- }
- } else evdwl = 0.0;
+ } else evdwl = 0.0;
+ }
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCutCoulCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.h b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h
index c8c34e259..3d4be420e 100644
--- a/src/USER-OMP/pair_lj_cut_coul_cut_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/coul/cut/omp,PairLJCutCoulCutOMP)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H
#define LMP_PAIR_LJ_CUT_COUL_CUT_OMP_H
#include "pair_lj_cut_coul_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCutCoulCutOMP : public PairLJCutCoulCut, public ThrOMP {
public:
PairLJCutCoulCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
index 13a4a1906..9d96f31db 100644
--- a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp
@@ -1,186 +1,182 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cut_coul_debye_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJCutCoulDebyeOMP::PairLJCutCoulDebyeOMP(LAMMPS *lmp) :
- PairLJCutCoulDebye(lmp), ThrOMP(lmp, PAIR)
+ PairLJCutCoulDebye(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulDebyeOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutCoulDebyeOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulDebyeOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double r,rinv,screening;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
-
if (rsq < cut_coulsq[itype][jtype]) {
r = sqrt(rsq);
rinv = 1.0/r;
screening = exp(-kappa*r);
forcecoul = qqrd2e * qtmp*q[j] * screening * (kappa + rinv);
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq[itype][jtype])
ecoul = factor_coul * qqrd2e * qtmp*q[j] * rinv * screening;
else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
+
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCutCoulDebyeOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulDebye::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
index 00cf540be..e2205cb7c 100644
--- a/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/coul/debye/omp,PairLJCutCoulDebyeOMP)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
#define LMP_PAIR_LJ_CUT_COUL_DEBYE_OMP_H
#include "pair_lj_cut_coul_debye.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCutCoulDebyeOMP : public PairLJCutCoulDebye, public ThrOMP {
public:
PairLJCutCoulDebyeOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
index 1d8f977c9..79976bf8a 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
@@ -1,220 +1,216 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cut_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) :
- PairLJCutCoulLong(lmp), ThrOMP(lmp, PAIR)
+ PairLJCutCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulLongOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
-
+
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCutCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_omp.h
index ac408ba88..a907959ae 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
#include "pair_lj_cut_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP {
public:
PairLJCutCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
index 6ada944c5..78f35709a 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
@@ -1,462 +1,458 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cut_coul_long_tip4p_omp.h"
#include "atom.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "error.h"
#include "memory.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
PairLJCutCoulLongTIP4POMP::PairLJCutCoulLongTIP4POMP(LAMMPS *lmp) :
- PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, PAIR)
+ PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
// for caching m-shift corrected positions
maxmpos = 0;
h1idx = h2idx = NULL;
mpos = NULL;
}
/* ---------------------------------------------------------------------- */
PairLJCutCoulLongTIP4POMP::~PairLJCutCoulLongTIP4POMP()
{
memory->destroy(h1idx);
memory->destroy(h2idx);
memory->destroy(mpos);
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nlocal = atom->nlocal;
const int nall = nlocal + atom->nghost;
// reallocate per-atom arrays, if necessary
if (nall > maxmpos) {
maxmpos = nall;
memory->grow(mpos,maxmpos,3,"pair:mpos");
memory->grow(h1idx,maxmpos,"pair:h1idx");
memory->grow(h2idx,maxmpos,"pair:h2idx");
}
// cache corrected M positions in mpos[]
- double **x = atom->x;
- int *type = atom->type;
+ const double * const * const x = atom->x;
+ const int * const type = atom->type;
for (int i = 0; i < nlocal; i++) {
if (type[i] == typeO) {
find_M(i,h1idx[i],h2idx[i],mpos[i]);
} else {
mpos[i][0] = x[i][0];
mpos[i][1] = x[i][1];
mpos[i][2] = x[i][2];
}
}
for (int i = nlocal; i < nall; i++) {
if (type[i] == typeO) {
find_M_permissive(i,h1idx[i],h2idx[i],mpos[i]);
} else {
mpos[i][0] = x[i][0];
mpos[i][1] = x[i][1];
mpos[i][2] = x[i][2];
}
}
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (vflag) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (vflag) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (vflag) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (vflag) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- eval<0,0,0>(f, ifrom, ito, tid);
+ eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int VFLAG>
-void PairLJCutCoulLongTIP4POMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
int n,vlist[6];
int iH1,iH2,jH1,jH2;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
double fraction,table;
double delxOM,delyOM,delzOM;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,cforce;
double factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc,ddotf;
double v[6],xH1[3],xH2[3];
double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz;
double *x1,*x2;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
x1 = mpos[i];
iH1 = h1idx[i];
iH2 = h2idx[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj * r2inv;
fxtmp += delx*forcelj;
fytmp += dely*forcelj;
fztmp += delz*forcelj;
f[j][0] -= delx*forcelj;
f[j][1] -= dely*forcelj;
f[j][2] -= delz*forcelj;
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
- evdwl,0.0,forcelj,delx,dely,delz,tid);
+ evdwl,0.0,forcelj,delx,dely,delz,thr);
}
// adjust rsq and delxyz for off-site O charge(s)
if (itype == typeO || jtype == typeO) {
x2 = mpos[j];
jH1 = h1idx[j];
jH2 = h2idx[j];
if (jtype == typeO && ( jH1 < 0 || jH2 < 0 ))
error->one(FLERR,"TIP4P hydrogen is missing");
delx = x1[0] - x2[0];
dely = x1[1] - x2[1];
delz = x1[2] - x2[2];
rsq = delx*delx + dely*dely + delz*delz;
}
// test current rsq against cutoff and compute Coulombic force
if (rsq < cut_coulsq) {
r2inv = 1 / rsq;
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) {
forcecoul -= (1.0-factor_coul)*prefactor;
}
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
cforce = forcecoul * r2inv;
// if i,j are not O atoms, force is applied directly
// if i or j are O atoms, force is on fictitious atom & partitioned
// force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
// f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
// preserves total force and torque on water molecule
// virial = sum(r x F) where each water's atoms are near xi and xj
// vlist stores 2,4,6 atoms whose forces contribute to virial
n = 0;
if (itype != typeO) {
fxtmp += delx * cforce;
fytmp += dely * cforce;
fztmp += delz * cforce;
if (VFLAG) {
v[0] = x[i][0] * delx * cforce;
v[1] = x[i][1] * dely * cforce;
v[2] = x[i][2] * delz * cforce;
v[3] = x[i][0] * dely * cforce;
v[4] = x[i][0] * delz * cforce;
v[5] = x[i][1] * delz * cforce;
vlist[n++] = i;
}
} else {
fdx = delx*cforce;
fdy = dely*cforce;
fdz = delz*cforce;
delxOM = x[i][0] - x1[0];
delyOM = x[i][1] - x1[1];
delzOM = x[i][2] - x1[2];
ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
(qdist*qdist);
f1x = alpha * (fdx - ddotf * delxOM);
f1y = alpha * (fdy - ddotf * delyOM);
f1z = alpha * (fdz - ddotf * delzOM);
fOx = fdx - f1x;
fOy = fdy - f1y;
fOz = fdz - f1z;
fHx = 0.5 * f1x;
fHy = 0.5 * f1y;
fHz = 0.5 * f1z;
fxtmp += fOx;
fytmp += fOy;
fztmp += fOz;
f[iH1][0] += fHx;
f[iH1][1] += fHy;
f[iH1][2] += fHz;
f[iH2][0] += fHx;
f[iH2][1] += fHy;
f[iH2][2] += fHz;
if (VFLAG) {
domain->closest_image(x[i],x[iH1],xH1);
domain->closest_image(x[i],x[iH2],xH2);
v[0] = x[i][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
v[1] = x[i][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
v[2] = x[i][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
v[3] = x[i][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
v[4] = x[i][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
v[5] = x[i][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
vlist[n++] = i;
vlist[n++] = iH1;
vlist[n++] = iH2;
}
}
if (jtype != typeO) {
f[j][0] -= delx * cforce;
f[j][1] -= dely * cforce;
f[j][2] -= delz * cforce;
if (VFLAG) {
v[0] -= x[j][0] * delx * cforce;
v[1] -= x[j][1] * dely * cforce;
v[2] -= x[j][2] * delz * cforce;
v[3] -= x[j][0] * dely * cforce;
v[4] -= x[j][0] * delz * cforce;
v[5] -= x[j][1] * delz * cforce;
vlist[n++] = j;
}
} else {
fdx = -delx*cforce;
fdy = -dely*cforce;
fdz = -delz*cforce;
delxOM = x[j][0] - x2[0];
delyOM = x[j][1] - x2[1];
delzOM = x[j][2] - x2[2];
ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
(qdist*qdist);
f1x = alpha * (fdx - ddotf * delxOM);
f1y = alpha * (fdy - ddotf * delyOM);
f1z = alpha * (fdz - ddotf * delzOM);
fOx = fdx - f1x;
fOy = fdy - f1y;
fOz = fdz - f1z;
fHx = 0.5 * f1x;
fHy = 0.5 * f1y;
fHz = 0.5 * f1z;
f[j][0] += fOx;
f[j][1] += fOy;
f[j][2] += fOz;
f[jH1][0] += fHx;
f[jH1][1] += fHy;
f[jH1][2] += fHz;
f[jH2][0] += fHx;
f[jH2][1] += fHy;
f[jH2][2] += fHz;
if (VFLAG) {
domain->closest_image(x[j],x[jH1],xH1);
domain->closest_image(x[j],x[jH2],xH2);
v[0] += x[j][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
v[1] += x[j][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
v[2] += x[j][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
v[3] += x[j][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
v[4] += x[j][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
v[5] += x[j][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
vlist[n++] = j;
vlist[n++] = jH1;
vlist[n++] = jH2;
}
}
if (EFLAG) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
- if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,tid);
+ if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,thr);
}
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
void PairLJCutCoulLongTIP4POMP::find_M_permissive(int i, int &iH1, int &iH2, double *xM)
{
// test that O is correctly bonded to 2 succesive H atoms
iH1 = atom->map(atom->tag[i] + 1);
iH2 = atom->map(atom->tag[i] + 2);
if (iH1 == -1 || iH2 == -1)
return;
else
find_M(i,iH1,iH2,xM);
}
/* ---------------------------------------------------------------------- */
double PairLJCutCoulLongTIP4POMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulLongTIP4P::memory_usage();
bytes += 2 * maxmpos * sizeof(int);
bytes += 3 * maxmpos * sizeof(double);
bytes += maxmpos * sizeof(double *);
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
index 093fc0216..ff49bdced 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
@@ -1,57 +1,56 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/coul/long/tip4p/omp,PairLJCutCoulLongTIP4POMP)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
#include "pair_lj_cut_coul_long_tip4p.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCutCoulLongTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
public:
PairLJCutCoulLongTIP4POMP(class LAMMPS *);
virtual ~PairLJCutCoulLongTIP4POMP();
virtual void compute(int, int);
virtual double memory_usage();
protected:
-
// this is to cache m-shift corrected positions.
int maxmpos; // size of the following arrays
int *h1idx, *h2idx; // local index of hydrogen atoms
double **mpos; // coordinates corrected for m-shift.
void find_M_permissive(int, int &, int &, double *);
private:
template <int EVFLAG, int EFLAG, int VFLAG>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_pppm_omp.cpp
similarity index 70%
copy from src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
copy to src/USER-OMP/pair_lj_cut_coul_pppm_omp.cpp
index 1d8f977c9..c048db9d4 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_omp.cpp
@@ -1,220 +1,245 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_lj_cut_coul_long_omp.h"
+#include "pair_lj_cut_coul_pppm_omp.h"
+#include "pppm_proxy.h"
#include "atom.h"
#include "comm.h"
+#include "error.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "update.h"
+
+#include <string.h>
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
-PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) :
- PairLJCutCoulLong(lmp), ThrOMP(lmp, PAIR)
+PairLJCutCoulPPPMOMP::PairLJCutCoulPPPMOMP(LAMMPS *lmp) :
+ PairLJCutCoulLong(lmp), ThrOMP(lmp, THR_PAIR|THR_PROXY)
{
respa_enable = 0;
+ nproxy=1;
+
+ kspace = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulPPPMOMP::init_style()
+{
+ if (comm->nthreads < 2)
+ error->all(FLERR,"need at least two threads per MPI task for this pair style");
+
+ if (strcmp(force->kspace_style,"pppm/proxy") != 0)
+ error->all(FLERR,"kspace style pppm/proxy is required with this pair style");
+
+ kspace = static_cast<PPPMProxy *>(force->kspace);
+
+ PairLJCutCoulLong::init_style();
}
/* ---------------------------------------------------------------------- */
-void PairLJCutCoulLongOMP::compute(int eflag, int vflag)
+void PairLJCutCoulPPPMOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads, nproxy);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
- if (evflag) {
- if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ // thread id 0 runs pppm, the rest the pair style
+ if (tid < nproxy) {
+ if (update->setupflag) kspace->setup_proxy();
+ kspace->compute_proxy(eflag,vflag);
+ } else {
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- } else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
}
-
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+
+ sync_threads();
+ reduce_thr(this, eflag, vflag, thr, nproxy);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
-
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulPPPMOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
} else forcecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
-
+
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-double PairLJCutCoulLongOMP::memory_usage()
+double PairLJCutCoulPPPMOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/pair_lj_cut_coul_pppm_omp.h
similarity index 73%
copy from src/USER-OMP/pair_lj_cut_coul_long_omp.h
copy to src/USER-OMP/pair_lj_cut_coul_pppm_omp.h
index ac408ba88..010b7818b 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_omp.h
@@ -1,48 +1,54 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP)
+PairStyle(lj/cut/coul/pppm/omp,PairLJCutCoulPPPMOMP)
#else
-#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
-#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
+#ifndef LMP_PAIR_LJ_CUT_COUL_PPPM_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_PPPM_OMP_H
#include "pair_lj_cut_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP {
+class PairLJCutCoulPPPMOMP : public PairLJCutCoulLong, public ThrOMP {
public:
- PairLJCutCoulLongOMP(class LAMMPS *);
+ PairLJCutCoulPPPMOMP(class LAMMPS *);
+ virtual ~PairLJCutCoulPPPMOMP() {};
+
+ virtual void init_style();
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
+
+ class PPPMProxy *kspace;
+ int nproxy;
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
similarity index 82%
copy from src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
copy to src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
index 6ada944c5..add0e295e 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
@@ -1,462 +1,487 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_lj_cut_coul_long_tip4p_omp.h"
+#include "pair_lj_cut_coul_pppm_tip4p_omp.h"
+#include "pppm_proxy.h"
#include "atom.h"
-#include "domain.h"
#include "comm.h"
-#include "force.h"
-#include "neighbor.h"
+#include "domain.h"
#include "error.h"
+#include "force.h"
#include "memory.h"
+#include "neighbor.h"
#include "neigh_list.h"
+#include "update.h"
+
+#include <string.h>
using namespace LAMMPS_NS;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
-PairLJCutCoulLongTIP4POMP::PairLJCutCoulLongTIP4POMP(LAMMPS *lmp) :
- PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, PAIR)
+PairLJCutCoulPPPMTIP4POMP::PairLJCutCoulPPPMTIP4POMP(LAMMPS *lmp) :
+ PairLJCutCoulLongTIP4P(lmp), ThrOMP(lmp, THR_PAIR|THR_PROXY)
{
respa_enable = 0;
+ nproxy=1;
+
+ kspace = NULL;
// for caching m-shift corrected positions
maxmpos = 0;
h1idx = h2idx = NULL;
mpos = NULL;
}
/* ---------------------------------------------------------------------- */
-PairLJCutCoulLongTIP4POMP::~PairLJCutCoulLongTIP4POMP()
+PairLJCutCoulPPPMTIP4POMP::~PairLJCutCoulPPPMTIP4POMP()
{
memory->destroy(h1idx);
memory->destroy(h2idx);
memory->destroy(mpos);
}
/* ---------------------------------------------------------------------- */
-void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag)
+void PairLJCutCoulPPPMTIP4POMP::init_style()
+{
+ if (comm->nthreads < 2)
+ error->all(FLERR,"need at least two threads per MPI task for this pair style");
+
+ if (strcmp(force->kspace_style,"pppm/tip4p/proxy") != 0)
+ error->all(FLERR,"kspace style pppm/tip4p/proxy is required with this pair style");
+
+ kspace = static_cast<PPPMProxy *>(force->kspace);
+
+ PairLJCutCoulLongTIP4P::init_style();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJCutCoulPPPMTIP4POMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nlocal = atom->nlocal;
const int nall = nlocal + atom->nghost;
// reallocate per-atom arrays, if necessary
if (nall > maxmpos) {
maxmpos = nall;
memory->grow(mpos,maxmpos,3,"pair:mpos");
memory->grow(h1idx,maxmpos,"pair:h1idx");
memory->grow(h2idx,maxmpos,"pair:h2idx");
}
// cache corrected M positions in mpos[]
- double **x = atom->x;
- int *type = atom->type;
+ const double * const * const x = atom->x;
+ const int * const type = atom->type;
for (int i = 0; i < nlocal; i++) {
if (type[i] == typeO) {
find_M(i,h1idx[i],h2idx[i],mpos[i]);
} else {
mpos[i][0] = x[i][0];
mpos[i][1] = x[i][1];
mpos[i][2] = x[i][2];
}
}
for (int i = nlocal; i < nall; i++) {
if (type[i] == typeO) {
find_M_permissive(i,h1idx[i],h2idx[i],mpos[i]);
} else {
mpos[i][0] = x[i][0];
mpos[i][1] = x[i][1];
mpos[i][2] = x[i][2];
}
}
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads, nproxy);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
- if (evflag) {
- if (eflag) {
- if (vflag) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ // thread id 0 runs pppm, the rest the pair style
+ if (tid < nproxy) {
+ if (update->setupflag) kspace->setup_proxy();
+ kspace->compute_proxy(eflag,vflag);
+ } else {
+ if (evflag) {
+ if (eflag) {
+ if (vflag) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (vflag) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
} else {
- if (vflag) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ eval<0,0,0>(ifrom, ito, thr);
}
- } else {
- eval<0,0,0>(f, ifrom, ito, tid);
}
-
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+
+ sync_threads();
+ reduce_thr(this, eflag, vflag, thr, nproxy);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int VFLAG>
-void PairLJCutCoulLongTIP4POMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
int n,vlist[6];
int iH1,iH2,jH1,jH2;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
double fraction,table;
double delxOM,delyOM,delzOM;
double r,rsq,r2inv,r6inv,forcecoul,forcelj,cforce;
double factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc,ddotf;
double v[6],xH1[3],xH2[3];
double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz;
double *x1,*x2;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
x1 = mpos[i];
iH1 = h1idx[i];
iH2 = h2idx[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= factor_lj * r2inv;
fxtmp += delx*forcelj;
fytmp += dely*forcelj;
fztmp += delz*forcelj;
f[j][0] -= delx*forcelj;
f[j][1] -= dely*forcelj;
f[j][2] -= delz*forcelj;
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
- evdwl,0.0,forcelj,delx,dely,delz,tid);
+ evdwl,0.0,forcelj,delx,dely,delz,thr);
}
// adjust rsq and delxyz for off-site O charge(s)
if (itype == typeO || jtype == typeO) {
x2 = mpos[j];
jH1 = h1idx[j];
jH2 = h2idx[j];
if (jtype == typeO && ( jH1 < 0 || jH2 < 0 ))
error->one(FLERR,"TIP4P hydrogen is missing");
delx = x1[0] - x2[0];
dely = x1[1] - x2[1];
delz = x1[2] - x2[2];
rsq = delx*delx + dely*dely + delz*delz;
}
// test current rsq against cutoff and compute Coulombic force
if (rsq < cut_coulsq) {
r2inv = 1 / rsq;
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) {
forcecoul -= (1.0-factor_coul)*prefactor;
}
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
cforce = forcecoul * r2inv;
// if i,j are not O atoms, force is applied directly
// if i or j are O atoms, force is on fictitious atom & partitioned
// force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
// f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
// preserves total force and torque on water molecule
// virial = sum(r x F) where each water's atoms are near xi and xj
// vlist stores 2,4,6 atoms whose forces contribute to virial
n = 0;
if (itype != typeO) {
fxtmp += delx * cforce;
fytmp += dely * cforce;
fztmp += delz * cforce;
if (VFLAG) {
v[0] = x[i][0] * delx * cforce;
v[1] = x[i][1] * dely * cforce;
v[2] = x[i][2] * delz * cforce;
v[3] = x[i][0] * dely * cforce;
v[4] = x[i][0] * delz * cforce;
v[5] = x[i][1] * delz * cforce;
vlist[n++] = i;
}
} else {
fdx = delx*cforce;
fdy = dely*cforce;
fdz = delz*cforce;
delxOM = x[i][0] - x1[0];
delyOM = x[i][1] - x1[1];
delzOM = x[i][2] - x1[2];
ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
(qdist*qdist);
f1x = alpha * (fdx - ddotf * delxOM);
f1y = alpha * (fdy - ddotf * delyOM);
f1z = alpha * (fdz - ddotf * delzOM);
fOx = fdx - f1x;
fOy = fdy - f1y;
fOz = fdz - f1z;
fHx = 0.5 * f1x;
fHy = 0.5 * f1y;
fHz = 0.5 * f1z;
fxtmp += fOx;
fytmp += fOy;
fztmp += fOz;
f[iH1][0] += fHx;
f[iH1][1] += fHy;
f[iH1][2] += fHz;
f[iH2][0] += fHx;
f[iH2][1] += fHy;
f[iH2][2] += fHz;
if (VFLAG) {
domain->closest_image(x[i],x[iH1],xH1);
domain->closest_image(x[i],x[iH2],xH2);
v[0] = x[i][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
v[1] = x[i][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
v[2] = x[i][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
v[3] = x[i][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
v[4] = x[i][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
v[5] = x[i][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
vlist[n++] = i;
vlist[n++] = iH1;
vlist[n++] = iH2;
}
}
if (jtype != typeO) {
f[j][0] -= delx * cforce;
f[j][1] -= dely * cforce;
f[j][2] -= delz * cforce;
if (VFLAG) {
v[0] -= x[j][0] * delx * cforce;
v[1] -= x[j][1] * dely * cforce;
v[2] -= x[j][2] * delz * cforce;
v[3] -= x[j][0] * dely * cforce;
v[4] -= x[j][0] * delz * cforce;
v[5] -= x[j][1] * delz * cforce;
vlist[n++] = j;
}
} else {
fdx = -delx*cforce;
fdy = -dely*cforce;
fdz = -delz*cforce;
delxOM = x[j][0] - x2[0];
delyOM = x[j][1] - x2[1];
delzOM = x[j][2] - x2[2];
ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
(qdist*qdist);
f1x = alpha * (fdx - ddotf * delxOM);
f1y = alpha * (fdy - ddotf * delyOM);
f1z = alpha * (fdz - ddotf * delzOM);
fOx = fdx - f1x;
fOy = fdy - f1y;
fOz = fdz - f1z;
fHx = 0.5 * f1x;
fHy = 0.5 * f1y;
fHz = 0.5 * f1z;
f[j][0] += fOx;
f[j][1] += fOy;
f[j][2] += fOz;
f[jH1][0] += fHx;
f[jH1][1] += fHy;
f[jH1][2] += fHz;
f[jH2][0] += fHx;
f[jH2][1] += fHy;
f[jH2][2] += fHz;
if (VFLAG) {
domain->closest_image(x[j],x[jH1],xH1);
domain->closest_image(x[j],x[jH2],xH2);
v[0] += x[j][0]*fOx + xH1[0]*fHx + xH2[0]*fHx;
v[1] += x[j][1]*fOy + xH1[1]*fHy + xH2[1]*fHy;
v[2] += x[j][2]*fOz + xH1[2]*fHz + xH2[2]*fHz;
v[3] += x[j][0]*fOy + xH1[0]*fHy + xH2[0]*fHy;
v[4] += x[j][0]*fOz + xH1[0]*fHz + xH2[0]*fHz;
v[5] += x[j][1]*fOz + xH1[1]*fHz + xH2[1]*fHz;
vlist[n++] = j;
vlist[n++] = jH1;
vlist[n++] = jH2;
}
}
if (EFLAG) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
- if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,tid);
+ if (EVFLAG) ev_tally_list_thr(this,n,vlist,ecoul,v,thr);
}
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-void PairLJCutCoulLongTIP4POMP::find_M_permissive(int i, int &iH1, int &iH2, double *xM)
+void PairLJCutCoulPPPMTIP4POMP::find_M_permissive(int i, int &iH1, int &iH2, double *xM)
{
// test that O is correctly bonded to 2 succesive H atoms
iH1 = atom->map(atom->tag[i] + 1);
iH2 = atom->map(atom->tag[i] + 2);
if (iH1 == -1 || iH2 == -1)
return;
else
find_M(i,iH1,iH2,xM);
}
/* ---------------------------------------------------------------------- */
-double PairLJCutCoulLongTIP4POMP::memory_usage()
+double PairLJCutCoulPPPMTIP4POMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCutCoulLongTIP4P::memory_usage();
bytes += 2 * maxmpos * sizeof(int);
bytes += 3 * maxmpos * sizeof(double);
bytes += maxmpos * sizeof(double *);
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
similarity index 73%
copy from src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
copy to src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
index 093fc0216..71da06eb9 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
@@ -1,57 +1,61 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(lj/cut/coul/long/tip4p/omp,PairLJCutCoulLongTIP4POMP)
+PairStyle(lj/cut/coul/pppm/tip4p/omp,PairLJCutCoulPPPMTIP4POMP)
#else
-#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
-#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OMP_H
+#ifndef LMP_PAIR_LJ_CUT_COUL_PPPM_TIP4P_OMP_H
+#define LMP_PAIR_LJ_CUT_COUL_PPPM_TIP4P_OMP_H
#include "pair_lj_cut_coul_long_tip4p.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCutCoulLongTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
+class PairLJCutCoulPPPMTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
public:
- PairLJCutCoulLongTIP4POMP(class LAMMPS *);
- virtual ~PairLJCutCoulLongTIP4POMP();
+ PairLJCutCoulPPPMTIP4POMP(class LAMMPS *);
+ virtual ~PairLJCutCoulPPPMTIP4POMP();
+
+ virtual void init_style();
virtual void compute(int, int);
virtual double memory_usage();
protected:
-
// this is to cache m-shift corrected positions.
int maxmpos; // size of the following arrays
int *h1idx, *h2idx; // local index of hydrogen atoms
double **mpos; // coordinates corrected for m-shift.
void find_M_permissive(int, int &, int &, double *);
private:
- template <int EVFLAG, int EFLAG, int VFLAG>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+ void eval(int ifrom, int ito, ThrData * const thr);
+
+ class PPPMProxy *kspace;
+ int nproxy;
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_omp.cpp
index 3d82149fe..4932a784b 100644
--- a/src/USER-OMP/pair_lj_cut_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_omp.cpp
@@ -1,160 +1,156 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJCutOMP::PairLJCutOMP(LAMMPS *lmp) :
- PairLJCut(lmp), ThrOMP(lmp, PAIR)
+ PairLJCut(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJCutOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])
- offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJCutOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJCut::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_omp.h b/src/USER-OMP/pair_lj_cut_omp.h
index 56f9f9b8a..f97996e48 100644
--- a/src/USER-OMP/pair_lj_cut_omp.h
+++ b/src/USER-OMP/pair_lj_cut_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/omp,PairLJCutOMP)
#else
#ifndef LMP_PAIR_LJ_CUT_OMP_H
#define LMP_PAIR_LJ_CUT_OMP_H
#include "pair_lj_cut.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJCutOMP : public PairLJCut, public ThrOMP {
public:
PairLJCutOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_expand_omp.cpp b/src/USER-OMP/pair_lj_expand_omp.cpp
index 7b06503ee..4f93d3bd4 100644
--- a/src/USER-OMP/pair_lj_expand_omp.cpp
+++ b/src/USER-OMP/pair_lj_expand_omp.cpp
@@ -1,164 +1,160 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_expand_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJExpandOMP::PairLJExpandOMP(LAMMPS *lmp) :
- PairLJExpand(lmp), ThrOMP(lmp, PAIR)
+ PairLJExpand(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJExpandOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJExpandOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJExpandOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
double r,rshift,rshiftsq;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
rshift = r - shift[itype][jtype];
rshiftsq = rshift*rshift;
r2inv = 1.0/rshiftsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj/rshift/r;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype])
- offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJExpandOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJExpand::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_expand_omp.h b/src/USER-OMP/pair_lj_expand_omp.h
index 29488deae..9ff8d3080 100644
--- a/src/USER-OMP/pair_lj_expand_omp.h
+++ b/src/USER-OMP/pair_lj_expand_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/cut/omp,PairLJExpandOMP)
#else
#ifndef LMP_PAIR_LJ_EXPAND_OMP_H
#define LMP_PAIR_LJ_EXPAND_OMP_H
#include "pair_lj_expand.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJExpandOMP : public PairLJExpand, public ThrOMP {
public:
PairLJExpandOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
index 2e97fa1b5..ca8875c7f 100644
--- a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
+++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp
@@ -1,210 +1,206 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_gromacs_coul_gromacs_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJGromacsCoulGromacsOMP::PairLJGromacsCoulGromacsOMP(LAMMPS *lmp) :
- PairLJGromacsCoulGromacs(lmp), ThrOMP(lmp, PAIR)
+ PairLJGromacsCoulGromacs(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJGromacsCoulGromacsOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJGromacsCoulGromacsOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJGromacsCoulGromacsOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double r,tlj,tc,fswitch,fswitchcoul,eswitch,ecoulswitch;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
// skip if qi or qj = 0.0 since this potential may be used as
// coarse-grain model with many uncharged atoms
if (rsq < cut_coulsq && qtmp != 0.0 && q[j] != 0.0) {
forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
if (rsq > cut_coul_innersq) {
r = sqrt(rsq);
tc = r - cut_coul_inner;
fswitchcoul = qqrd2e * qtmp*q[j]*r*tc*tc*(coulsw1 + coulsw2*tc);
forcecoul += fswitchcoul;
}
forcecoul *= factor_coul;
} else forcecoul = 0.0;
if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_lj_innersq) {
r = sqrt(rsq);
tlj = r - cut_lj_inner;
fswitch = r*tlj*tlj*(ljsw1[itype][jtype] +
ljsw2[itype][jtype]*tlj);
forcelj += fswitch;
}
forcelj *= factor_lj;
} else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
ecoul = qqrd2e * qtmp*q[j] * (sqrt(r2inv) - coulsw5);
if (rsq > cut_coul_innersq) {
ecoulswitch = tc*tc*tc * (coulsw3 + coulsw4*tc);
ecoul += qqrd2e*qtmp*q[j]*ecoulswitch;
}
ecoul *= factor_coul;
} else ecoul = 0.0;
if (rsq < cut_ljsq) {
evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
evdwl += ljsw5[itype][jtype];
if (rsq > cut_lj_innersq) {
eswitch = tlj*tlj*tlj *
(ljsw3[itype][jtype] + ljsw4[itype][jtype]*tlj);
evdwl += eswitch;
}
evdwl *= factor_lj;
} else evdwl = 0.0;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJGromacsCoulGromacsOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJGromacsCoulGromacs::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
index d789bd679..ee506c2c4 100644
--- a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
+++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/gromacs/coul/gromacs/omp,PairLJGromacsCoulGromacsOMP)
#else
#ifndef LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H
#define LMP_PAIR_LJ_GROMACS_COUL_GROMACS_OMP_H
#include "pair_lj_gromacs_coul_gromacs.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJGromacsCoulGromacsOMP : public PairLJGromacsCoulGromacs, public ThrOMP {
public:
PairLJGromacsCoulGromacsOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_omp.cpp
index f1c7d2faf..abdc4c5cc 100644
--- a/src/USER-OMP/pair_lj_gromacs_omp.cpp
+++ b/src/USER-OMP/pair_lj_gromacs_omp.cpp
@@ -1,172 +1,168 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_gromacs_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJGromacsOMP::PairLJGromacsOMP(LAMMPS *lmp) :
- PairLJGromacs(lmp), ThrOMP(lmp, PAIR)
+ PairLJGromacs(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJGromacsOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJGromacsOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJGromacsOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
double r,t,fswitch,eswitch;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
if (rsq > cut_inner_sq[itype][jtype]) {
r = sqrt(rsq);
t = r - cut_inner[itype][jtype];
fswitch = r*t*t*(ljsw1[itype][jtype] + ljsw2[itype][jtype]*t);
forcelj += fswitch;
}
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv * (lj3[itype][jtype]*r6inv - lj4[itype][jtype]);
evdwl += ljsw5[itype][jtype];
if (rsq > cut_inner_sq[itype][jtype]) {
eswitch = t*t*t*(ljsw3[itype][jtype] + ljsw4[itype][jtype]*t);
evdwl += eswitch;
}
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJGromacsOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJGromacs::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_gromacs_omp.h b/src/USER-OMP/pair_lj_gromacs_omp.h
index d192a414e..8e0f4bd28 100644
--- a/src/USER-OMP/pair_lj_gromacs_omp.h
+++ b/src/USER-OMP/pair_lj_gromacs_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/gromacs/omp,PairLJGromacsOMP)
#else
#ifndef LMP_PAIR_LJ_GROMACS_OMP_H
#define LMP_PAIR_LJ_GROMACS_OMP_H
#include "pair_lj_gromacs.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJGromacsOMP : public PairLJGromacs, public ThrOMP {
public:
PairLJGromacsOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp
similarity index 61%
copy from src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
copy to src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp
index 1d8f977c9..0e120a863 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp
+++ b/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp
@@ -1,220 +1,248 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
-#include "pair_lj_cut_coul_long_omp.h"
+#include "pair_lj_sdk_coul_long_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "lj_sdk_common.h"
+
using namespace LAMMPS_NS;
+using namespace LJSDKParms;
#define EWALD_F 1.12837917
#define EWALD_P 0.3275911
#define A1 0.254829592
#define A2 -0.284496736
#define A3 1.421413741
#define A4 -1.453152027
#define A5 1.061405429
/* ---------------------------------------------------------------------- */
-PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) :
- PairLJCutCoulLong(lmp), ThrOMP(lmp, PAIR)
+PairLJSDKCoulLongOMP::PairLJSDKCoulLongOMP(LAMMPS *lmp) :
+ PairLJSDKCoulLong(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
-void PairLJCutCoulLongOMP::compute(int eflag, int vflag)
+void PairLJSDKCoulLongOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval_thr<1,1,1>(ifrom, ito, thr);
+ else eval_thr<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval_thr<1,0,1>(ifrom, ito, thr);
+ else eval_thr<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval_thr<0,0,1>(ifrom, ito, thr);
+ else eval_thr<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJCutCoulLongOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJSDKCoulLongOMP::eval_thr(int iifrom, int iito, ThrData * const thr)
{
- int i,j,ii,jj,jnum,itype,jtype,itable;
+ int i,ii,j,jj,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
- double r,rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
+ double r,rsq,r2inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc;
- int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = ecoul = 0.0;
- double **x = atom->x;
- double *q = atom->q;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_coul = force->special_coul;
- double *special_lj = force->special_lj;
- double qqrd2e = force->qqrd2e;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const q = atom->q;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_coul = force->special_coul;
+ const double * const special_lj = force->special_lj;
+ const double qqrd2e = force->qqrd2e;
double fxtmp,fytmp,fztmp;
- ilist = list->ilist;
- numneigh = list->numneigh;
- firstneigh = list->firstneigh;
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
qtmp = q[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
- itype = type[i];
- jlist = firstneigh[i];
- jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) {
r = sqrt(rsq);
grij = g_ewald * r;
expm2 = exp(-grij*grij);
t = 1.0 / (1.0 + EWALD_P*grij);
erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
prefactor = qqrd2e * qtmp*q[j]/r;
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
} else {
union_int_float_t rsq_lookup;
rsq_lookup.f = rsq;
itable = rsq_lookup.i & ncoulmask;
itable >>= ncoulshiftbits;
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
table = ftable[itable] + fraction*dftable[itable];
forcecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) {
table = ctable[itable] + fraction*dctable[itable];
prefactor = qtmp*q[j] * table;
forcecoul -= (1.0-factor_coul)*prefactor;
}
}
- } else forcecoul = 0.0;
+ } else {
+ forcecoul = 0.0;
+ ecoul = 0.0;
+ }
if (rsq < cut_ljsq[itype][jtype]) {
- r6inv = r2inv*r2inv*r2inv;
- forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
- forcelj *= factor_lj;
- } else forcelj = 0.0;
- fpair = (forcecoul + forcelj) * r2inv;
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ }
+ } else {
+ forcelj=0.0;
+ evdwl = 0.0;
+ }
+
+ fpair = (forcecoul + factor_lj*forcelj) * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq)
ecoul = prefactor*erfc;
else {
table = etable[itable] + fraction*detable[itable];
ecoul = qtmp*q[j] * table;
}
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) {
- evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
- offset[itype][jtype];
evdwl *= factor_lj;
} else evdwl = 0.0;
}
-
+
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,ecoul,fpair,delx,dely,delz,tid);
+ evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
-double PairLJCutCoulLongOMP::memory_usage()
+double PairLJSDKCoulLongOMP::memory_usage()
{
double bytes = memory_usage_thr();
- bytes += PairLJCutCoulLong::memory_usage();
+ bytes += PairLJSDKCoulLong::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.h b/src/USER-OMP/pair_lj_sdk_coul_long_omp.h
similarity index 73%
copy from src/USER-OMP/pair_lj_cut_coul_long_omp.h
copy to src/USER-OMP/pair_lj_sdk_coul_long_omp.h
index ac408ba88..01912535b 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_omp.h
+++ b/src/USER-OMP/pair_lj_sdk_coul_long_omp.h
@@ -1,48 +1,49 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(lj/cut/coul/long/omp,PairLJCutCoulLongOMP)
+PairStyle(lj/sdk/coul/long/omp,PairLJSDKCoulLongOMP)
+PairStyle(cg/cmm/coul/long/omp,PairLJSDKCoulLongOMP)
#else
-#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
-#define LMP_PAIR_LJ_CUT_COUL_LONG_OMP_H
+#ifndef LMP_PAIR_LJ_SDK_COUL_LONG_OMP_H
+#define LMP_PAIR_LJ_SDK_COUL_LONG_OMP_H
-#include "pair_lj_cut_coul_long.h"
+#include "pair_lj_sdk_coul_long.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairLJCutCoulLongOMP : public PairLJCutCoulLong, public ThrOMP {
+class PairLJSDKCoulLongOMP : public PairLJSDKCoulLong, public ThrOMP {
public:
- PairLJCutCoulLongOMP(class LAMMPS *);
+ PairLJSDKCoulLongOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval_thr(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_sdk_omp.cpp b/src/USER-OMP/pair_lj_sdk_omp.cpp
new file mode 100644
index 000000000..bc5faafad
--- /dev/null
+++ b/src/USER-OMP/pair_lj_sdk_omp.cpp
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+ This style is a simplified re-implementation of the CG/CMM pair style
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_lj_sdk_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#include "lj_sdk_common.h"
+
+using namespace LAMMPS_NS;
+using namespace LJSDKParms;
+
+/* ---------------------------------------------------------------------- */
+
+PairLJSDKOMP::PairLJSDKOMP(LAMMPS *lmp) :
+ PairLJSDK(lmp), ThrOMP(lmp, THR_PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairLJSDKOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval_thr<1,1,1>(ifrom, ito, thr);
+ else eval_thr<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_pair) eval_thr<1,0,1>(ifrom, ito, thr);
+ else eval_thr<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_pair) eval_thr<0,0,1>(ifrom, ito, thr);
+ else eval_thr<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+/* ---------------------------------------------------------------------- */
+
+template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+void PairLJSDKOMP::eval_thr(int iifrom, int iito, ThrData * const thr)
+{
+ int i,j,ii,jj,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,forcelj,factor_lj;
+
+ evdwl = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
+ double fxtmp,fytmp,fztmp;
+
+ const int * const ilist = list->ilist;
+ const int * const numneigh = list->numneigh;
+ const int * const * const firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp=fytmp=fztmp=0.0;
+
+ const int itype = type[i];
+ const int * const jlist = firstneigh[i];
+ const int jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ factor_lj = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+ const int ljt = lj_type[itype][jtype];
+
+ if (ljt == LJ12_4) {
+ const double r4inv=r2inv*r2inv;
+ forcelj = r4inv*(lj1[itype][jtype]*r4inv*r4inv
+ - lj2[itype][jtype]);
+
+ if (EFLAG)
+ evdwl = r4inv*(lj3[itype][jtype]*r4inv*r4inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ9_6) {
+ const double r3inv = r2inv*sqrt(r2inv);
+ const double r6inv = r3inv*r3inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r3inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r3inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+
+ } else if (ljt == LJ12_6) {
+ const double r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv*(lj1[itype][jtype]*r6inv
+ - lj2[itype][jtype]);
+ if (EFLAG)
+ evdwl = r6inv*(lj3[itype][jtype]*r6inv
+ - lj4[itype][jtype]) - offset[itype][jtype];
+ } else continue;
+
+ fpair = factor_lj*forcelj*r2inv;
+
+ fxtmp += delx*fpair;
+ fytmp += dely*fpair;
+ fztmp += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (EFLAG) evdwl *= factor_lj;
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+ }
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairLJSDKOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairLJSDK::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_lj_sdk_omp.h
similarity index 78%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/pair_lj_sdk_omp.h
index b24de4a57..f2c9e5ff1 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_lj_sdk_omp.h
@@ -1,48 +1,49 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(born/omp,PairBornOMP)
+PairStyle(lj/sdk/omp,PairLJSDKOMP)
+PairStyle(cg/cmm/omp,PairLJSDKOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_PAIR_LJ_SDK_OMP_H
+#define LMP_PAIR_LJ_SDK_OMP_H
-#include "pair_born.h"
+#include "pair_lj_sdk.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class PairLJSDKOMP : public PairLJSDK, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ PairLJSDKOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval_thr(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_sf_omp.cpp b/src/USER-OMP/pair_lj_sf_omp.cpp
index 55ee908e4..47cc23bf9 100644
--- a/src/USER-OMP/pair_lj_sf_omp.cpp
+++ b/src/USER-OMP/pair_lj_sf_omp.cpp
@@ -1,163 +1,159 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_sf_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJShiftedForceOMP::PairLJShiftedForceOMP(LAMMPS *lmp) :
- PairLJShiftedForce(lmp), ThrOMP(lmp, PAIR)
+ PairLJShiftedForce(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJShiftedForceOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJShiftedForceOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJShiftedForceOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double t,rsq,r2inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
t = sqrt(r2inv*cutsq[itype][jtype]);
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) -
t*foffset[itype][jtype];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) +
(t-1.0)*foffset[itype][jtype] - offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJShiftedForceOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJShiftedForce::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_sf_omp.h b/src/USER-OMP/pair_lj_sf_omp.h
index 6fba43fb8..c73c8f746 100644
--- a/src/USER-OMP/pair_lj_sf_omp.h
+++ b/src/USER-OMP/pair_lj_sf_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/sf/omp,PairLJShiftedForceOMP)
#else
#ifndef LMP_PAIR_LJ_SF_OMP_H
#define LMP_PAIR_LJ_SF_OMP_H
#include "pair_lj_sf.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJShiftedForceOMP : public PairLJShiftedForce, public ThrOMP {
public:
PairLJShiftedForceOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_lj_smooth_omp.cpp b/src/USER-OMP/pair_lj_smooth_omp.cpp
index 1ad88044a..4bf9ceb41 100644
--- a/src/USER-OMP/pair_lj_smooth_omp.cpp
+++ b/src/USER-OMP/pair_lj_smooth_omp.cpp
@@ -1,176 +1,172 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_lj_smooth_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairLJSmoothOMP::PairLJSmoothOMP(LAMMPS *lmp) :
- PairLJSmooth(lmp), ThrOMP(lmp, PAIR)
+ PairLJSmooth(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairLJSmoothOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairLJSmoothOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairLJSmoothOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
double r,t,tsq,fskin;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
if (rsq < cut_inner_sq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv-lj2[itype][jtype]);
} else {
r = sqrt(rsq);
t = r - cut_inner[itype][jtype];
tsq = t*t;
fskin = ljsw1[itype][jtype] + ljsw2[itype][jtype]*t +
ljsw3[itype][jtype]*tsq + ljsw4[itype][jtype]*tsq*t;
forcelj = fskin*r;
}
fpair = factor_lj*forcelj*r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (rsq < cut_inner_sq[itype][jtype])
evdwl = r6inv * (lj3[itype][jtype]*r6inv -
lj4[itype][jtype]) - offset[itype][jtype];
else
evdwl = ljsw0[itype][jtype] - ljsw1[itype][jtype]*t -
ljsw2[itype][jtype]*tsq/2.0 - ljsw3[itype][jtype]*tsq*t/3.0 -
ljsw4[itype][jtype]*tsq*tsq/4.0 - offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairLJSmoothOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairLJSmooth::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_lj_smooth_omp.h b/src/USER-OMP/pair_lj_smooth_omp.h
index de27a4008..eb6eb92de 100644
--- a/src/USER-OMP/pair_lj_smooth_omp.h
+++ b/src/USER-OMP/pair_lj_smooth_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lj/smooth/omp,PairLJSmoothOMP)
#else
#ifndef LMP_PAIR_LJ_SMOOTH_OMP_H
#define LMP_PAIR_LJ_SMOOTH_OMP_H
#include "pair_lj_smooth.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairLJSmoothOMP : public PairLJSmooth, public ThrOMP {
public:
PairLJSmoothOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_morse_omp.cpp b/src/USER-OMP/pair_morse_omp.cpp
index a53e35a97..f61fd4e38 100644
--- a/src/USER-OMP/pair_morse_omp.cpp
+++ b/src/USER-OMP/pair_morse_omp.cpp
@@ -1,160 +1,156 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_morse_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairMorseOMP::PairMorseOMP(LAMMPS *lmp) :
- PairMorse(lmp), ThrOMP(lmp, PAIR)
+ PairMorse(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairMorseOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairMorseOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairMorseOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,dr,dexp,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
dr = r - r0[itype][jtype];
dexp = exp(-alpha[itype][jtype] * dr);
fpair = factor_lj * morse1[itype][jtype] * (dexp*dexp - dexp) / r;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = d0[itype][jtype] * (dexp*dexp - 2.0*dexp) -
offset[itype][jtype];
evdwl *= factor_lj;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairMorseOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairMorse::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_morse_omp.h b/src/USER-OMP/pair_morse_omp.h
index a966e6f11..a20aad671 100644
--- a/src/USER-OMP/pair_morse_omp.h
+++ b/src/USER-OMP/pair_morse_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(morse/omp,PairMorseOMP)
#else
#ifndef LMP_PAIR_MORSE_OMP_H
#define LMP_PAIR_MORSE_OMP_H
#include "pair_morse.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairMorseOMP : public PairMorse, public ThrOMP {
public:
PairMorseOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_peri_lps_omp.cpp b/src/USER-OMP/pair_peri_lps_omp.cpp
index 7cb1e8308..a4479180b 100644
--- a/src/USER-OMP/pair_peri_lps_omp.cpp
+++ b/src/USER-OMP/pair_peri_lps_omp.cpp
@@ -1,456 +1,452 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "float.h"
#include "pair_peri_lps_omp.h"
#include "fix.h"
#include "fix_peri_neigh.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "memory.h"
#include "lattice.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
+#include "math_const.h"
using namespace LAMMPS_NS;
+using namespace MathConst;
/* ---------------------------------------------------------------------- */
PairPeriLPSOMP::PairPeriLPSOMP(LAMMPS *lmp) :
- PairPeriLPS(lmp), ThrOMP(lmp, PAIR)
+ PairPeriLPS(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairPeriLPSOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow bond forces array if necessary
if (atom->nmax > nmax) {
memory->destroy(s0_new);
memory->destroy(theta);
nmax = atom->nmax;
memory->create(s0_new,nmax,"pair:s0_new");
memory->create(theta,nmax,"pair:theta");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairPeriLPSOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairPeriLPSOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0;
double rsq,r,dr,rk,evdwl,fpair,fbond;
int *ilist,*jlist,*numneigh,**firstneigh;
double d_ij,delta,stretch;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double *vfrac = atom->vfrac;
double *s0 = atom->s0;
double **x0 = atom->x0;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
// lc = lattice constant
// init_style guarantees it's the same in x, y, and z
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double vfrac_scale = 1.0;
// short-range forces
int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic);
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
// need minimg() for x0 difference since not ghosted
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
-
+
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
jtype = type[j];
r = sqrt(rsq);
// short-range interaction distance based on initial particle position
// 0.9 and 1.35 are constants
d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
// short-range contact forces
// 15 is constant taken from the EMU Theory Manual
// Silling, 12 May 2005, p 18
if (r < d_ij) {
dr = r - d_ij;
// kshort based upon short-range force constant
// of the bond-based theory used in PMB model
double kshort = (15.0 * 18.0 * bulkmodulus[itype][itype]) /
- (3.141592653589793 * cutsq[itype][jtype] * cutsq[itype][jtype]);
+ (MY_PI * cutsq[itype][jtype] * cutsq[itype][jtype]);
rk = (kshort * vfrac[j]) * (dr / cut[itype][jtype]);
if (r > 0.0) fpair = -(rk/r);
else fpair = 0.0;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) evdwl = 0.5*rk*dr;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
- fpair*vfrac[i],delx,dely,delz,tid);
+ fpair*vfrac[i],delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
// wait until all threads are done since we
// need to distribute the work differently.
sync_threads();
#if defined(_OPENMP)
// each thread works on a fixed chunk of atoms.
const int idelta = 1 + nlocal/comm->nthreads;
- iifrom = tid*idelta;
+ iifrom = thr->get_tid()*idelta;
iito = iifrom + idelta;
if (iito > nlocal)
iito = nlocal;
#else
iifrom = 0;
iito = nlocal;
#endif
// Compute the dilatation on each particle
compute_dilatation_thr(iifrom, iito);
// wait until all threads are done before communication
sync_threads();
#if defined(_OPENMP)
#pragma omp master
#endif
{ // communicate dilatation (theta) of each particle
comm->forward_comm_pair(this);
- // communicate wighted volume (wvolume) upon every reneighbor
+ // communicate weighted volume (wvolume) upon every reneighbor
if (neighbor->ago == 0)
comm->forward_comm_fix(modify->fix[ifix_peri]);
}
sync_threads();
// Volume-dependent part of the energy
if (EFLAG) {
for (i = iifrom; i < iito; i++) {
itype = type[i];
- if (eflag_global)
- eng_vdwl_thr[tid] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
- if (eflag_atom)
- eatom_thr[tid][i] += 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]);
+ e_tally_thr(this, i, i, nlocal, NEWTON_PAIR,
+ 0.5 * bulkmodulus[itype][itype] * (theta[i] * theta[i]), 0.0, thr);
}
}
// loop over my particles and their partners
// partner list contains all bond partners, so I-J appears twice
// if bond already broken, skip this partner
// first = true if this is first neighbor of particle i
bool first;
double omega_minus, omega_plus;
for (i = iifrom; i < iito; ++i) {
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
itype = type[i];
jnum = npartner[i];
first = true;
for (jj = 0; jj < jnum; jj++) {
if (partner[i][jj] == 0) continue;
j = atom->map(partner[i][jj]);
// check if lost a partner without first breaking bond
if (j < 0) {
partner[i][jj] = 0;
continue;
}
// compute force density, add to PD equation of motion
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
if (periodic) domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
jtype = type[j];
delta = cut[itype][jtype];
r = sqrt(rsq);
dr = r - r0[i][jj];
// avoid roundoff errors
if (fabs(dr) < 2.2204e-016) dr = 0.0;
// scale vfrac[j] if particle j near the horizon
if ((fabs(r0[i][jj] - delta)) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((delta - half_lc)/(2*half_lc) ) );
else vfrac_scale = 1.0;
omega_plus = influence_function(-1.0*delx0,-1.0*dely0,-1.0*delz0);
omega_minus = influence_function(delx0,dely0,delz0);
rk = ( (3.0 * bulkmodulus[itype][itype]) -
(5.0 * shearmodulus[itype][itype]) ) * vfrac[j] * vfrac_scale *
( (omega_plus * theta[i] / wvolume[i]) +
( omega_minus * theta[j] / wvolume[j] ) ) * r0[i][jj];
rk += 15.0 * ( shearmodulus[itype][itype] * vfrac[j] * vfrac_scale ) *
( (omega_plus / wvolume[i]) + (omega_minus / wvolume[j]) ) * dr;
if (r > 0.0) fbond = -(rk/r);
else fbond = 0.0;
f[i][0] += delx*fbond;
f[i][1] += dely*fbond;
f[i][2] += delz*fbond;
// since I-J is double counted, set newton off & use 1/2 factor and I,I
double deviatoric_extension = dr - (theta[i]* r0[i][jj] / 3.0);
if (EFLAG) evdwl = 0.5 * 15 * (shearmodulus[itype][itype]/wvolume[i]) *
omega_plus*(deviatoric_extension * deviatoric_extension) *
vfrac[j] * vfrac_scale;
if (EVFLAG) ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0,
- 0.5*fbond*vfrac[i],delx,dely,delz,tid);
+ 0.5*fbond*vfrac[i],delx,dely,delz,thr);
// find stretch in bond I-J and break if necessary
// use s0 from previous timestep
stretch = dr / r0[i][jj];
if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0;
// update s0 for next timestep
if (first)
s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch);
else
s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch));
first = false;
}
}
sync_threads();
// store new s0 (in parallel)
for (i = iifrom; i < iito; i++) s0[i] = s0_new[i];
}
/* ---------------------------------------------------------------------- */
void PairPeriLPSOMP::compute_dilatation_thr(int ifrom, int ito)
{
int i,j,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0;
double rsq,r,dr;
double delta;
double **x = atom->x;
int *type = atom->type;
double **x0 = atom->x0;
double *vfrac = atom->vfrac;
double vfrac_scale = 1.0;
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
int periodic = domain->xperiodic || domain->yperiodic || domain->zperiodic;
// compute the dilatation theta
for (i = ifrom; i < ito; i++) {
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
jnum = npartner[i];
theta[i] = 0.0;
itype = type[i];
for (jj = 0; jj < jnum; jj++) {
// if bond already broken, skip this partner
if (partner[i][jj] == 0) continue;
// Look up local index of this partner particle
j = atom->map(partner[i][jj]);
// Skip if particle is "lost"
if (j < 0) continue;
// Compute force density and add to PD equation of motion
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
if (periodic) domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
r = sqrt(rsq);
dr = r - r0[i][jj];
if (fabs(dr) < 2.2204e-016) dr = 0.0;
jtype = type[j];
delta = cut[itype][jtype];
// scale vfrac[j] if particle j near the horizon
if ((fabs(r0[i][jj] - delta)) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((delta - half_lc)/(2*half_lc) ) );
else vfrac_scale = 1.0;
theta[i] += influence_function(delx0, dely0, delz0) * r0[i][jj] * dr *
vfrac[j] * vfrac_scale;
}
// if wvolume[i] is zero, then particle i has no bonds
// therefore, the dilatation is set to
if (wvolume[i] != 0.0) theta[i] = (3.0/wvolume[i]) * theta[i];
else theta[i] = 0;
}
}
/* ---------------------------------------------------------------------- */
double PairPeriLPSOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairPeriLPS::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_peri_lps_omp.h b/src/USER-OMP/pair_peri_lps_omp.h
index 2068830ca..f234a4109 100644
--- a/src/USER-OMP/pair_peri_lps_omp.h
+++ b/src/USER-OMP/pair_peri_lps_omp.h
@@ -1,52 +1,52 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(peri/lps/omp,PairPeriLPSOMP)
#else
#ifndef LMP_PAIR_PERI_LPS_OMP_H
#define LMP_PAIR_PERI_LPS_OMP_H
#include "pair_peri_lps.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairPeriLPSOMP : public PairPeriLPS, public ThrOMP {
public:
PairPeriLPSOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
protected:
void compute_dilatation_thr(int ifrom, int ito);
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_peri_pmb_omp.cpp b/src/USER-OMP/pair_peri_pmb_omp.cpp
index 4e46d142d..de6387ae6 100644
--- a/src/USER-OMP/pair_peri_pmb_omp.cpp
+++ b/src/USER-OMP/pair_peri_pmb_omp.cpp
@@ -1,312 +1,310 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "float.h"
#include "pair_peri_pmb_omp.h"
#include "fix.h"
#include "fix_peri_neigh.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "memory.h"
#include "lattice.h"
#include "modify.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairPeriPMBOMP::PairPeriPMBOMP(LAMMPS *lmp) :
- PairPeriPMB(lmp), ThrOMP(lmp, PAIR)
+ PairPeriPMB(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairPeriPMBOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
// grow bond forces array if necessary
if (atom->nmax > nmax) {
memory->destroy(s0_new);
nmax = atom->nmax;
memory->create(s0_new,nmax,"pair:s0_new");
}
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairPeriPMBOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairPeriPMBOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double xtmp0,ytmp0,ztmp0,delx0,dely0,delz0,rsq0;
double rsq,r,dr,rk,evdwl,fpair,fbond;
int *ilist,*jlist,*numneigh,**firstneigh;
double d_ij,delta,stretch;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
double fxtmp,fytmp,fztmp;
double *vfrac = atom->vfrac;
double *s0 = atom->s0;
double **x0 = atom->x0;
double **r0 = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
// lc = lattice constant
// init_style guarantees it's the same in x, y, and z
double lc = domain->lattice->xlattice;
double half_lc = 0.5*lc;
double vfrac_scale = 1.0;
// short-range forces
int periodic = (domain->xperiodic || domain->yperiodic || domain->zperiodic);
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
// need minimg() for x0 difference since not ghosted
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
xtmp0 = x0[i][0];
ytmp0 = x0[i][1];
ztmp0 = x0[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
-
+
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
+
rsq = delx*delx + dely*dely + delz*delz;
delx0 = xtmp0 - x0[j][0];
dely0 = ytmp0 - x0[j][1];
delz0 = ztmp0 - x0[j][2];
if (periodic) domain->minimum_image(delx0,dely0,delz0);
rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
jtype = type[j];
r = sqrt(rsq);
// short-range interaction distance based on initial particle position
// 0.9 and 1.35 are constants
d_ij = MIN(0.9*sqrt(rsq0),1.35*lc);
// short-range contact forces
// 15 is constant taken from the EMU Theory Manual
// Silling, 12 May 2005, p 18
if (r < d_ij) {
dr = r - d_ij;
rk = (15.0 * kspring[itype][jtype] * vfrac[j]) *
(dr / cut[itype][jtype]);
if (r > 0.0) fpair = -(rk/r);
else fpair = 0.0;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) evdwl = 0.5*rk*dr;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,evdwl,0.0,
- fpair*vfrac[i],delx,dely,delz,tid);
+ fpair*vfrac[i],delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
// wait until all threads are done since we
// need to distribute the work differently.
sync_threads();
#if defined(_OPENMP)
// each thread works on a fixed chunk of atoms.
const int idelta = 1 + nlocal/comm->nthreads;
- iifrom = tid*idelta;
+ iifrom = thr->get_tid()*idelta;
iito = iifrom + idelta;
if (iito > nlocal)
iito = nlocal;
#else
iifrom = 0;
iito = nlocal;
#endif
// loop over my particles and their partners
// partner list contains all bond partners, so I-J appears twice
// if bond already broken, skip this partner
// first = true if this is first neighbor of particle i
bool first;
for (i = iifrom; i < iito; ++i) {
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jnum = npartner[i];
s0_new[i] = DBL_MAX;
first = true;
for (jj = 0; jj < jnum; jj++) {
if (partner[i][jj] == 0) continue;
j = atom->map(partner[i][jj]);
// check if lost a partner without first breaking bond
if (j < 0) {
partner[i][jj] = 0;
continue;
}
// compute force density, add to PD equation of motion
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
if (periodic) domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
delta = cut[itype][jtype];
r = sqrt(rsq);
dr = r - r0[i][jj];
// avoid roundoff errors
if (fabs(dr) < 2.2204e-016) dr = 0.0;
// scale vfrac[j] if particle j near the horizon
if ((fabs(r0[i][jj] - delta)) <= half_lc)
vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
(1.0 + ((delta - half_lc)/(2*half_lc) ) );
else vfrac_scale = 1.0;
stretch = dr / r0[i][jj];
rk = (kspring[itype][jtype] * vfrac[j]) * vfrac_scale * stretch;
if (r > 0.0) fbond = -(rk/r);
else fbond = 0.0;
f[i][0] += delx*fbond;
f[i][1] += dely*fbond;
f[i][2] += delz*fbond;
// since I-J is double counted, set newton off & use 1/2 factor and I,I
if (EFLAG) evdwl = 0.5*rk*dr;
if (EVFLAG)
ev_tally_thr(this,i,i,nlocal,0,0.5*evdwl,0.0,
- 0.5*fbond*vfrac[i],delx,dely,delz,tid);
+ 0.5*fbond*vfrac[i],delx,dely,delz,thr);
// find stretch in bond I-J and break if necessary
// use s0 from previous timestep
if (stretch > MIN(s0[i],s0[j])) partner[i][jj] = 0;
// update s0 for next timestep
if (first)
s0_new[i] = s00[itype][jtype] - (alpha[itype][jtype] * stretch);
else
s0_new[i] = MAX(s0_new[i],s00[itype][jtype] - (alpha[itype][jtype] * stretch));
+
first = false;
}
}
sync_threads();
- // store new s0
+ // store new s0 (in parallel)
for (i = iifrom; i < iito; i++) s0[i] = s0_new[i];
}
/* ---------------------------------------------------------------------- */
double PairPeriPMBOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairPeriPMB::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_peri_pmb_omp.h b/src/USER-OMP/pair_peri_pmb_omp.h
index 9940e5ed1..8a7fc091d 100644
--- a/src/USER-OMP/pair_peri_pmb_omp.h
+++ b/src/USER-OMP/pair_peri_pmb_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(peri/pmb/omp,PairPeriPMBOMP)
#else
#ifndef LMP_PAIR_PERI_PMB_OMP_H
#define LMP_PAIR_PERI_PMB_OMP_H
#include "pair_peri_pmb.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairPeriPMBOMP : public PairPeriPMB, public ThrOMP {
public:
PairPeriPMBOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/main.cpp b/src/USER-OMP/pair_rebo_omp.cpp
similarity index 69%
copy from src/main.cpp
copy to src/USER-OMP/pair_rebo_omp.cpp
index a3764872e..70b5c4e8a 100644
--- a/src/main.cpp
+++ b/src/USER-OMP/pair_rebo_omp.cpp
@@ -1,33 +1,33 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
-#include "lammps.h"
-#include "input.h"
+#include "pair_rebo_omp.h"
+#include "error.h"
using namespace LAMMPS_NS;
+/* ---------------------------------------------------------------------- */
+
+PairREBOOMP::PairREBOOMP(LAMMPS *lmp) : PairAIREBOOMP(lmp) {}
+
/* ----------------------------------------------------------------------
- main program to drive LAMMPS
+ global settings
------------------------------------------------------------------------- */
-int main(int argc, char **argv)
+void PairREBOOMP::settings(int narg, char **arg)
{
- MPI_Init(&argc,&argv);
-
- LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD);
- lammps->input->file();
- delete lammps;
+ if (narg != 0) error->all(FLERR,"Illegal pair_style command");
- MPI_Finalize();
+ cutlj = 0.0;
+ ljflag = torflag = 0;
}
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/USER-OMP/pair_rebo_omp.h
similarity index 73%
copy from src/GRANULAR/pair_gran_hooke.h
copy to src/USER-OMP/pair_rebo_omp.h
index d5cff796f..4606e56ae 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/USER-OMP/pair_rebo_omp.h
@@ -1,36 +1,36 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(gran/hooke,PairGranHooke)
+PairStyle(rebo/omp,PairREBOOMP)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_H
-#define LMP_PAIR_GRAN_HOOKE_H
+#ifndef LMP_PAIR_REBO_OMP_H
+#define LMP_PAIR_REBO_OMP_H
-#include "pair_gran_hooke_history.h"
+#include "pair_airebo_omp.h"
namespace LAMMPS_NS {
-class PairGranHooke : public PairGranHookeHistory {
+class PairREBOOMP : public PairAIREBOOMP {
public:
- PairGranHooke(class LAMMPS *);
- virtual void compute(int, int);
+ PairREBOOMP(class LAMMPS *);
+ virtual void settings(int, char **);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_resquared_omp.cpp b/src/USER-OMP/pair_resquared_omp.cpp
index 487055305..cef5aaefc 100644
--- a/src/USER-OMP/pair_resquared_omp.cpp
+++ b/src/USER-OMP/pair_resquared_omp.cpp
@@ -1,210 +1,213 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_resquared_omp.h"
#include "math_extra.h"
#include "atom.h"
#include "comm.h"
#include "atom_vec_ellipsoid.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairRESquaredOMP::PairRESquaredOMP(LAMMPS *lmp) :
- PairRESquared(lmp), ThrOMP(lmp, PAIR)
+ PairRESquared(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairRESquaredOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f, **torque;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
- torque = atom->torque + tid*nall;
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, torque, ifrom, ito, tid);
- else eval<1,1,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, torque, ifrom, ito, tid);
- else eval<1,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, torque, ifrom, ito, tid);
- else eval<0,0,0>(f, torque, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces and torques into global arrays.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
- data_reduce_thr(&(atom->torque[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairRESquaredOMP::eval(double **f, double **tor, int iifrom, int iito, int tid)
+void PairRESquaredOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
double fforce[3],ttor[3],rtor[3],r12[3];
int *ilist,*jlist,*numneigh,**firstneigh;
RE2Vars wi,wj;
- double **x = atom->x;
- int *ellipsoid = atom->ellipsoid;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const tor = thr->get_torque();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp,t1tmp,t2tmp,t3tmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itype = type[i];
+ fxtmp=fytmp=fztmp=t1tmp=t2tmp=t3tmp=0.0;
// not a LJ sphere
if (lshape[itype] != 0.0) precompute_i(i,wi);
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
// r12 = center to center vector
r12[0] = x[j][0]-x[i][0];
r12[1] = x[j][1]-x[i][1];
r12[2] = x[j][2]-x[i][2];
rsq = MathExtra::dot3(r12,r12);
jtype = type[j];
// compute if less than cutoff
if (rsq < cutsq[itype][jtype]) {
+ fforce[0] = fforce[1] = fforce[2] = 0.0;
+
switch (form[itype][jtype]) {
case SPHERE_SPHERE:
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
forcelj *= -r2inv;
if (EFLAG) one_eng =
r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
offset[itype][jtype];
fforce[0] = r12[0]*forcelj;
fforce[1] = r12[1]*forcelj;
fforce[2] = r12[2]*forcelj;
break;
case SPHERE_ELLIPSE:
precompute_i(j,wj);
if (NEWTON_PAIR || j < nlocal) {
one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,true);
tor[j][0] += rtor[0]*factor_lj;
tor[j][1] += rtor[1]*factor_lj;
tor[j][2] += rtor[2]*factor_lj;
} else
one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,false);
break;
case ELLIPSE_SPHERE:
one_eng = resquared_lj(i,j,wi,r12,rsq,fforce,ttor,true);
- tor[i][0] += ttor[0]*factor_lj;
- tor[i][1] += ttor[1]*factor_lj;
- tor[i][2] += ttor[2]*factor_lj;
+ t1tmp += ttor[0]*factor_lj;
+ t2tmp += ttor[1]*factor_lj;
+ t3tmp += ttor[2]*factor_lj;
break;
default:
precompute_i(j,wj);
one_eng = resquared_analytic(i,j,wi,wj,r12,rsq,fforce,ttor,rtor);
- tor[i][0] += ttor[0]*factor_lj;
- tor[i][1] += ttor[1]*factor_lj;
- tor[i][2] += ttor[2]*factor_lj;
+ t1tmp += ttor[0]*factor_lj;
+ t2tmp += ttor[1]*factor_lj;
+ t3tmp += ttor[2]*factor_lj;
if (NEWTON_PAIR || j < nlocal) {
tor[j][0] += rtor[0]*factor_lj;
tor[j][1] += rtor[1]*factor_lj;
tor[j][2] += rtor[2]*factor_lj;
}
break;
}
fforce[0] *= factor_lj;
fforce[1] *= factor_lj;
fforce[2] *= factor_lj;
- f[i][0] += fforce[0];
- f[i][1] += fforce[1];
- f[i][2] += fforce[2];
+ fxtmp += fforce[0];
+ fytmp += fforce[1];
+ fztmp += fforce[2];
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= fforce[0];
f[j][1] -= fforce[1];
f[j][2] -= fforce[2];
}
if (EFLAG) evdwl = factor_lj*one_eng;
if (EVFLAG) ev_tally_xyz_thr(this,i,j,nlocal,NEWTON_PAIR,
evdwl,0.0,fforce[0],fforce[1],fforce[2],
- -r12[0],-r12[1],-r12[2],tid);
+ -r12[0],-r12[1],-r12[2],thr);
}
}
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ tor[i][0] += t1tmp;
+ tor[i][1] += t2tmp;
+ tor[i][2] += t3tmp;
}
}
/* ---------------------------------------------------------------------- */
double PairRESquaredOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairRESquared::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_resquared_omp.h b/src/USER-OMP/pair_resquared_omp.h
index 2a50bb6dd..53a6e2e28 100644
--- a/src/USER-OMP/pair_resquared_omp.h
+++ b/src/USER-OMP/pair_resquared_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(resquared/omp,PairRESquaredOMP)
#else
#ifndef LMP_PAIR_RESQUARED_OMP_H
#define LMP_PAIR_RESQUARED_OMP_H
#include "pair_resquared.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairRESquaredOMP : public PairRESquared, public ThrOMP {
public:
PairRESquaredOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, double **torque, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp
index 9f9673a28..cbc1c9f7f 100644
--- a/src/USER-OMP/pair_soft_omp.cpp
+++ b/src/USER-OMP/pair_soft_omp.cpp
@@ -1,162 +1,158 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_soft_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 1.0e-4
/* ---------------------------------------------------------------------- */
PairSoftOMP::PairSoftOMP(LAMMPS *lmp) :
- PairSoft(lmp), ThrOMP(lmp, PAIR)
+ PairSoft(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairSoftOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairSoftOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairSoftOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double r,rsq,arg,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
arg = MY_PI/cut[itype][jtype];
if (r > SMALL) fpair = factor_lj * prefactor[itype][jtype] *
sin(arg*r) * arg/r;
else fpair = 0.0;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG)
evdwl = factor_lj * prefactor[itype][jtype] * (1.0+cos(arg*r));
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairSoftOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairSoft::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_soft_omp.h b/src/USER-OMP/pair_soft_omp.h
index 840d87460..169808952 100644
--- a/src/USER-OMP/pair_soft_omp.h
+++ b/src/USER-OMP/pair_soft_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(soft/omp,PairSoftOMP)
#else
#ifndef LMP_PAIR_SOFT_OMP_H
#define LMP_PAIR_SOFT_OMP_H
#include "pair_soft.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairSoftOMP : public PairSoft, public ThrOMP {
public:
PairSoftOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_sw_omp.cpp b/src/USER-OMP/pair_sw_omp.cpp
index 5d7f1a60d..12aceed1d 100644
--- a/src/USER-OMP/pair_sw_omp.cpp
+++ b/src/USER-OMP/pair_sw_omp.cpp
@@ -1,212 +1,208 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_sw_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairSWOMP::PairSWOMP(LAMMPS *lmp) :
- PairSW(lmp), ThrOMP(lmp, PAIR)
+ PairSW(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairSWOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- eval<1,1>(f, ifrom, ito, tid);
+ eval<1,1>(ifrom, ito, thr);
} else {
- eval<1,0>(f, ifrom, ito, tid);
+ eval<1,0>(ifrom, ito, thr);
}
- } else eval<0,0>(f, ifrom, ito, tid);
+ } else eval<0,0>(ifrom, ito, thr);
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG>
-void PairSWOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairSWOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,k,ii,jj,kk,jnum,jnumm1,itag,jtag;
int itype,jtype,ktype,ijparam,ikparam,ijkparam;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rsq1,rsq2;
double delr1[3],delr2[3],fj[3],fk[3];
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *tag = atom->tag;
- int *type = atom->type;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const tag = atom->tag;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
double fxtmp,fytmp,fztmp;
- // loop over neighbors of my atoms
+ // loop over full neighbor list of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
fxtmp = fytmp = fztmp = 0.0;
// two-body interactions, skip half of them
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
ijparam = elem2param[itype][jtype][jtype];
if (rsq > params[ijparam].cutsq) continue;
twobody(&params[ijparam],rsq,fpair,EFLAG,evdwl);
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
jnumm1 = jnum - 1;
for (jj = 0; jj < jnumm1; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
ijparam = elem2param[itype][jtype][jtype];
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
if (rsq1 > params[ijparam].cutsq) continue;
double fjxtmp,fjytmp,fjztmp;
fjxtmp = fjytmp = fjztmp = 0.0;
for (kk = jj+1; kk < jnum; kk++) {
k = jlist[kk];
k &= NEIGHMASK;
ktype = map[type[k]];
ikparam = elem2param[itype][ktype][ktype];
ijkparam = elem2param[itype][jtype][ktype];
delr2[0] = x[k][0] - xtmp;
delr2[1] = x[k][1] - ytmp;
delr2[2] = x[k][2] - ztmp;
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 > params[ikparam].cutsq) continue;
threebody(&params[ijparam],&params[ikparam],&params[ijkparam],
rsq1,rsq2,delr1,delr2,fj,fk,EFLAG,evdwl);
fxtmp -= fj[0] + fk[0];
fytmp -= fj[1] + fk[1];
fztmp -= fj[2] + fk[2];
fjxtmp += fj[0];
fjytmp += fj[1];
fjztmp += fj[2];
f[k][0] += fk[0];
f[k][1] += fk[1];
f[k][2] += fk[2];
- if (EVFLAG) ev_tally3_thr(this,i,j,k,evdwl,0.0,fj,fk,delr1,delr2,tid);
+ if (EVFLAG) ev_tally3_thr(this,i,j,k,evdwl,0.0,fj,fk,delr1,delr2,thr);
}
f[j][0] += fjxtmp;
f[j][1] += fjytmp;
f[j][2] += fjztmp;
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairSWOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairSW::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_sw_omp.h b/src/USER-OMP/pair_sw_omp.h
index 40052d7d4..c4af86007 100644
--- a/src/USER-OMP/pair_sw_omp.h
+++ b/src/USER-OMP/pair_sw_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(sw/omp,PairSWOMP)
#else
#ifndef LMP_PAIR_SW_OMP_H
#define LMP_PAIR_SW_OMP_H
#include "pair_sw.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairSWOMP : public PairSW, public ThrOMP {
public:
PairSWOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_table_omp.cpp b/src/USER-OMP/pair_table_omp.cpp
index 6b14d4c98..e8d63e590 100644
--- a/src/USER-OMP/pair_table_omp.cpp
+++ b/src/USER-OMP/pair_table_omp.cpp
@@ -1,202 +1,198 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_table_omp.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairTableOMP::PairTableOMP(LAMMPS *lmp) :
- PairTable(lmp), ThrOMP(lmp, PAIR)
+ PairTable(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairTableOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairTableOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairTableOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype,itable;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,factor_lj,fraction,value,a,b;
int *ilist,*jlist,*numneigh,**firstneigh;
Table *tb;
union_int_float_t rsq_lookup;
int tlm1 = tablength - 1;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
-
+
if (rsq < cutsq[itype][jtype]) {
tb = &tables[tabindex[itype][jtype]];
if (rsq < tb->innersq)
error->one(FLERR,"Pair distance < table inner cutoff");
if (tabstyle == LOOKUP) {
itable = static_cast<int> ((rsq - tb->innersq) * tb->invdelta);
if (itable >= tlm1)
error->one(FLERR,"Pair distance > table outer cutoff");
fpair = factor_lj * tb->f[itable];
} else if (tabstyle == LINEAR) {
itable = static_cast<int> ((rsq - tb->innersq) * tb->invdelta);
if (itable >= tlm1)
error->one(FLERR,"Pair distance > table outer cutoff");
fraction = (rsq - tb->rsq[itable]) * tb->invdelta;
value = tb->f[itable] + fraction*tb->df[itable];
fpair = factor_lj * value;
} else if (tabstyle == SPLINE) {
itable = static_cast<int> ((rsq - tb->innersq) * tb->invdelta);
if (itable >= tlm1)
error->one(FLERR,"Pair distance > table outer cutoff");
b = (rsq - tb->rsq[itable]) * tb->invdelta;
a = 1.0 - b;
value = a * tb->f[itable] + b * tb->f[itable+1] +
((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) *
tb->deltasq6;
fpair = factor_lj * value;
} else {
rsq_lookup.f = rsq;
itable = rsq_lookup.i & tb->nmask;
itable >>= tb->nshiftbits;
fraction = (rsq_lookup.f - tb->rsq[itable]) * tb->drsq[itable];
value = tb->f[itable] + fraction*tb->df[itable];
fpair = factor_lj * value;
}
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
if (tabstyle == LOOKUP)
evdwl = tb->e[itable];
else if (tabstyle == LINEAR || tabstyle == BITMAP)
evdwl = tb->e[itable] + fraction*tb->de[itable];
else
evdwl = a * tb->e[itable] + b * tb->e[itable+1] +
((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
tb->deltasq6;
evdwl *= factor_lj;
}
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairTableOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairTable::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_table_omp.h b/src/USER-OMP/pair_table_omp.h
index 6fd1ce74a..974149b9a 100644
--- a/src/USER-OMP/pair_table_omp.h
+++ b/src/USER-OMP/pair_table_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(table/omp,PairTableOMP)
#else
#ifndef LMP_PAIR_TABLE_OMP_H
#define LMP_PAIR_TABLE_OMP_H
#include "pair_table.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairTableOMP : public PairTable, public ThrOMP {
public:
PairTableOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_tersoff_omp.cpp b/src/USER-OMP/pair_tersoff_omp.cpp
index f59a8488f..fdbcd4829 100644
--- a/src/USER-OMP/pair_tersoff_omp.cpp
+++ b/src/USER-OMP/pair_tersoff_omp.cpp
@@ -1,252 +1,248 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_tersoff_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairTersoffOMP::PairTersoffOMP(LAMMPS *lmp) :
- PairTersoff(lmp), ThrOMP(lmp, PAIR)
+ PairTersoff(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairTersoffOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = vflag_atom = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (vflag_atom) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (vflag_atom) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (vflag_atom) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (vflag_atom) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
- } else eval<0,0,0>(f, ifrom, ito, tid);
+ } else eval<0,0,0>(ifrom, ito, thr);
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
-void PairTersoffOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairTersoffOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,k,ii,jj,kk,jnum;
int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rsq1,rsq2;
double delr1[3],delr2[3],fi[3],fj[3],fk[3];
double zeta_ij,prefactor;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *tag = atom->tag;
- int *type = atom->type;
- int nlocal = atom->nlocal;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const tag = atom->tag;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
double fxtmp,fytmp,fztmp;
// loop over full neighbor list of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
itag = tag[i];
itype = map[type[i]];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
fxtmp = fytmp = fztmp = 0.0;
// two-body interactions, skip half of them
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
jtype = map[type[j]];
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
iparam_ij = elem2param[itype][jtype][jtype];
if (rsq > params[iparam_ij].cutsq) continue;
repulsive(&params[iparam_ij],rsq,fpair,EFLAG,evdwl);
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
// three-body interactions
// skip immediately if I-J is not within cutoff
double fjxtmp,fjytmp,fjztmp;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
jtype = map[type[j]];
iparam_ij = elem2param[itype][jtype][jtype];
delr1[0] = x[j][0] - xtmp;
delr1[1] = x[j][1] - ytmp;
delr1[2] = x[j][2] - ztmp;
rsq1 = delr1[0]*delr1[0] + delr1[1]*delr1[1] + delr1[2]*delr1[2];
if (rsq1 > params[iparam_ij].cutsq) continue;
// accumulate bondorder zeta for each i-j interaction via loop over k
fjxtmp = fjytmp = fjztmp = 0.0;
zeta_ij = 0.0;
for (kk = 0; kk < jnum; kk++) {
if (jj == kk) continue;
k = jlist[kk];
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
delr2[0] = x[k][0] - xtmp;
delr2[1] = x[k][1] - ytmp;
delr2[2] = x[k][2] - ztmp;
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 > params[iparam_ijk].cutsq) continue;
zeta_ij += zeta(&params[iparam_ijk],rsq1,rsq2,delr1,delr2);
}
// pairwise force due to zeta
force_zeta(&params[iparam_ij],rsq1,zeta_ij,fpair,prefactor,EFLAG,evdwl);
fxtmp += delr1[0]*fpair;
fytmp += delr1[1]*fpair;
fztmp += delr1[2]*fpair;
fjxtmp -= delr1[0]*fpair;
fjytmp -= delr1[1]*fpair;
fjztmp -= delr1[2]*fpair;
if (EVFLAG) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,evdwl,0.0,
- -fpair,-delr1[0],-delr1[1],-delr1[2],tid);
+ -fpair,-delr1[0],-delr1[1],-delr1[2],thr);
// attractive term via loop over k
for (kk = 0; kk < jnum; kk++) {
if (jj == kk) continue;
k = jlist[kk];
k &= NEIGHMASK;
ktype = map[type[k]];
iparam_ijk = elem2param[itype][jtype][ktype];
delr2[0] = x[k][0] - xtmp;
delr2[1] = x[k][1] - ytmp;
delr2[2] = x[k][2] - ztmp;
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 > params[iparam_ijk].cutsq) continue;
attractive(&params[iparam_ijk],prefactor,
rsq1,rsq2,delr1,delr2,fi,fj,fk);
fxtmp += fi[0];
fytmp += fi[1];
fztmp += fi[2];
fjxtmp += fj[0];
fjytmp += fj[1];
fjztmp += fj[2];
f[k][0] += fk[0];
f[k][1] += fk[1];
f[k][2] += fk[2];
- if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,tid);
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,fj,fk,delr1,delr2,thr);
}
f[j][0] += fjxtmp;
f[j][1] += fjytmp;
f[j][2] += fjztmp;
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairTersoffOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairTersoff::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_tersoff_omp.h b/src/USER-OMP/pair_tersoff_omp.h
index 5e5dc066d..97c20548a 100644
--- a/src/USER-OMP/pair_tersoff_omp.h
+++ b/src/USER-OMP/pair_tersoff_omp.h
@@ -1,43 +1,43 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(tersoff/omp,PairTersoffOMP)
#else
#ifndef LMP_PAIR_TERSOFF_OMP_H
#define LMP_PAIR_TERSOFF_OMP_H
#include "pair_tersoff.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairTersoffOMP : public PairTersoff, public ThrOMP {
public:
PairTersoffOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_tersoff_table_omp.cpp b/src/USER-OMP/pair_tersoff_table_omp.cpp
new file mode 100644
index 000000000..6c9a680f0
--- /dev/null
+++ b/src/USER-OMP/pair_tersoff_table_omp.cpp
@@ -0,0 +1,496 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ This software is distributed under the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_tersoff_table_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairTersoffTableOMP::PairTersoffTableOMP(LAMMPS *lmp) :
+ PairTersoffTable(lmp), ThrOMP(lmp, THR_PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTersoffTableOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = vflag_atom = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag)
+ if (vflag_atom) eval<1,1>(ifrom, ito, thr);
+ else eval<1,0>(ifrom, ito, thr);
+ else eval<0,0>(ifrom, ito, thr);
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int VFLAG_ATOM>
+void PairTersoffTableOMP::eval(int iifrom, int iito, ThrData * const thr)
+{
+ int i,j,k,ii,inum,jnum;
+ int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+ double xtmp,ytmp,ztmp;
+ double fxtmp,fytmp,fztmp;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ int interpolIDX;
+ double r_ik_x, r_ik_y, r_ik_z;
+ double directorCos_ij_x, directorCos_ij_y, directorCos_ij_z, directorCos_ik_x, directorCos_ik_y, directorCos_ik_z;
+ double invR_ij, invR_ik, cosTeta;
+ double repulsivePotential, attractivePotential;
+ double exponentRepulsivePotential, exponentAttractivePotential,interpolTMP,interpolDeltaX,interpolY1;
+ double interpolY2, cutoffFunctionIJ, attractiveExponential, repulsiveExponential, cutoffFunctionDerivedIJ,zeta;
+ double gtetaFunctionIJK,gtetaFunctionDerivedIJK,cutoffFunctionIK;
+ double cutoffFunctionDerivedIK,factor_force3_ij,factor_1_force3_ik;
+ double factor_2_force3_ik,betaZetaPowerIJK,betaZetaPowerDerivedIJK,factor_force_tot;
+ double factor_force_ij;
+ double gtetaFunctionDerived_temp,gtetaFunction_temp;
+
+ double evdwl = 0.0;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over full neighbor list of my atoms
+ for (ii = iifrom; ii < iito; ii++) {
+
+ i = ilist[ii];
+ itype = map[type[i]];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ fxtmp = fytmp = fztmp = 0.0;
+
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ // Pre-calculate gteta and cutoff function
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+
+ double dr_ij[3], r_ij;
+
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ dr_ij[0] = xtmp - x[j][0];
+ dr_ij[1] = ytmp - x[j][1];
+ dr_ij[2] = ztmp - x[j][2];
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+
+ invR_ij = 1.0 / r_ij;
+
+ directorCos_ij_x = invR_ij * dr_ij[0];
+ directorCos_ij_y = invR_ij * dr_ij[1];
+ directorCos_ij_z = invR_ij * dr_ij[2];
+
+ // preCutoffFunction
+ interpolDeltaX = r_ij - GRIDSTART;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_FCUTOFF);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = cutoffFunction[itype][jtype][interpolIDX];
+ interpolY2 = cutoffFunction[itype][jtype][interpolIDX+1];
+ preCutoffFunction[neighbor_j] = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // preCutoffFunctionDerived
+ interpolY1 = cutoffFunctionDerived[itype][jtype][interpolIDX];
+ interpolY2 = cutoffFunctionDerived[itype][jtype][interpolIDX+1];
+ preCutoffFunctionDerived[neighbor_j] = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+
+ for (int neighbor_k = neighbor_j + 1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y + directorCos_ij_z * directorCos_ik_z;
+
+ // preGtetaFunction
+ interpolDeltaX=cosTeta+1.0;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_GTETA);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = gtetaFunction[itype][interpolIDX];
+ interpolY2 = gtetaFunction[itype][interpolIDX+1];
+ gtetaFunction_temp = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // preGtetaFunctionDerived
+ interpolY1 = gtetaFunctionDerived[itype][interpolIDX];
+ interpolY2 = gtetaFunctionDerived[itype][interpolIDX+1];
+ gtetaFunctionDerived_temp = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+ preGtetaFunction[neighbor_j][neighbor_k]=params[ijkparam].gamma*gtetaFunction_temp;
+ preGtetaFunctionDerived[neighbor_j][neighbor_k]=params[ijkparam].gamma*gtetaFunctionDerived_temp;
+ preGtetaFunction[neighbor_k][neighbor_j]=params[ijkparam].gamma*gtetaFunction_temp;
+ preGtetaFunctionDerived[neighbor_k][neighbor_j]=params[ijkparam].gamma*gtetaFunctionDerived_temp;
+
+ } // loop on K
+
+ } // loop on J
+
+
+ // loop over neighbours of atom i
+ for (int neighbor_j = 0; neighbor_j < jnum; neighbor_j++) {
+
+ double dr_ij[3], r_ij, f_ij[3];
+
+ j = jlist[neighbor_j];
+ j &= NEIGHMASK;
+
+ dr_ij[0] = xtmp - x[j][0];
+ dr_ij[1] = ytmp - x[j][1];
+ dr_ij[2] = ztmp - x[j][2];
+ r_ij = dr_ij[0]*dr_ij[0] + dr_ij[1]*dr_ij[1] + dr_ij[2]*dr_ij[2];
+
+ jtype = map[type[j]];
+ ijparam = elem2param[itype][jtype][jtype];
+
+ if (r_ij > params[ijparam].cutsq) continue;
+
+ r_ij = sqrt(r_ij);
+ invR_ij = 1.0 / r_ij;
+
+ directorCos_ij_x = invR_ij * dr_ij[0];
+ directorCos_ij_y = invR_ij * dr_ij[1];
+ directorCos_ij_z = invR_ij * dr_ij[2];
+
+ exponentRepulsivePotential = params[ijparam].lam1 * r_ij;
+ exponentAttractivePotential = params[ijparam].lam2 * r_ij;
+
+ // repulsiveExponential
+ interpolDeltaX = exponentRepulsivePotential - minArgumentExponential;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_EXP);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = exponential[interpolIDX];
+ interpolY2 = exponential[interpolIDX+1];
+ repulsiveExponential = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+ // attractiveExponential
+ interpolDeltaX = exponentAttractivePotential - minArgumentExponential;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_EXP);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = exponential[interpolIDX];
+ interpolY2 = exponential[interpolIDX+1];
+ attractiveExponential = interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX);
+
+ repulsivePotential = params[ijparam].biga * repulsiveExponential;
+ attractivePotential = -params[ijparam].bigb * attractiveExponential;
+
+ cutoffFunctionIJ = preCutoffFunction[neighbor_j];
+ cutoffFunctionDerivedIJ = preCutoffFunctionDerived[neighbor_j];
+
+ zeta = 0.0;
+
+ // first loop over neighbours of atom i except j - part 1/2
+ for (int neighbor_k = 0; neighbor_k < neighbor_j; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * r_ik_x;
+ directorCos_ik_y = invR_ik * r_ik_y;
+ directorCos_ik_z = invR_ik * r_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ zeta += cutoffFunctionIK * gtetaFunctionIJK;
+
+ }
+
+ // first loop over neighbours of atom i except j - part 2/2
+ for (int neighbor_k = neighbor_j+1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik;
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ zeta += cutoffFunctionIK * gtetaFunctionIJK;
+ }
+
+ // betaZetaPowerIJK
+ interpolDeltaX= params[ijparam].beta * zeta;
+ interpolTMP = (interpolDeltaX * GRIDDENSITY_BIJ);
+ interpolIDX = (int) interpolTMP;
+ interpolY1 = betaZetaPower[itype][interpolIDX];
+ interpolY2 = betaZetaPower[itype][interpolIDX+1];
+ betaZetaPowerIJK = (interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX));
+ // betaZetaPowerDerivedIJK
+ interpolY1 = betaZetaPowerDerived[itype][interpolIDX];
+ interpolY2 = betaZetaPowerDerived[itype][interpolIDX+1];
+ betaZetaPowerDerivedIJK = params[ijparam].beta*(interpolY1 + (interpolY2 - interpolY1) * (interpolTMP - interpolIDX));
+
+ // Forces and virial
+ factor_force_ij = 0.5*cutoffFunctionDerivedIJ*(repulsivePotential + attractivePotential * betaZetaPowerIJK)+0.5*cutoffFunctionIJ*(-repulsivePotential*params[ijparam].lam1-betaZetaPowerIJK*attractivePotential*params[ijparam].lam2);
+
+ f_ij[0] = factor_force_ij * directorCos_ij_x;
+ f_ij[1] = factor_force_ij * directorCos_ij_y;
+ f_ij[2] = factor_force_ij * directorCos_ij_z;
+
+ f[j][0] += f_ij[0];
+ f[j][1] += f_ij[1];
+ f[j][2] += f_ij[2];
+
+ fxtmp -= f_ij[0];
+ fytmp -= f_ij[1];
+ fztmp -= f_ij[2];
+
+ // potential energy
+ evdwl = cutoffFunctionIJ * repulsivePotential
+ + cutoffFunctionIJ * attractivePotential * betaZetaPowerIJK;
+
+ if (EVFLAG) ev_tally_thr(this,i, j, nlocal, /* newton_pair */ 1, 0.5 * evdwl, 0.0,
+ -factor_force_ij*invR_ij, dr_ij[0], dr_ij[1], dr_ij[2],thr);
+
+ factor_force_tot= 0.5*cutoffFunctionIJ*attractivePotential*betaZetaPowerDerivedIJK;
+
+ // second loop over neighbours of atom i except j, forces and virial only - part 1/2
+ for (int neighbor_k = 0; neighbor_k < neighbor_j; neighbor_k++) {
+ double dr_ik[3], r_ik, f_ik[3];
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y
+ + directorCos_ij_z * directorCos_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ gtetaFunctionDerivedIJK = preGtetaFunctionDerived[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ cutoffFunctionDerivedIK = preCutoffFunctionDerived[neighbor_k];
+
+ factor_force3_ij= cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ij *factor_force_tot;
+
+ f_ij[0] = factor_force3_ij * (directorCos_ij_x*cosTeta - directorCos_ik_x);
+ f_ij[1] = factor_force3_ij * (directorCos_ij_y*cosTeta - directorCos_ik_y);
+ f_ij[2] = factor_force3_ij * (directorCos_ij_z*cosTeta - directorCos_ik_z);
+
+ factor_1_force3_ik = (cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ik)*factor_force_tot;
+ factor_2_force3_ik = -(cutoffFunctionDerivedIK * gtetaFunctionIJK)*factor_force_tot;
+
+ f_ik[0] = factor_1_force3_ik * (directorCos_ik_x*cosTeta - directorCos_ij_x)
+ + factor_2_force3_ik * directorCos_ik_x;
+ f_ik[1] = factor_1_force3_ik * (directorCos_ik_y*cosTeta - directorCos_ij_y)
+ + factor_2_force3_ik * directorCos_ik_y;
+ f_ik[2] = factor_1_force3_ik * (directorCos_ik_z*cosTeta - directorCos_ij_z)
+ + factor_2_force3_ik * directorCos_ik_z;
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[k][0] -= f_ik[0];
+ f[k][1] -= f_ik[1];
+ f[k][2] -= f_ik[2];
+
+ fxtmp += f_ij[0] + f_ik[0];
+ fytmp += f_ij[1] + f_ik[1];
+ fztmp += f_ij[2] + f_ik[2];
+
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,f_ij,f_ik,dr_ij,dr_ik,thr);
+ }
+
+ // second loop over neighbours of atom i except j, forces and virial only - part 2/2
+ for (int neighbor_k = neighbor_j+1; neighbor_k < jnum; neighbor_k++) {
+ double dr_ik[3], r_ik, f_ik[3];
+
+ k = jlist[neighbor_k];
+ k &= NEIGHMASK;
+ ktype = map[type[k]];
+ ikparam = elem2param[itype][ktype][ktype];
+ ijkparam = elem2param[itype][jtype][ktype];
+
+ dr_ik[0] = xtmp -x[k][0];
+ dr_ik[1] = ytmp -x[k][1];
+ dr_ik[2] = ztmp -x[k][2];
+ r_ik = dr_ik[0]*dr_ik[0] + dr_ik[1]*dr_ik[1] + dr_ik[2]*dr_ik[2];
+
+ if (r_ik > params[ikparam].cutsq) continue;
+
+ r_ik = sqrt(r_ik);
+ invR_ik = 1.0 / r_ik;
+
+ directorCos_ik_x = invR_ik * dr_ik[0];
+ directorCos_ik_y = invR_ik * dr_ik[1];
+ directorCos_ik_z = invR_ik * dr_ik[2];
+
+ cosTeta = directorCos_ij_x * directorCos_ik_x + directorCos_ij_y * directorCos_ik_y
+ + directorCos_ij_z * directorCos_ik_z;
+
+ gtetaFunctionIJK = preGtetaFunction[neighbor_j][neighbor_k];
+
+ gtetaFunctionDerivedIJK = preGtetaFunctionDerived[neighbor_j][neighbor_k];
+
+ cutoffFunctionIK = preCutoffFunction[neighbor_k];
+
+ cutoffFunctionDerivedIK = preCutoffFunctionDerived[neighbor_k];
+
+ factor_force3_ij= cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ij *factor_force_tot;
+
+ f_ij[0] = factor_force3_ij * (directorCos_ij_x*cosTeta - directorCos_ik_x);
+ f_ij[1] = factor_force3_ij * (directorCos_ij_y*cosTeta - directorCos_ik_y);
+ f_ij[2] = factor_force3_ij * (directorCos_ij_z*cosTeta - directorCos_ik_z);
+
+ factor_1_force3_ik = (cutoffFunctionIK * gtetaFunctionDerivedIJK * invR_ik)*factor_force_tot;
+ factor_2_force3_ik = -(cutoffFunctionDerivedIK * gtetaFunctionIJK)*factor_force_tot;
+
+ f_ik[0] = factor_1_force3_ik * (directorCos_ik_x*cosTeta - directorCos_ij_x)
+ + factor_2_force3_ik * directorCos_ik_x;
+ f_ik[1] = factor_1_force3_ik * (directorCos_ik_y*cosTeta - directorCos_ij_y)
+ + factor_2_force3_ik * directorCos_ik_y;
+ f_ik[2] = factor_1_force3_ik * (directorCos_ik_z*cosTeta - directorCos_ij_z)
+ + factor_2_force3_ik * directorCos_ik_z;
+
+ f[j][0] -= f_ij[0];
+ f[j][1] -= f_ij[1];
+ f[j][2] -= f_ij[2];
+
+ f[k][0] -= f_ik[0];
+ f[k][1] -= f_ik[1];
+ f[k][2] -= f_ik[2];
+
+ fxtmp += f_ij[0] + f_ik[0];
+ fytmp += f_ij[1] + f_ik[1];
+ fztmp += f_ij[2] + f_ik[2];
+
+ if (VFLAG_ATOM) v_tally3_thr(i,j,k,f_ij,f_ik,dr_ij,dr_ik,thr);
+
+ }
+ } // loop on J
+ f[i][0] += fxtmp;
+ f[i][1] += fytmp;
+ f[i][2] += fztmp;
+ } // loop on I
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairTersoffTableOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairTersoffTable::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_edip_omp.h b/src/USER-OMP/pair_tersoff_table_omp.h
similarity index 68%
copy from src/USER-OMP/pair_edip_omp.h
copy to src/USER-OMP/pair_tersoff_table_omp.h
index 55c34db34..ffde58215 100644
--- a/src/USER-OMP/pair_edip_omp.h
+++ b/src/USER-OMP/pair_tersoff_table_omp.h
@@ -1,43 +1,43 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(edip/omp,PairEDIPOMP)
+PairStyle(tersoff/table/omp,PairTersoffTableOMP)
#else
-#ifndef LMP_PAIR_EDIP_OMP_H
-#define LMP_PAIR_EDIP_OMP_H
+#ifndef LMP_PAIR_TERSOFF_TABLE_OMP_H
+#define LMP_PAIR_TERSOFF_TABLE_OMP_H
-#include "pair_edip.h"
+#include "pair_tersoff_table.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairEDIPOMP : public PairEDIP, public ThrOMP {
+class PairTersoffTableOMP : public PairTersoffTable, public ThrOMP {
public:
- PairEDIPOMP(class LAMMPS *);
+ PairTersoffTableOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
- template <int EVFLAG, int EFLAG, int VFLAG_ATOM>
- void eval(double **f, int ifrom, int ito, int tid);
+ template <int EVFLAG, int VFLAG_ATOM>
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_tri_lj_omp.cpp b/src/USER-OMP/pair_tri_lj_omp.cpp
new file mode 100644
index 000000000..97f58a62d
--- /dev/null
+++ b/src/USER-OMP/pair_tri_lj_omp.cpp
@@ -0,0 +1,409 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "pair_tri_lj_omp.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "atom_vec_tri.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+
+#include <string.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairTriLJOMP::PairTriLJOMP(LAMMPS *lmp) :
+ PairTriLJ(lmp), ThrOMP(lmp, THR_PAIR)
+{
+ respa_enable = 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTriLJOMP::compute(int eflag, int vflag)
+{
+ if (eflag || vflag) {
+ ev_setup(eflag,vflag);
+ } else evflag = vflag_fdotr = 0;
+
+ const int nall = atom->nlocal + atom->nghost;
+ const int nthreads = comm->nthreads;
+ const int inum = list->inum;
+ const int * const tri = atom->tri;
+ const int * const type = atom->type;
+ AtomVecTri::Bonus * const bonus = avec->bonus;
+
+ // grow discrete list if necessary and initialize
+
+ if (nall > nmax) {
+ nmax = nall;
+ memory->destroy(dnum);
+ memory->destroy(dfirst);
+ memory->create(dnum,nall,"pair:dnum");
+ memory->create(dfirst,nall,"pair:dfirst");
+ }
+ memset(dnum,0,nall*sizeof(int));
+ ndiscrete = 0;
+
+ // need to discretize the system ahead of time
+ // until we find a good way to multi-thread it.
+ for (int i = 0; i < nall; ++i) {
+ double dc1[3],dc2[3],dc3[3],p[3][3];
+
+ if (tri[i] >= 0) {
+ if (dnum[i] == 0) {
+ MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
+ MathExtra::matvec(p,bonus[tri[i]].c1,dc1);
+ MathExtra::matvec(p,bonus[tri[i]].c2,dc2);
+ MathExtra::matvec(p,bonus[tri[i]].c3,dc3);
+ dfirst[i] = ndiscrete;
+ discretize(i,sigma[type[i]][type[i]],dc1,dc2,dc3);
+ dnum[i] = ndiscrete - dfirst[i];
+ }
+ }
+ }
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+ int ifrom, ito, tid;
+
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
+
+ if (evflag) {
+ if (eflag) {
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
+ } else {
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
+ }
+ } else {
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
+ }
+
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+void PairTriLJOMP::eval(int iifrom, int iito, ThrData * const thr)
+{
+ int i,j,ii,jj,jnum,itype,jtype;
+ int ni,nj,npi,npj,ifirst,jfirst;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double rsq,r2inv,r6inv,term1,term2,sig,sig3,forcelj;
+ double dxi,dxj,dyi,dyj,dzi,dzj;
+ double xi[3],xj[3],fi[3],fj[3],ti[3],tj[3];
+ int *ilist,*jlist,*numneigh,**firstneigh;
+
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ double * const * const torque = thr->get_torque();
+ const int * const tri = atom->tri;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = iifrom; ii < iito; ++ii) {
+
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq >= cutsq[itype][jtype]) continue;
+
+ // tri/tri interactions = NxN particles
+ // c1,c2,c3 = corner pts of triangle I or J
+
+ evdwl = 0.0;
+ if (tri[i] >= 0 && tri[j] >= 0) {
+ npi = dnum[i];
+ ifirst = dfirst[i];
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ fi[0]=fi[1]=fi[2]=fj[0]=fj[1]=fj[2]=0.0;
+ ti[0]=ti[1]=ti[2]=tj[0]=tj[1]=tj[2]=0.0;
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ fi[2] += delz*fpair;
+ ti[0] += fpair*(dyi*delz - dzi*dely);
+ ti[1] += fpair*(dzi*delx - dxi*delz);
+ ti[2] += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ fj[2] -= delz*fpair;
+ tj[0] -= fpair*(dyj*delz - dzj*dely);
+ tj[1] -= fpair*(dzj*delx - dxj*delz);
+ tj[2] -= fpair*(dxj*dely - dyj*delx);
+ }
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ torque[i][0] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+
+ // tri/particle interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle I
+
+ } else if (tri[i] >= 0) {
+ npi = dnum[i];
+ ifirst = dfirst[i];
+
+ fi[0]=fi[1]=fi[2]=fj[0]=fj[1]=fj[2]=0.0;
+ ti[0]=ti[1]=ti[2]=tj[0]=tj[1]=tj[2]=0.0;
+
+ for (ni = 0; ni < npi; ni++) {
+ dxi = discrete[ifirst+ni].dx;
+ dyi = discrete[ifirst+ni].dy;
+ dzi = discrete[ifirst+ni].dz;
+
+ xi[0] = x[i][0] + dxi;
+ xi[1] = x[i][1] + dyi;
+ xi[2] = x[i][2] + dzi;
+ xj[0] = x[j][0];
+ xj[1] = x[j][1];
+ xj[2] = x[j][2];
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (discrete[ifirst+ni].sigma+sigma[jtype][jtype]);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ fi[2] += delz*fpair;
+ ti[0] += fpair*(dyi*delz - dzi*dely);
+ ti[1] += fpair*(dzi*delx - dxi*delz);
+ ti[2] += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ fj[2] -= delz*fpair;
+ tj[0] -= fpair*(dyj*delz - dzj*dely);
+ tj[1] -= fpair*(dzj*delx - dxj*delz);
+ tj[2] -= fpair*(dxj*dely - dyj*delx);
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ torque[i][0] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+
+ // particle/tri interaction = Nx1 particles
+ // c1,c2,c3 = corner pts of triangle J
+
+ } else if (tri[j] >= 0) {
+ npj = dnum[j];
+ jfirst = dfirst[j];
+
+ fi[0]=fi[1]=fi[2]=fj[0]=fj[1]=fj[2]=0.0;
+ ti[0]=ti[1]=ti[2]=tj[0]=tj[1]=tj[2]=0.0;
+
+ for (nj = 0; nj < npj; nj++) {
+ dxj = discrete[jfirst+nj].dx;
+ dyj = discrete[jfirst+nj].dy;
+ dzj = discrete[jfirst+nj].dz;
+
+ xi[0] = x[i][0];
+ xi[1] = x[i][1];
+ xi[2] = x[i][2];
+ xj[0] = x[j][0] + dxj;
+ xj[1] = x[j][1] + dyj;
+ xj[2] = x[j][2] + dzj;
+
+ delx = xi[0] - xj[0];
+ dely = xi[1] - xj[1];
+ delz = xi[2] - xj[2];
+ rsq = delx*delx + dely*dely + delz*delz;
+
+ sig = 0.5 * (sigma[itype][itype]+discrete[jfirst+nj].sigma);
+ sig3 = sig*sig*sig;
+ term2 = 24.0*epsilon[itype][jtype] * sig3*sig3;
+ term1 = 2.0 * term2 * sig3*sig3;
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (term1*r6inv - term2);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ if (EFLAG) evdwl += r6inv*(term1/12.0*r6inv-term2/6.0);
+
+ fi[0] += delx*fpair;
+ fi[1] += dely*fpair;
+ fi[2] += delz*fpair;
+ ti[0] += fpair*(dyi*delz - dzi*dely);
+ ti[1] += fpair*(dzi*delx - dxi*delz);
+ ti[2] += fpair*(dxi*dely - dyi*delx);
+
+ if (NEWTON_PAIR || j < nlocal) {
+ fj[0] -= delx*fpair;
+ fj[1] -= dely*fpair;
+ fj[2] -= delz*fpair;
+ tj[0] -= fpair*(dyj*delz - dzj*dely);
+ tj[1] -= fpair*(dzj*delx - dxj*delz);
+ tj[2] -= fpair*(dxj*dely - dyj*delx);
+ }
+ }
+
+ f[i][0] += fi[0];
+ f[i][1] += fi[1];
+ f[i][2] += fi[2];
+ f[j][0] += fj[0];
+ f[j][1] += fj[1];
+ f[j][2] += fj[2];
+ torque[i][0] += ti[0];
+ torque[i][1] += ti[1];
+ torque[i][2] += ti[2];
+ torque[j][0] += tj[0];
+ torque[j][1] += tj[1];
+ torque[j][2] += tj[2];
+
+ // particle/particle interaction = 1x1 particles
+
+ } else {
+ r2inv = 1.0/rsq;
+ r6inv = r2inv*r2inv*r2inv;
+ forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+ fpair = forcelj*r2inv;
+
+ if (EFLAG)
+ evdwl += r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (NEWTON_PAIR || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+ }
+
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairTriLJOMP::memory_usage()
+{
+ double bytes = memory_usage_thr();
+ bytes += PairTriLJ::memory_usage();
+
+ return bytes;
+}
diff --git a/src/USER-OMP/pair_born_omp.h b/src/USER-OMP/pair_tri_lj_omp.h
similarity index 80%
copy from src/USER-OMP/pair_born_omp.h
copy to src/USER-OMP/pair_tri_lj_omp.h
index b24de4a57..d21c562a8 100644
--- a/src/USER-OMP/pair_born_omp.h
+++ b/src/USER-OMP/pair_tri_lj_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(born/omp,PairBornOMP)
+PairStyle(tri/lj/omp,PairTriLJOMP)
#else
-#ifndef LMP_PAIR_BORN_OMP_H
-#define LMP_PAIR_BORN_OMP_H
+#ifndef LMP_PAIR_TRI_LJ_OMP_H
+#define LMP_PAIR_TRI_LJ_OMP_H
-#include "pair_born.h"
+#include "pair_tri_lj.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairBornOMP : public PairBorn, public ThrOMP {
+class PairTriLJOMP : public PairTriLJ, public ThrOMP {
public:
- PairBornOMP(class LAMMPS *);
+ PairTriLJOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.cpp b/src/USER-OMP/pair_yukawa_colloid_omp.cpp
index 710ad9df1..6caa13ee9 100644
--- a/src/USER-OMP/pair_yukawa_colloid_omp.cpp
+++ b/src/USER-OMP/pair_yukawa_colloid_omp.cpp
@@ -1,164 +1,160 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_yukawa_colloid_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairYukawaColloidOMP::PairYukawaColloidOMP(LAMMPS *lmp) :
- PairYukawaColloid(lmp), ThrOMP(lmp, PAIR)
+ PairYukawaColloid(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairYukawaColloidOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairYukawaColloidOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairYukawaColloidOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair,radi,radj;
double rsq,r,rinv,r2inv,screening,forceyukawa,factor;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- double *radius = atom->radius;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const double * const radius = atom->radius;
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
radi = radius[i];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
radj = radius[j];
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
rinv = 1.0/r;
screening = exp(-kappa*(r-(radi+radj)));
forceyukawa = a[itype][jtype] * screening;
fpair = factor*forceyukawa * rinv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = a[itype][jtype]/kappa * screening - offset[itype][jtype];
evdwl *= factor;
}
if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairYukawaColloidOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairYukawaColloid::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.h b/src/USER-OMP/pair_yukawa_colloid_omp.h
index 9483cd15c..c424e9eff 100644
--- a/src/USER-OMP/pair_yukawa_colloid_omp.h
+++ b/src/USER-OMP/pair_yukawa_colloid_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(yukawa/colloid/omp,PairYukawaColloidOMP)
#else
#ifndef LMP_PAIR_YUKAWA_COLLOID_OMP_H
#define LMP_PAIR_YUKAWA_COLLOID_OMP_H
#include "pair_yukawa_colloid.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairYukawaColloidOMP : public PairYukawaColloid, public ThrOMP {
public:
PairYukawaColloidOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pair_yukawa_omp.cpp b/src/USER-OMP/pair_yukawa_omp.cpp
index 1380e2239..210c7fcc1 100644
--- a/src/USER-OMP/pair_yukawa_omp.cpp
+++ b/src/USER-OMP/pair_yukawa_omp.cpp
@@ -1,162 +1,158 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
This software is distributed under the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "pair_yukawa_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairYukawaOMP::PairYukawaOMP(LAMMPS *lmp) :
- PairYukawa(lmp), ThrOMP(lmp, PAIR)
+ PairYukawa(lmp), ThrOMP(lmp, THR_PAIR)
{
respa_enable = 0;
}
/* ---------------------------------------------------------------------- */
void PairYukawaOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
- ev_setup_thr(this);
} else evflag = vflag_fdotr = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = list->inum;
#if defined(_OPENMP)
-#pragma omp parallel default(shared)
+#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
- double **f;
- f = loop_setup_thr(atom->f, ifrom, ito, tid, inum, nall, nthreads);
+ loop_setup_thr(ifrom, ito, tid, inum, nthreads);
+ ThrData *thr = fix->get_thr(tid);
+ ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
- if (force->newton_pair) eval<1,1,1>(f, ifrom, ito, tid);
- else eval<1,1,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,1,1>(ifrom, ito, thr);
+ else eval<1,1,0>(ifrom, ito, thr);
} else {
- if (force->newton_pair) eval<1,0,1>(f, ifrom, ito, tid);
- else eval<1,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<1,0,1>(ifrom, ito, thr);
+ else eval<1,0,0>(ifrom, ito, thr);
}
} else {
- if (force->newton_pair) eval<0,0,1>(f, ifrom, ito, tid);
- else eval<0,0,0>(f, ifrom, ito, tid);
+ if (force->newton_pair) eval<0,0,1>(ifrom, ito, thr);
+ else eval<0,0,0>(ifrom, ito, thr);
}
- // reduce per thread forces into global force array.
- data_reduce_thr(&(atom->f[0][0]), nall, nthreads, 3, tid);
+ reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
-
- // reduce per thread energy and virial, if requested.
- if (evflag) ev_reduce_thr(this);
- if (vflag_fdotr) virial_fdotr_compute();
}
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
-void PairYukawaOMP::eval(double **f, int iifrom, int iito, int tid)
+void PairYukawaOMP::eval(int iifrom, int iito, ThrData * const thr)
{
int i,j,ii,jj,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r,rinv,screening,forceyukawa,factor;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
- double **x = atom->x;
- int *type = atom->type;
- int nlocal = atom->nlocal;
- double *special_lj = force->special_lj;
+ const double * const * const x = atom->x;
+ double * const * const f = thr->get_f();
+ const int * const type = atom->type;
+ const int nlocal = atom->nlocal;
+ const double * const special_lj = force->special_lj;
double fxtmp,fytmp,fztmp;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = iifrom; ii < iito; ++ii) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
fxtmp=fytmp=fztmp=0.0;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r = sqrt(rsq);
rinv = 1.0/r;
screening = exp(-kappa*r);
forceyukawa = a[itype][jtype] * screening * (kappa + rinv);
fpair = factor*forceyukawa * r2inv;
fxtmp += delx*fpair;
fytmp += dely*fpair;
fztmp += delz*fpair;
if (NEWTON_PAIR || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (EFLAG) {
evdwl = a[itype][jtype] * screening * rinv - offset[itype][jtype];
evdwl *= factor;
}
- if (EVFLAG) ev_tally_thr(this, i,j,nlocal,NEWTON_PAIR,
- evdwl,0.0,fpair,delx,dely,delz,tid);
+ if (EVFLAG) ev_tally_thr(this,i,j,nlocal,NEWTON_PAIR,
+ evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
f[i][0] += fxtmp;
f[i][1] += fytmp;
f[i][2] += fztmp;
}
}
/* ---------------------------------------------------------------------- */
double PairYukawaOMP::memory_usage()
{
double bytes = memory_usage_thr();
bytes += PairYukawa::memory_usage();
return bytes;
}
diff --git a/src/USER-OMP/pair_yukawa_omp.h b/src/USER-OMP/pair_yukawa_omp.h
index e363ac6d1..99abc569f 100644
--- a/src/USER-OMP/pair_yukawa_omp.h
+++ b/src/USER-OMP/pair_yukawa_omp.h
@@ -1,48 +1,48 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(yukawa/omp,PairYukawaOMP)
#else
#ifndef LMP_PAIR_YUKAWA_OMP_H
#define LMP_PAIR_YUKAWA_OMP_H
#include "pair_yukawa.h"
#include "thr_omp.h"
namespace LAMMPS_NS {
class PairYukawaOMP : public PairYukawa, public ThrOMP {
public:
PairYukawaOMP(class LAMMPS *);
virtual void compute(int, int);
virtual double memory_usage();
private:
template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
- void eval(double **f, int ifrom, int ito, int tid);
+ void eval(int ifrom, int ito, ThrData * const thr);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pppm_omp.cpp b/src/USER-OMP/pppm_omp.cpp
new file mode 100644
index 000000000..50c0b5422
--- /dev/null
+++ b/src/USER-OMP/pppm_omp.cpp
@@ -0,0 +1,323 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "pppm_omp.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+
+#include <string.h>
+
+using namespace LAMMPS_NS;
+
+#ifdef FFT_SINGLE
+#define ZEROF 0.0f
+#define ONEF 1.0f
+#else
+#define ZEROF 0.0
+#define ONEF 1.0
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+PPPMOMP::PPPMOMP(LAMMPS *lmp, int narg, char **arg) :
+ PPPM(lmp, narg, arg), ThrOMP(lmp, THR_KSPACE)
+{
+}
+
+
+/* ----------------------------------------------------------------------
+ allocate memory that depends on # of K-vectors and order
+------------------------------------------------------------------------- */
+
+void PPPMOMP::allocate()
+{
+ PPPM::allocate();
+
+ const int nthreads = comm->nthreads;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+ {
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ FFT_SCALAR **rho1d_thr;
+ memory->create2d_offset(rho1d_thr,3,-order/2,order/2,"pppm:rho1d_thr");
+ ThrData *thr = fix->get_thr(tid);
+ thr->init_pppm(static_cast<void *>(rho1d_thr));
+ }
+
+ const int nzend = (nzhi_out-nzlo_out+1)*nthreads + nzlo_out -1;
+
+ // reallocate density brick, so it fits our needs
+ memory->destroy3d_offset(density_brick,nzlo_out,nylo_out,nxlo_out);
+ memory->create3d_offset(density_brick,nzlo_out,nzend,nylo_out,nyhi_out,
+ nxlo_out,nxhi_out,"pppm:density_brick");
+}
+
+// NOTE: special version of reduce_data for FFT_SCALAR data type.
+// reduce per thread data into the first part of the data
+// array that is used for the non-threaded parts and reset
+// the temporary storage to 0.0. this routine depends on
+// multi-dimensional arrays like force stored in this order
+// x1,y1,z1,x2,y2,z2,...
+// we need to post a barrier to wait until all threads are done
+// with writing to the array .
+static void data_reduce_fft(FFT_SCALAR *dall, int nall, int nthreads, int ndim, int tid)
+{
+#if defined(_OPENMP)
+ // NOOP in non-threaded execution.
+ if (nthreads == 1) return;
+#pragma omp barrier
+ {
+ const int nvals = ndim*nall;
+ const int idelta = nvals/nthreads + 1;
+ const int ifrom = tid*idelta;
+ const int ito = ((ifrom + idelta) > nvals) ? nvals : (ifrom + idelta);
+
+ for (int m = ifrom; m < ito; ++m) {
+ for (int n = 1; n < nthreads; ++n) {
+ dall[m] += dall[n*nvals + m];
+ dall[n*nvals + m] = 0.0;
+ }
+ }
+ }
+#else
+ // NOOP in non-threaded execution.
+ return;
+#endif
+}
+
+/* ----------------------------------------------------------------------
+ free memory that depends on # of K-vectors and order
+------------------------------------------------------------------------- */
+
+void PPPMOMP::deallocate()
+{
+ PPPM::deallocate();
+ for (int i=0; i < comm->nthreads; ++i) {
+ ThrData * thr = fix->get_thr(i);
+ FFT_SCALAR ** rho1d_thr = static_cast<FFT_SCALAR **>(thr->get_rho1d());
+ memory->destroy2d_offset(rho1d_thr,-order/2);
+ }
+}
+
+void PPPMOMP::compute(int eflag, int vflag)
+{
+
+ PPPM::compute(eflag,vflag);
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+ ThrData *thr = fix->get_thr(tid);
+ reduce_thr(this, eflag, vflag, thr);
+ } // end of omp parallel region
+}
+
+/* ----------------------------------------------------------------------
+ create discretized "density" on section of global grid due to my particles
+ density(x,y,z) = charge "density" at grid points of my 3d brick
+ (nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
+ in global grid
+------------------------------------------------------------------------- */
+
+void PPPMOMP::make_rho()
+{
+ const double * const q = atom->q;
+ const double * const * const x = atom->x;
+ const int nthreads = comm->nthreads;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+ {
+ // each thread works on a fixed chunk of atoms.
+ const int tid = omp_get_thread_num();
+ const int inum = atom->nlocal;
+ const int idelta = 1 + inum/nthreads;
+ const int ifrom = tid*idelta;
+ const int ito = ((ifrom + idelta) > inum) ? inum : ifrom + idelta;
+#else
+ const int tid = 0;
+ const int ifrom = 0;
+ const int ito = atom->nlocal;
+#endif
+
+ int l,m,n,nx,ny,nz,mx,my,mz;
+ FFT_SCALAR dx,dy,dz,x0,y0,z0;
+
+ // set up clear 3d density array
+ const int nzoffs = (nzhi_out-nzlo_out+1)*tid;
+ FFT_SCALAR * const * const * const db = &(density_brick[nzoffs]);
+ memset(&(db[nzlo_out][nylo_out][nxlo_out]),0,ngrid*sizeof(FFT_SCALAR));
+
+ ThrData *thr = fix->get_thr(tid);
+ FFT_SCALAR * const * const r1d = static_cast<FFT_SCALAR **>(thr->get_rho1d());
+
+ // loop over my charges, add their contribution to nearby grid points
+ // (nx,ny,nz) = global coords of grid pt to "lower left" of charge
+ // (dx,dy,dz) = distance to "lower left" grid pt
+ // (mx,my,mz) = global coords of moving stencil pt
+
+ for (int i = ifrom; i < ito; i++) {
+
+ nx = part2grid[i][0];
+ ny = part2grid[i][1];
+ nz = part2grid[i][2];
+ dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
+ dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
+ dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
+
+ compute_rho1d_thr(r1d,dx,dy,dz);
+
+ z0 = delvolinv * q[i];
+ for (n = nlower; n <= nupper; n++) {
+ mz = n+nz;
+ y0 = z0*r1d[2][n];
+ for (m = nlower; m <= nupper; m++) {
+ my = m+ny;
+ x0 = y0*r1d[1][m];
+ for (l = nlower; l <= nupper; l++) {
+ mx = l+nx;
+ db[mz][my][mx] += x0*r1d[0][l];
+ }
+ }
+ }
+ }
+#if defined(_OPENMP)
+ // reduce 3d density array
+ if (nthreads > 1) {
+ sync_threads();
+ data_reduce_fft(&(density_brick[nzlo_out][nylo_out][nxlo_out]),ngrid,nthreads,1,tid);
+ }
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------
+ interpolate from grid to get electric field & force on my particles
+------------------------------------------------------------------------- */
+
+void PPPMOMP::fieldforce()
+{
+ // loop over my charges, interpolate electric field from nearby grid points
+ // (nx,ny,nz) = global coords of grid pt to "lower left" of charge
+ // (dx,dy,dz) = distance to "lower left" grid pt
+ // (mx,my,mz) = global coords of moving stencil pt
+ // ek = 3 components of E-field on particle
+
+ const double * const q = atom->q;
+ const double * const * const x = atom->x;
+ const int nthreads = comm->nthreads;
+ const double qqrd2e = force->qqrd2e;
+
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+ {
+ // each thread works on a fixed chunk of atoms.
+ const int tid = omp_get_thread_num();
+ const int inum = atom->nlocal;
+ const int idelta = 1 + inum/nthreads;
+ const int ifrom = tid*idelta;
+ const int ito = ((ifrom + idelta) > inum) ? inum : ifrom + idelta;
+#else
+ const int ifrom = 0;
+ const int ito = atom->nlocal;
+ const int tid = 0;
+#endif
+ ThrData *thr = fix->get_thr(tid);
+ double * const * const f = thr->get_f();
+ FFT_SCALAR * const * const r1d = static_cast<FFT_SCALAR **>(thr->get_rho1d());
+
+ int l,m,n,nx,ny,nz,mx,my,mz;
+ FFT_SCALAR dx,dy,dz,x0,y0,z0;
+ FFT_SCALAR ekx,eky,ekz;
+
+ for (int i = ifrom; i < ito; i++) {
+
+ nx = part2grid[i][0];
+ ny = part2grid[i][1];
+ nz = part2grid[i][2];
+ dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
+ dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
+ dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
+
+ compute_rho1d_thr(r1d,dx,dy,dz);
+
+ ekx = eky = ekz = ZEROF;
+ for (n = nlower; n <= nupper; n++) {
+ mz = n+nz;
+ z0 = r1d[2][n];
+ for (m = nlower; m <= nupper; m++) {
+ my = m+ny;
+ y0 = z0*r1d[1][m];
+ for (l = nlower; l <= nupper; l++) {
+ mx = l+nx;
+ x0 = y0*r1d[0][l];
+ ekx -= x0*vdx_brick[mz][my][mx];
+ eky -= x0*vdy_brick[mz][my][mx];
+ ekz -= x0*vdz_brick[mz][my][mx];
+ }
+ }
+ }
+
+ // convert E-field to force
+ const double qfactor = qqrd2e*scale*q[i];
+ f[i][0] += qfactor*ekx;
+ f[i][1] += qfactor*eky;
+ f[i][2] += qfactor*ekz;
+ }
+#if defined(_OPENMP)
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------
+ charge assignment into rho1d
+ dx,dy,dz = distance of particle from "lower left" grid point
+------------------------------------------------------------------------- */
+void PPPMOMP::compute_rho1d_thr(FFT_SCALAR * const * const r1d, const FFT_SCALAR &dx,
+ const FFT_SCALAR &dy, const FFT_SCALAR &dz)
+{
+ int k,l;
+ FFT_SCALAR r1,r2,r3;
+
+ for (k = (1-order)/2; k <= order/2; k++) {
+ r1 = r2 = r3 = ZEROF;
+
+ for (l = order-1; l >= 0; l--) {
+ r1 = rho_coeff[l][k] + r1*dx;
+ r2 = rho_coeff[l][k] + r2*dy;
+ r3 = rho_coeff[l][k] + r3*dz;
+ }
+ r1d[0][k] = r1;
+ r1d[1][k] = r2;
+ r1d[2][k] = r3;
+ }
+}
diff --git a/src/KSPACE/pppm_tip4p.h b/src/USER-OMP/pppm_omp.h
similarity index 62%
copy from src/KSPACE/pppm_tip4p.h
copy to src/USER-OMP/pppm_omp.h
index 764db68ed..0701cb339 100644
--- a/src/KSPACE/pppm_tip4p.h
+++ b/src/USER-OMP/pppm_omp.h
@@ -1,44 +1,49 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
-KSpaceStyle(pppm/tip4p,PPPMTIP4P)
+KSpaceStyle(pppm/omp,PPPMOMP)
#else
-#ifndef LMP_PPPM_TIP4P_H
-#define LMP_PPPM_TIP4P_H
+#ifndef LMP_PPPM_OMP_H
+#define LMP_PPPM_OMP_H
#include "pppm.h"
+#include "thr_omp.h"
namespace LAMMPS_NS {
-class PPPMTIP4P : public PPPM {
+ class PPPMOMP : public PPPM, public ThrOMP {
public:
- PPPMTIP4P(class LAMMPS *, int, char **);
- virtual ~PPPMTIP4P () {};
+ PPPMOMP(class LAMMPS *, int, char **);
+ virtual ~PPPMOMP () {};
protected:
- virtual void particle_map();
- virtual void make_rho();
+ virtual void allocate();
+ virtual void deallocate();
+ virtual void compute(int, int);
virtual void fieldforce();
+ virtual void make_rho();
+ void compute_rho1d_thr(FFT_SCALAR * const * const, const FFT_SCALAR &,
+ const FFT_SCALAR &, const FFT_SCALAR &);
+// void compute_rho_coeff();
+// void slabcorr(int);
- private:
- void find_M(int, int &, int &, double *);
};
}
#endif
#endif
diff --git a/src/USER-OMP/pppm_proxy.cpp b/src/USER-OMP/pppm_proxy.cpp
new file mode 100644
index 000000000..1b8a9c545
--- /dev/null
+++ b/src/USER-OMP/pppm_proxy.cpp
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "pppm_proxy.h"
+
+#include <stdio.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PPPMProxy::PPPMProxy(LAMMPS *lmp, int narg, char **arg) :
+ PPPM(lmp, narg, arg), ThrOMP(lmp, THR_KSPACE|THR_PROXY) {}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMProxy::setup_proxy()
+{
+ PPPM::setup();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMProxy::compute(int eflag, int vflag)
+{
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ ThrData *thr = fix->get_thr(tid);
+ reduce_thr(this, eflag,vflag,thr);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMProxy::compute_proxy(int eflag, int vflag)
+{
+ PPPM::compute(eflag,vflag);
+}
+
diff --git a/src/KSPACE/pppm_tip4p.h b/src/USER-OMP/pppm_proxy.h
similarity index 64%
copy from src/KSPACE/pppm_tip4p.h
copy to src/USER-OMP/pppm_proxy.h
index 764db68ed..e7387569d 100644
--- a/src/KSPACE/pppm_tip4p.h
+++ b/src/USER-OMP/pppm_proxy.h
@@ -1,44 +1,44 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef KSPACE_CLASS
-KSpaceStyle(pppm/tip4p,PPPMTIP4P)
+KSpaceStyle(pppm/proxy,PPPMProxy)
#else
-#ifndef LMP_PPPM_TIP4P_H
-#define LMP_PPPM_TIP4P_H
+#ifndef LMP_PPPM_PROXY_H
+#define LMP_PPPM_PROXY_H
#include "pppm.h"
+#include "thr_omp.h"
namespace LAMMPS_NS {
-class PPPMTIP4P : public PPPM {
+ class PPPMProxy : public PPPM, public ThrOMP {
public:
- PPPMTIP4P(class LAMMPS *, int, char **);
- virtual ~PPPMTIP4P () {};
+ PPPMProxy(class LAMMPS *, int, char **);
+ virtual ~PPPMProxy () {};
- protected:
- virtual void particle_map();
- virtual void make_rho();
- virtual void fieldforce();
+ virtual void compute(int, int);
+ virtual void compute_proxy(int eflag, int vflag);
- private:
- void find_M(int, int &, int &, double *);
+ // nothing to do in setup
+ virtual void setup() {};
+ virtual void setup_proxy();
};
}
#endif
#endif
diff --git a/src/USER-OMP/pppm_tip4p_proxy.cpp b/src/USER-OMP/pppm_tip4p_proxy.cpp
new file mode 100644
index 000000000..fa8d382c2
--- /dev/null
+++ b/src/USER-OMP/pppm_tip4p_proxy.cpp
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------
+ 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: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "pppm_tip4p_proxy.h"
+
+#include <stdio.h>
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PPPMTIP4PProxy::PPPMTIP4PProxy(LAMMPS *lmp, int narg, char **arg) :
+ PPPMTIP4P(lmp, narg, arg), ThrOMP(lmp, THR_KSPACE|THR_PROXY) {}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMTIP4PProxy::setup_proxy()
+{
+ PPPMTIP4P::setup();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMTIP4PProxy::compute(int eflag, int vflag)
+{
+#if defined(_OPENMP)
+#pragma omp parallel default(none) shared(eflag,vflag)
+#endif
+ {
+#if defined(_OPENMP)
+ const int tid = omp_get_thread_num();
+#else
+ const int tid = 0;
+#endif
+
+ ThrData *thr = fix->get_thr(tid);
+ reduce_thr(this, eflag,vflag,thr);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PPPMTIP4PProxy::compute_proxy(int eflag, int vflag)
+{
+ PPPMTIP4P::compute(eflag,vflag);
+}
+
diff --git a/src/GRANULAR/pair_gran_hooke.h b/src/USER-OMP/pppm_tip4p_proxy.h
similarity index 61%
copy from src/GRANULAR/pair_gran_hooke.h
copy to src/USER-OMP/pppm_tip4p_proxy.h
index d5cff796f..b69cab2ad 100644
--- a/src/GRANULAR/pair_gran_hooke.h
+++ b/src/USER-OMP/pppm_tip4p_proxy.h
@@ -1,36 +1,44 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
-#ifdef PAIR_CLASS
+#ifdef KSPACE_CLASS
-PairStyle(gran/hooke,PairGranHooke)
+KSpaceStyle(pppm/tip4p/proxy,PPPMTIP4PProxy)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_H
-#define LMP_PAIR_GRAN_HOOKE_H
+#ifndef LMP_PPPM_TIP4P_PROXY_H
+#define LMP_PPPM_TIP4P_PROXY_H
-#include "pair_gran_hooke_history.h"
+#include "pppm_tip4p.h"
+#include "thr_omp.h"
namespace LAMMPS_NS {
-class PairGranHooke : public PairGranHookeHistory {
+ class PPPMTIP4PProxy : public PPPMTIP4P, public ThrOMP {
public:
- PairGranHooke(class LAMMPS *);
+ PPPMTIP4PProxy(class LAMMPS *, int, char **);
+ virtual ~PPPMTIP4PProxy () {};
+
virtual void compute(int, int);
+ virtual void compute_proxy(int eflag, int vflag);
+
+ // nothing to do in setup
+ virtual void setup() {};
+ virtual void setup_proxy();
};
}
#endif
#endif
diff --git a/src/USER-OMP/thr_data.cpp b/src/USER-OMP/thr_data.cpp
new file mode 100644
index 000000000..069a5fc75
--- /dev/null
+++ b/src/USER-OMP/thr_data.cpp
@@ -0,0 +1,230 @@
+/* -------------------------------------------------------------------------
+ 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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ per-thread data management for LAMMPS
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#include "thr_data.h"
+
+#include <string.h>
+#include <stdio.h>
+
+using namespace LAMMPS_NS;
+
+
+ThrData::ThrData(int tid)
+ : _f(NULL), _torque(NULL), _erforce(NULL), _de(NULL), _drho(NULL), _mu(NULL),
+ _lambda(NULL), _rhoB(NULL), _D_values(NULL), _rho(NULL), _fp(NULL),
+ _rho1d(NULL), _tid(tid)
+{
+ // nothing else to do here.
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+void ThrData::check_tid(int tid)
+{
+ if (tid != _tid)
+ fprintf(stderr,"WARNING: external and internal tid mismatch %d != %d\n",tid,_tid);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ThrData::init_force(int nall, double **f, double **torque,
+ double *erforce, double *de, double *drho)
+{
+ eng_vdwl=eng_coul=eng_bond=eng_angle=eng_dihed=eng_imprp=eng_kspce=0.0;
+ memset(virial_pair,0,6*sizeof(double));
+ memset(virial_bond,0,6*sizeof(double));
+ memset(virial_angle,0,6*sizeof(double));
+ memset(virial_dihed,0,6*sizeof(double));
+ memset(virial_imprp,0,6*sizeof(double));
+ memset(virial_kspce,0,6*sizeof(double));
+
+ eatom_pair=eatom_bond=eatom_angle=eatom_dihed=eatom_imprp=eatom_kspce=NULL;
+ vatom_pair=vatom_bond=vatom_angle=vatom_dihed=vatom_imprp=vatom_kspce=NULL;
+
+ _f = f + _tid*nall;
+ if (nall > 0)
+ memset(&(_f[0][0]),0,nall*3*sizeof(double));
+
+ if (torque) {
+ _torque = torque + _tid*nall;
+ if (nall > 0)
+ memset(&(_torque[0][0]),0,nall*3*sizeof(double));
+ } else _torque = NULL;
+
+ if (erforce) {
+ _erforce = erforce + _tid*nall;
+ if (nall > 0)
+ memset(&(_erforce[0]),0,nall*sizeof(double));
+ } else _erforce = NULL;
+
+ if (de) {
+ _de = de + _tid*nall;
+ if (nall > 0)
+ memset(&(_de[0]),0,nall*sizeof(double));
+ } else _de = NULL;
+
+ if (drho) {
+ _drho = drho + _tid*nall;
+ if (nall > 0)
+ memset(&(_drho[0]),0,nall*sizeof(double));
+ } else _drho = NULL;
+}
+
+/* ----------------------------------------------------------------------
+ set up and clear out locally managed per atom arrays
+------------------------------------------------------------------------- */
+
+void ThrData::init_eam(int nall, double *rho)
+{
+ _rho = rho + _tid*nall;
+ if (nall > 0)
+ memset(_rho, 0, nall*sizeof(double));
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ThrData::init_adp(int nall, double *rho, double **mu, double **lambda)
+{
+ init_eam(nall, rho);
+
+ _mu = mu + _tid*nall;
+ _lambda = lambda + _tid*nall;
+ if (nall > 0) {
+ memset(&(_mu[0][0]), 0, nall*3*sizeof(double));
+ memset(&(_lambda[0][0]), 0, nall*6*sizeof(double));
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ThrData::init_cdeam(int nall, double *rho, double *rhoB, double *D_values)
+{
+ init_eam(nall, rho);
+
+ _rhoB = rhoB + _tid*nall;
+ _D_values = D_values + _tid*nall;
+ if (nall > 0) {
+ memset(_rhoB, 0, nall*sizeof(double));
+ memset(_D_values, 0, nall*sizeof(double));
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ThrData::init_eim(int nall, double *rho, double *fp)
+{
+ init_eam(nall, rho);
+
+ _fp = fp + _tid*nall;
+ if (nall > 0)
+ memset(_fp,0,nall*sizeof(double));
+}
+
+/* ----------------------------------------------------------------------
+ compute global pair virial via summing F dot r over own & ghost atoms
+ at this point, only pairwise forces have been accumulated in atom->f
+------------------------------------------------------------------------- */
+
+void ThrData::virial_fdotr_compute(double **x, int nlocal, int nghost, int nfirst)
+{
+
+ // sum over force on all particles including ghosts
+
+ if (nfirst < 0) {
+ int nall = nlocal + nghost;
+ for (int i = 0; i < nall; i++) {
+ virial_pair[0] += _f[i][0]*x[i][0];
+ virial_pair[1] += _f[i][1]*x[i][1];
+ virial_pair[2] += _f[i][2]*x[i][2];
+ virial_pair[3] += _f[i][1]*x[i][0];
+ virial_pair[4] += _f[i][2]*x[i][0];
+ virial_pair[5] += _f[i][2]*x[i][1];
+ }
+
+ // neighbor includegroup flag is set
+ // sum over force on initial nfirst particles and ghosts
+
+ } else {
+ int nall = nfirst;
+ for (int i = 0; i < nall; i++) {
+ virial_pair[0] += _f[i][0]*x[i][0];
+ virial_pair[1] += _f[i][1]*x[i][1];
+ virial_pair[2] += _f[i][2]*x[i][2];
+ virial_pair[3] += _f[i][1]*x[i][0];
+ virial_pair[4] += _f[i][2]*x[i][0];
+ virial_pair[5] += _f[i][2]*x[i][1];
+ }
+
+ nall = nlocal + nghost;
+ for (int i = nlocal; i < nall; i++) {
+ virial_pair[0] += _f[i][0]*x[i][0];
+ virial_pair[1] += _f[i][1]*x[i][1];
+ virial_pair[2] += _f[i][2]*x[i][2];
+ virial_pair[3] += _f[i][1]*x[i][0];
+ virial_pair[4] += _f[i][2]*x[i][0];
+ virial_pair[5] += _f[i][2]*x[i][1];
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double ThrData::memory_usage()
+{
+ double bytes = (7 + 6*6) * sizeof(double);
+ bytes += 2 * sizeof(double*);
+ bytes += 4 * sizeof(int);
+
+ return bytes;
+}
+
+/* additional helper functions */
+
+// reduce per thread data into the first part of the data
+// array that is used for the non-threaded parts and reset
+// the temporary storage to 0.0. this routine depends on
+// multi-dimensional arrays like force stored in this order
+// x1,y1,z1,x2,y2,z2,...
+// we need to post a barrier to wait until all threads are done
+// with writing to the array .
+void LAMMPS_NS::data_reduce_thr(double *dall, int nall, int nthreads, int ndim, int tid)
+{
+#if defined(_OPENMP)
+ // NOOP in non-threaded execution.
+ if (nthreads == 1) return;
+#pragma omp barrier
+ {
+ const int nvals = ndim*nall;
+ const int idelta = nvals/nthreads + 1;
+ const int ifrom = tid*idelta;
+ const int ito = ((ifrom + idelta) > nvals) ? nvals : (ifrom + idelta);
+
+ for (int m = ifrom; m < ito; ++m) {
+ for (int n = 1; n < nthreads; ++n) {
+ dall[m] += dall[n*nvals + m];
+ dall[n*nvals + m] = 0.0;
+ }
+ }
+ }
+#else
+ // NOOP in non-threaded execution.
+ return;
+#endif
+}
+
diff --git a/src/USER-OMP/thr_data.h b/src/USER-OMP/thr_data.h
new file mode 100644
index 000000000..400d5716c
--- /dev/null
+++ b/src/USER-OMP/thr_data.h
@@ -0,0 +1,132 @@
+/* -*- c++ -*- -------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing author: Axel Kohlmeyer (Temple U)
+------------------------------------------------------------------------- */
+
+#ifndef LMP_THR_DATA_H
+#define LMP_THR_DATA_H
+
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
+
+namespace LAMMPS_NS {
+
+// per thread data accumulators
+// there should be one instance
+// of this class for each thread.
+class ThrData {
+ friend class FixOMP;
+ friend class ThrOMP;
+
+ public:
+ ThrData(int tid);
+ ~ThrData() {};
+
+ void check_tid(int); // thread id consistency check
+ int get_tid() const { return _tid; }; // our thread id.
+
+ // erase accumulator contents and hook up force arrays
+ void init_force(int, double **, double **, double *, double *, double *);
+
+ // give access to per-thread offset arrays
+ double **get_f() const { return _f; };
+ double **get_torque() const { return _torque; };
+ double *get_de() const { return _de; };
+ double *get_drho() const { return _drho; };
+
+ // setup and erase per atom arrays
+ void init_adp(int, double *, double **, double **); // ADP (+ EAM)
+ void init_cdeam(int, double *, double *, double *); // CDEAM (+ EAM)
+ void init_eam(int, double *); // EAM
+ void init_eim(int, double *, double *); // EIM (+ EAM)
+
+ void init_pppm(void *r1d) { _rho1d = r1d; };
+
+ // access methods for arrays that we handle in this class
+ double **get_lambda() const { return _lambda; };
+ double **get_mu() const { return _mu; };
+ double *get_D_values() const { return _D_values; };
+ double *get_fp() const { return _fp; };
+ double *get_rho() const { return _rho; };
+ double *get_rhoB() const { return _rhoB; };
+ void *get_rho1d() const { return _rho1d; };
+
+ private:
+ double eng_vdwl; // non-bonded non-coulomb energy
+ double eng_coul; // non-bonded coulomb energy
+ double virial_pair[6]; // virial contribution from non-bonded
+ double *eatom_pair;
+ double **vatom_pair;
+ double eng_bond; // bond energy
+ double virial_bond[6]; // virial contribution from bonds
+ double *eatom_bond;
+ double **vatom_bond;
+ double eng_angle; // angle energy
+ double virial_angle[6]; // virial contribution from angles
+ double *eatom_angle;
+ double **vatom_angle;
+ double eng_dihed; // dihedral energy
+ double virial_dihed[6]; // virial contribution from dihedrals
+ double *eatom_dihed;
+ double **vatom_dihed;
+ double eng_imprp; // improper energy
+ double virial_imprp[6]; // virial contribution from impropers
+ double *eatom_imprp;
+ double **vatom_imprp;
+ double eng_kspce; // kspace energy
+ double virial_kspce[6]; // virial contribution from kspace
+ double *eatom_kspce;
+ double **vatom_kspce;
+
+ // per thread segments of various force or similar arrays
+
+ // these are maintained by atom styles
+ double **_f;
+ double **_torque;
+ double *_erforce;
+ double *_de;
+ double *_drho;
+
+ // these are maintained by individual pair styles
+ double **_mu, **_lambda; // ADP (+ EAM)
+ double *_rhoB, *_D_values; // CDEAM (+ EAM)
+ double *_rho; // EAM
+ double *_fp; // EIM (+ EAM)
+
+ // this is for pppm/omp
+ void *_rho1d;
+
+ // my thread id
+ const int _tid;
+
+ public:
+ // compute global per thread virial contribution from per-thread force
+ void virial_fdotr_compute(double **, int, int, int);
+
+ double memory_usage();
+
+ // disabled default methods
+ private:
+ ThrData() : _tid(-1) {};
+};
+
+////////////////////////////////////////////////////////////////////////
+// helper functions operating on data replicated for thread support //
+////////////////////////////////////////////////////////////////////////
+// generic per thread data reduction for continous arrays of nthreads*nmax size
+void data_reduce_thr(double *, int, int, int, int);
+}
+#endif
diff --git a/src/USER-OMP/thr_omp.cpp b/src/USER-OMP/thr_omp.cpp
index 37ce1f198..5ae7cc87d 100644
--- a/src/USER-OMP/thr_omp.cpp
+++ b/src/USER-OMP/thr_omp.cpp
@@ -1,833 +1,1162 @@
/* -------------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
OpenMP based threading support for LAMMPS
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
-#include "thr_omp.h"
-
-#include "memory.h"
-
#include "atom.h"
#include "comm.h"
+#include "error.h"
#include "force.h"
+#include "memory.h"
+#include "modify.h"
+#include "neighbor.h"
+
+#include "thr_omp.h"
#include "pair.h"
+#include "bond.h"
+#include "angle.h"
#include "dihedral.h"
-
-#if defined(_OPENMP)
-#include <omp.h>
-#endif
+#include "improper.h"
+#include "kspace.h"
#include "math_const.h"
+#include <string.h>
+
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
-ThrOMP::ThrOMP(LAMMPS *ptr, int style) : thr_style(style), lmp(ptr)
+ThrOMP::ThrOMP(LAMMPS *ptr, int style) : lmp(ptr), fix(NULL), thr_style(style)
{
- // initialize fixed size per thread storage
- eng_vdwl_thr = eng_coul_thr = eng_bond_thr = NULL;
- virial_thr = NULL;
-
- lmp->memory->create(eng_vdwl_thr,lmp->comm->nthreads,"thr_omp:eng_vdwl_thr");
- lmp->memory->create(eng_coul_thr,lmp->comm->nthreads,"thr_omp:eng_coul_thr");
- lmp->memory->create(eng_bond_thr,lmp->comm->nthreads,"thr_omp:eng_bond_thr");
- lmp->memory->create(virial_thr,lmp->comm->nthreads,6,"thr_omp:virial_thr");
-
- // variable size per thread, per atom storage
- // the actually allocation happens via memory->grow() in ev_steup_thr()
- maxeatom_thr = maxvatom_thr = 0;
- evflag_global = evflag_atom = 0;
- eatom_thr = NULL;
- vatom_thr = NULL;
+ // register fix omp with this class
+ int ifix = lmp->modify->find_fix("package_omp");
+ if (ifix < 0)
+ lmp->error->all(FLERR,"The 'package omp' command is required for /omp styles");
+ fix = static_cast<FixOMP *>(lmp->modify->fix[ifix]);
}
/* ---------------------------------------------------------------------- */
ThrOMP::~ThrOMP()
{
- lmp->memory->destroy(eng_vdwl_thr);
- lmp->memory->destroy(eng_coul_thr);
- lmp->memory->destroy(eng_bond_thr);
- lmp->memory->destroy(virial_thr);
- lmp->memory->destroy(eatom_thr);
- lmp->memory->destroy(vatom_thr);
+ // nothing to do?
}
-/* ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ Hook up per thread per atom arrays into the tally infrastructure
+ ---------------------------------------------------------------------- */
-void ThrOMP::ev_setup_acc_thr(int ntotal, int eflag_global, int vflag_global,
- int eflag_atom, int vflag_atom, int nthreads)
+void ThrOMP::ev_setup_thr(int eflag, int vflag, int nall, double *eatom,
+ double **vatom, ThrData *thr)
{
- int t,i;
-
- evflag_global = (eflag_global || vflag_global);
- evflag_atom = (eflag_atom || vflag_atom);
+ const int tid = thr->get_tid();
- for (t = 0; t < nthreads; ++t) {
+ if (thr_style & THR_PAIR) {
+ if (eflag & 2) {
+ thr->eatom_pair = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_pair[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_pair = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_pair[0][0]),0,nall*6*sizeof(double));
+ }
+ }
+
+ if (thr_style & THR_BOND) {
+ if (eflag & 2) {
+ thr->eatom_bond = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_bond[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_bond = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_bond[0][0]),0,nall*6*sizeof(double));
+ }
+ }
- if (eflag_global)
- eng_vdwl_thr[t] = eng_coul_thr[t] = eng_bond_thr[t] = 0.0;
+ if (thr_style & THR_ANGLE) {
+ if (eflag & 2) {
+ thr->eatom_angle = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_angle[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_angle = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_angle[0][0]),0,nall*6*sizeof(double));
+ }
+ }
- if (vflag_global)
- for (i = 0; i < 6; ++i)
- virial_thr[t][i] = 0.0;
+ if (thr_style & THR_DIHEDRAL) {
+ if (eflag & 2) {
+ thr->eatom_dihed = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_dihed[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_dihed = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_dihed[0][0]),0,nall*6*sizeof(double));
+ }
+ }
- if (eflag_atom)
- for (i = 0; i < ntotal; ++i)
- eatom_thr[t][i] = 0.0;
-
- if (vflag_atom)
- for (i = 0; i < ntotal; ++i) {
- vatom_thr[t][i][0] = 0.0;
- vatom_thr[t][i][1] = 0.0;
- vatom_thr[t][i][2] = 0.0;
- vatom_thr[t][i][3] = 0.0;
- vatom_thr[t][i][4] = 0.0;
- vatom_thr[t][i][5] = 0.0;
- }
+ if (thr_style & THR_IMPROPER) {
+ if (eflag & 2) {
+ thr->eatom_imprp = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_imprp[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_imprp = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_imprp[0][0]),0,nall*6*sizeof(double));
+ }
}
-}
-/* ---------------------------------------------------------------------- */
+#if 0 /* not supported (yet) */
+ if (thr_style & THR_KSPACE) {
+ if (eflag & 2) {
+ thr->eatom_kspce = eatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->eatom_kspce[0]),0,nall*sizeof(double));
+ }
+ if (vflag & 4) {
+ thr->vatom_kspce = vatom + tid*nall;
+ if (nall > 0)
+ memset(&(thr->vatom_kspce[0][0]),0,nall*6*sizeof(double));
+ }
+ }
+#endif
+}
-void ThrOMP::ev_setup_thr(Dihedral *dihed)
+/* ----------------------------------------------------------------------
+ Reduce per thread data into the regular structures
+ Reduction of global properties is serialized with a "critical"
+ directive, so that only one thread at a time will access the
+ global variables. Since we are not synchronized, this should
+ come with little overhead. The reduction of per-atom properties
+ in contrast is parallelized over threads in the same way as forces.
+ ---------------------------------------------------------------------- */
+
+void ThrOMP::reduce_thr(void *style, const int eflag, const int vflag,
+ ThrData *const thr, const int nproxy)
{
- int nthreads = lmp->comm->nthreads;
+ const int nlocal = lmp->atom->nlocal;
+ const int nghost = lmp->atom->nghost;
+ const int nall = nlocal + nghost;
+ const int nfirst = lmp->atom->nfirst;
+ const int nthreads = lmp->comm->nthreads;
+ const int evflag = eflag | vflag;
+
+ const int tid = thr->get_tid();
+ double **f = lmp->atom->f;
+ double **x = lmp->atom->x;
+
+ switch (thr_style) {
- // reallocate per-atom arrays if necessary
- if (dihed->eflag_atom && lmp->atom->nmax > maxeatom_thr) {
- maxeatom_thr = lmp->atom->nmax;
- lmp->memory->grow(eatom_thr,nthreads,maxeatom_thr,"thr_omp:eatom_thr");
+ case THR_PAIR: {
+ Pair * const pair = lmp->force->pair;
+
+ if (pair->vflag_fdotr) {
+ if (lmp->neighbor->includegroup == 0)
+ thr->virial_fdotr_compute(x, nlocal, nghost, -1);
+ else
+ thr->virial_fdotr_compute(x, nlocal, nghost, nfirst);
+ }
+
+ if (evflag) {
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ if (eflag & 1) {
+ pair->eng_vdwl += thr->eng_vdwl;
+ pair->eng_coul += thr->eng_coul;
+ thr->eng_vdwl = 0.0;
+ thr->eng_coul = 0.0;
+ }
+ if (vflag & 3)
+ for (int i=0; i < 6; ++i) {
+ pair->virial[i] += thr->virial_pair[i];
+ thr->virial_pair[i] = 0.0;
+ }
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(pair->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
}
- if (dihed->vflag_atom && lmp->atom->nmax > maxvatom_thr) {
- maxvatom_thr = lmp->atom->nmax;
- lmp->memory->grow(vatom_thr,nthreads,maxeatom_thr,6,"thr_omp:vatom_thr");
+ break;
+
+ case THR_PAIR|THR_PROXY: {
+ Pair * const pair = lmp->force->pair;
+
+ if (tid >= nproxy && pair->vflag_fdotr) {
+ if (lmp->neighbor->includegroup == 0)
+ thr->virial_fdotr_compute(x, nlocal, nghost, -1);
+ else
+ thr->virial_fdotr_compute(x, nlocal, nghost, nfirst);
+ }
+
+ if (evflag) {
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ if (tid < nproxy) {
+ // nothing to do for kspace?
+ if (vflag & 3)
+ for (int i=0; i < 6; ++i) {
+ thr->virial_pair[i] = 0.0;
+ }
+ } else {
+ if (eflag & 1) {
+ pair->eng_vdwl += thr->eng_vdwl;
+ pair->eng_coul += thr->eng_coul;
+ thr->eng_vdwl = 0.0;
+ thr->eng_coul = 0.0;
+ }
+ if (vflag & 3)
+ for (int i=0; i < 6; ++i) {
+ pair->virial[i] += thr->virial_pair[i];
+ thr->virial_pair[i] = 0.0;
+ }
+ }
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(pair->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
}
+ break;
- int ntotal = (lmp->force->newton_bond) ?
- (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
+ case THR_BOND:
- // set up per thread accumulators
- ev_setup_acc_thr(ntotal, dihed->eflag_global, dihed->vflag_global,
- dihed->eflag_atom, dihed->vflag_atom, nthreads);
-}
+ if (evflag) {
+ Bond * const bond = lmp->force->bond;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ bond->energy += thr->eng_bond;
+ for (int i=0; i < 6; ++i)
+ bond->virial[i] += thr->virial_bond[i];
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(bond->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(bond->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+ break;
-/* ---------------------------------------------------------------------- */
+ case THR_ANGLE:
-void ThrOMP::ev_setup_thr(Pair *pair)
-{
- int nthreads = lmp->comm->nthreads;
+ if (evflag) {
+ Angle * const angle = lmp->force->angle;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ angle->energy += thr->eng_angle;
+ for (int i=0; i < 6; ++i)
+ angle->virial[i] += thr->virial_angle[i];
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(angle->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(angle->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+ break;
- // reallocate per-atom arrays if necessary
- if (pair->eflag_atom && lmp->atom->nmax > maxeatom_thr) {
- maxeatom_thr = lmp->atom->nmax;
- lmp->memory->grow(eatom_thr,nthreads,maxeatom_thr,"thr_omp:eatom_thr");
- }
- if (pair->vflag_atom && lmp->atom->nmax > maxvatom_thr) {
- maxvatom_thr = lmp->atom->nmax;
- lmp->memory->grow(vatom_thr,nthreads,maxeatom_thr,6,"thr_omp:vatom_thr");
- }
+ case THR_DIHEDRAL:
+
+ if (evflag) {
+ Dihedral * const dihedral = lmp->force->dihedral;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ dihedral->energy += thr->eng_dihed;
+ for (int i=0; i < 6; ++i)
+ dihedral->virial[i] += thr->virial_dihed[i];
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(dihedral->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(dihedral->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+ break;
- int ntotal = (lmp->force->newton) ?
- (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
+ case THR_DIHEDRAL|THR_CHARMM: // special case for CHARMM dihedrals
+
+ if (evflag) {
+ Dihedral * const dihedral = lmp->force->dihedral;
+ Pair * const pair = lmp->force->pair;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ if (eflag & 1) {
+ dihedral->energy += thr->eng_dihed;
+ pair->eng_vdwl += thr->eng_vdwl;
+ pair->eng_coul += thr->eng_coul;
+ }
+
+ if (vflag & 3) {
+ for (int i=0; i < 6; ++i) {
+ dihedral->virial[i] += thr->virial_dihed[i];
+ pair->virial[i] += thr->virial_pair[i];
+ }
+ }
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(dihedral->eatom[0]), nall, nthreads, 1, tid);
+ data_reduce_thr(&(pair->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(dihedral->vatom[0][0]), nall, nthreads, 6, tid);
+ data_reduce_thr(&(pair->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+ break;
+
+ case THR_IMPROPER:
+
+ if (evflag) {
+ Improper *improper = lmp->force->improper;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ improper->energy += thr->eng_imprp;
+ for (int i=0; i < 6; ++i)
+ improper->virial[i] += thr->virial_imprp[i];
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(improper->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(improper->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+ break;
+
+ case THR_KSPACE|THR_PROXY: // fallthrough
+ case THR_KSPACE:
+ // nothing to do (for now)
+#if 0
+ if (evflag) {
+ KSpace *kspace = lmp->force->kspace;
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+ {
+ kspace->energy += thr->eng_kspce;
+ for (int i=0; i < 6; ++i)
+ kspace->virial[i] += thr->virial_kspce[i];
+ }
+ if (eflag & 2) {
+ sync_threads();
+ data_reduce_thr(&(kspace->eatom[0]), nall, nthreads, 1, tid);
+ }
+ if (vflag & 4) {
+ sync_threads();
+ data_reduce_thr(&(kspace->vatom[0][0]), nall, nthreads, 6, tid);
+ }
+ }
+#endif
+ break;
- // set up per thread accumulators
- ev_setup_acc_thr(ntotal, pair->eflag_global, pair->vflag_global,
- pair->eflag_atom, pair->vflag_atom, nthreads);
+ default:
+ printf("tid:%d unhandled thr_style case %d\n", tid, thr_style);
+ break;
+ }
+
+ if (style == fix->last_omp_style) {
+ sync_threads();
+ data_reduce_thr(&(f[0][0]), nall, nthreads, 3, tid);
+ if (lmp->atom->torque)
+ data_reduce_thr(&(lmp->atom->torque[0][0]), nall, nthreads, 3, tid);
+ }
}
/* ----------------------------------------------------------------------
- reduce the per thread accumulated E/V data into the canonical accumulators.
+ tally eng_vdwl and eng_coul into per thread global and per-atom accumulators
------------------------------------------------------------------------- */
-void ThrOMP::ev_reduce_thr(Dihedral *dihed)
+
+void ThrOMP::e_tally_thr(Pair * const pair, const int i, const int j,
+ const int nlocal, const int newton_pair,
+ const double evdwl, const double ecoul, ThrData * const thr)
{
- int nthreads = lmp->comm->nthreads;
- int ntotal = (lmp->force->newton_bond) ?
- (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
-
- for (int n = 0; n < nthreads; ++n) {
- dihed->energy += eng_bond_thr[n];
- if (dihed->vflag_either) {
- dihed->virial[0] += virial_thr[n][0];
- dihed->virial[1] += virial_thr[n][1];
- dihed->virial[2] += virial_thr[n][2];
- dihed->virial[3] += virial_thr[n][3];
- dihed->virial[4] += virial_thr[n][4];
- dihed->virial[5] += virial_thr[n][5];
- if (dihed->vflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- dihed->vatom[i][0] += vatom_thr[n][i][0];
- dihed->vatom[i][1] += vatom_thr[n][i][1];
- dihed->vatom[i][2] += vatom_thr[n][i][2];
- dihed->vatom[i][3] += vatom_thr[n][i][3];
- dihed->vatom[i][4] += vatom_thr[n][i][4];
- dihed->vatom[i][5] += vatom_thr[n][i][5];
- }
+ if (pair->eflag_global) {
+ if (newton_pair) {
+ thr->eng_vdwl += evdwl;
+ thr->eng_coul += ecoul;
+ } else {
+ const double evdwlhalf = 0.5*evdwl;
+ const double ecoulhalf = 0.5*ecoul;
+ if (i < nlocal) {
+ thr->eng_vdwl += evdwlhalf;
+ thr->eng_coul += ecoulhalf;
}
- }
- if (dihed->eflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- dihed->eatom[i] += eatom_thr[n][i];
+ if (j < nlocal) {
+ thr->eng_vdwl += evdwlhalf;
+ thr->eng_coul += ecoulhalf;
}
}
}
+ if (pair->eflag_atom) {
+ const double epairhalf = 0.5 * (evdwl + ecoul);
+ if (newton_pair || i < nlocal) thr->eatom_pair[i] += epairhalf;
+ if (newton_pair || j < nlocal) thr->eatom_pair[j] += epairhalf;
+ }
+}
+
+/* helper functions */
+static void v_tally(double * const vout, const double * const vin)
+{
+ vout[0] += vin[0];
+ vout[1] += vin[1];
+ vout[2] += vin[2];
+ vout[3] += vin[3];
+ vout[4] += vin[4];
+ vout[5] += vin[5];
+}
+
+static void v_tally(double * const vout, const double scale, const double * const vin)
+{
+ vout[0] += scale*vin[0];
+ vout[1] += scale*vin[1];
+ vout[2] += scale*vin[2];
+ vout[3] += scale*vin[3];
+ vout[4] += scale*vin[4];
+ vout[5] += scale*vin[5];
}
/* ----------------------------------------------------------------------
- reduce the per thread accumulated E/V data into the canonical accumulators.
+ tally virial into per thread global and per-atom accumulators
------------------------------------------------------------------------- */
-void ThrOMP::ev_reduce_thr(Pair *pair)
+void ThrOMP::v_tally_thr(Pair * const pair, const int i, const int j,
+ const int nlocal, const int newton_pair,
+ const double * const v, ThrData * const thr)
{
- const int nthreads = lmp->comm->nthreads;
- const int ntotal = (lmp->force->newton) ?
- (lmp->atom->nlocal + lmp->atom->nghost) : lmp->atom->nlocal;
-
- for (int n = 0; n < nthreads; ++n) {
- pair->eng_vdwl += eng_vdwl_thr[n];
- pair->eng_coul += eng_coul_thr[n];
- if (pair->vflag_either) {
- pair->virial[0] += virial_thr[n][0];
- pair->virial[1] += virial_thr[n][1];
- pair->virial[2] += virial_thr[n][2];
- pair->virial[3] += virial_thr[n][3];
- pair->virial[4] += virial_thr[n][4];
- pair->virial[5] += virial_thr[n][5];
- if (pair->vflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- pair->vatom[i][0] += vatom_thr[n][i][0];
- pair->vatom[i][1] += vatom_thr[n][i][1];
- pair->vatom[i][2] += vatom_thr[n][i][2];
- pair->vatom[i][3] += vatom_thr[n][i][3];
- pair->vatom[i][4] += vatom_thr[n][i][4];
- pair->vatom[i][5] += vatom_thr[n][i][5];
- }
- }
+ if (pair->vflag_global) {
+ double * const va = thr->virial_pair;
+ if (newton_pair) {
+ v_tally(va,v);
+ } else {
+ if (i < nlocal) v_tally(va,0.5,v);
+ if (j < nlocal) v_tally(va,0.5,v);
}
- if (pair->eflag_atom) {
- for (int i = 0; i < ntotal; ++i) {
- pair->eatom[i] += eatom_thr[n][i];
- }
+ }
+
+ if (pair->vflag_atom) {
+ if (newton_pair || i < nlocal) {
+ double * const va = thr->vatom_pair[i];
+ v_tally(va,0.5,v);
+ }
+ if (newton_pair || j < nlocal) {
+ double * const va = thr->vatom_pair[j];
+ v_tally(va,0.5,v);
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into per thread global and per-atom accumulators
need i < nlocal test since called by bond_quartic and dihedral_charmm
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally_thr(Pair *pair, int i, int j, int nlocal,
- int newton_pair, double evdwl, double ecoul,
- double fpair, double delx, double dely,
- double delz, int tid)
+void ThrOMP::ev_tally_thr(Pair * const pair, const int i, const int j, const int nlocal,
+ const int newton_pair, const double evdwl, const double ecoul,
+ const double fpair, const double delx, const double dely,
+ const double delz, ThrData * const thr)
{
- double evdwlhalf,ecoulhalf,epairhalf,v[6];
- if (pair->eflag_either) {
- if (pair->eflag_global) {
- if (newton_pair) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
- } else {
- evdwlhalf = 0.5*evdwl;
- ecoulhalf = 0.5*ecoul;
- if (i < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- if (j < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- }
- }
- if (pair->eflag_atom) {
- epairhalf = 0.5 * (evdwl + ecoul);
- if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf;
- if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf;
- }
- }
+ if (pair->eflag_either)
+ e_tally_thr(pair, i, j, nlocal, newton_pair, evdwl, ecoul, thr);
if (pair->vflag_either) {
+ double v[6];
v[0] = delx*delx*fpair;
v[1] = dely*dely*fpair;
v[2] = delz*delz*fpair;
v[3] = delx*dely*fpair;
v[4] = delx*delz*fpair;
v[5] = dely*delz*fpair;
- if (pair->vflag_global) {
- if (newton_pair) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- } else {
- if (i < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- if (j < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- }
- }
-
- if (pair->vflag_atom) {
- if (newton_pair || i < nlocal) {
- vatom_thr[tid][i][0] += 0.5*v[0];
- vatom_thr[tid][i][1] += 0.5*v[1];
- vatom_thr[tid][i][2] += 0.5*v[2];
- vatom_thr[tid][i][3] += 0.5*v[3];
- vatom_thr[tid][i][4] += 0.5*v[4];
- vatom_thr[tid][i][5] += 0.5*v[5];
- }
- if (newton_pair || j < nlocal) {
- vatom_thr[tid][j][0] += 0.5*v[0];
- vatom_thr[tid][j][1] += 0.5*v[1];
- vatom_thr[tid][j][2] += 0.5*v[2];
- vatom_thr[tid][j][3] += 0.5*v[3];
- vatom_thr[tid][j][4] += 0.5*v[4];
- vatom_thr[tid][j][5] += 0.5*v[5];
- }
- }
+ v_tally_thr(pair, i, j, nlocal, newton_pair, v, thr);
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
for virial, have delx,dely,delz and fx,fy,fz
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally_xyz_thr(Pair *pair, int i, int j, int nlocal,
- int newton_pair, double evdwl, double ecoul,
- double fx, double fy, double fz,
- double delx, double dely, double delz, int tid)
+void ThrOMP::ev_tally_xyz_thr(Pair * const pair, const int i, const int j,
+ const int nlocal, const int newton_pair,
+ const double evdwl, const double ecoul,
+ const double fx, const double fy, const double fz,
+ const double delx, const double dely, const double delz,
+ ThrData * const thr)
{
- double evdwlhalf,ecoulhalf,epairhalf,v[6];
- if (pair->eflag_either) {
- if (pair->eflag_global) {
- if (newton_pair) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
- } else {
- evdwlhalf = 0.5*evdwl;
- ecoulhalf = 0.5*ecoul;
- if (i < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- if (j < nlocal) {
- eng_vdwl_thr[tid] += evdwlhalf;
- eng_coul_thr[tid] += ecoulhalf;
- }
- }
- }
- if (pair->eflag_atom) {
- epairhalf = 0.5 * (evdwl + ecoul);
- if (newton_pair || i < nlocal) eatom_thr[tid][i] += epairhalf;
- if (newton_pair || j < nlocal) eatom_thr[tid][j] += epairhalf;
- }
- }
+ if (pair->eflag_either)
+ e_tally_thr(pair, i, j, nlocal, newton_pair, evdwl, ecoul, thr);
if (pair->vflag_either) {
+ double v[6];
v[0] = delx*fx;
v[1] = dely*fy;
v[2] = delz*fz;
v[3] = delx*fy;
v[4] = delx*fz;
v[5] = dely*fz;
- if (pair->vflag_global) {
- if (newton_pair) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- } else {
- if (i < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- if (j < nlocal) {
- virial_thr[tid][0] += 0.5*v[0];
- virial_thr[tid][1] += 0.5*v[1];
- virial_thr[tid][2] += 0.5*v[2];
- virial_thr[tid][3] += 0.5*v[3];
- virial_thr[tid][4] += 0.5*v[4];
- virial_thr[tid][5] += 0.5*v[5];
- }
- }
- }
-
- if (pair->vflag_atom) {
- if (newton_pair || i < nlocal) {
- vatom_thr[tid][i][0] += 0.5*v[0];
- vatom_thr[tid][i][1] += 0.5*v[1];
- vatom_thr[tid][i][2] += 0.5*v[2];
- vatom_thr[tid][i][3] += 0.5*v[3];
- vatom_thr[tid][i][4] += 0.5*v[4];
- vatom_thr[tid][i][5] += 0.5*v[5];
- }
- if (newton_pair || j < nlocal) {
- vatom_thr[tid][j][0] += 0.5*v[0];
- vatom_thr[tid][j][1] += 0.5*v[1];
- vatom_thr[tid][j][2] += 0.5*v[2];
- vatom_thr[tid][j][3] += 0.5*v[3];
- vatom_thr[tid][j][4] += 0.5*v[4];
- vatom_thr[tid][j][5] += 0.5*v[5];
- }
- }
+ v_tally_thr(pair, i, j, nlocal, newton_pair, v, thr);
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
called by SW and hbond potentials, newton_pair is always on
virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally3_thr(Pair *pair, int i, int j, int k, double evdwl, double ecoul,
- double *fj, double *fk, double *drji, double *drki, int tid)
+void ThrOMP::ev_tally3_thr(Pair * const pair, const int i, const int j, const int k,
+ const double evdwl, const double ecoul,
+ const double * const fj, const double * const fk,
+ const double * const drji, const double * const drki,
+ ThrData * const thr)
{
- double epairthird,v[6];
-
if (pair->eflag_either) {
if (pair->eflag_global) {
- eng_vdwl_thr[tid] += evdwl;
- eng_coul_thr[tid] += ecoul;
+ thr->eng_vdwl += evdwl;
+ thr->eng_coul += ecoul;
}
if (pair->eflag_atom) {
- epairthird = THIRD * (evdwl + ecoul);
- eatom_thr[tid][i] += epairthird;
- eatom_thr[tid][j] += epairthird;
- eatom_thr[tid][k] += epairthird;
+ const double epairthird = THIRD * (evdwl + ecoul);
+ thr->eatom_pair[i] += epairthird;
+ thr->eatom_pair[j] += epairthird;
+ thr->eatom_pair[k] += epairthird;
}
}
if (pair->vflag_either) {
+ double v[6];
+
v[0] = drji[0]*fj[0] + drki[0]*fk[0];
v[1] = drji[1]*fj[1] + drki[1]*fk[1];
v[2] = drji[2]*fj[2] + drki[2]*fk[2];
v[3] = drji[0]*fj[1] + drki[0]*fk[1];
v[4] = drji[0]*fj[2] + drki[0]*fk[2];
v[5] = drji[1]*fj[2] + drki[1]*fk[2];
- if (pair->vflag_global) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- }
+ if (pair->vflag_global) v_tally(thr->virial_pair,v);
if (pair->vflag_atom) {
- for (int n=0; n < 6; ++n) {
- vatom_thr[tid][i][n] += THIRD*v[n];
- vatom_thr[tid][j][n] += THIRD*v[n];
- vatom_thr[tid][k][n] += THIRD*v[n];
- }
+ v_tally(thr->vatom_pair[i],THIRD,v);
+ v_tally(thr->vatom_pair[j],THIRD,v);
+ v_tally(thr->vatom_pair[k],THIRD,v);
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
called by AIREBO potential, newton_pair is always on
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally4_thr(Pair *pair, int i, int j, int k, int m, double evdwl,
- double *fi, double *fj, double *fk,
- double *drim, double *drjm, double *drkm,int tid)
+void ThrOMP::ev_tally4_thr(Pair * const pair, const int i, const int j,
+ const int k, const int m, const double evdwl,
+ const double * const fi, const double * const fj,
+ const double * const fk, const double * const drim,
+ const double * const drjm, const double * const drkm,
+ ThrData * const thr)
{
- double epairfourth,v[6];
+ double v[6];
if (pair->eflag_either) {
- if (pair->eflag_global) eng_vdwl_thr[tid] += evdwl;
+ if (pair->eflag_global) thr->eng_vdwl += evdwl;
if (pair->eflag_atom) {
- epairfourth = 0.25 * evdwl;
- eatom_thr[tid][i] += epairfourth;
- eatom_thr[tid][j] += epairfourth;
- eatom_thr[tid][k] += epairfourth;
- eatom_thr[tid][m] += epairfourth;
+ const double epairfourth = 0.25 * evdwl;
+ thr->eatom_pair[i] += epairfourth;
+ thr->eatom_pair[j] += epairfourth;
+ thr->eatom_pair[k] += epairfourth;
+ thr->eatom_pair[m] += epairfourth;
}
}
if (pair->vflag_atom) {
v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
- vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
- vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
- vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2];
- vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
+ v_tally(thr->vatom_pair[i],v);
+ v_tally(thr->vatom_pair[j],v);
+ v_tally(thr->vatom_pair[k],v);
+ v_tally(thr->vatom_pair[m],v);
}
}
/* ----------------------------------------------------------------------
tally ecoul and virial into each of n atoms in list
called by TIP4P potential, newton_pair is always on
changes v values by dividing by n
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally_list_thr(Pair *pair, int n, int *list, double ecoul, double *v, int tid)
+void ThrOMP::ev_tally_list_thr(Pair * const pair, const int n,
+ const int * const list, const double ecoul,
+ const double * const v, ThrData * const thr)
{
- int i,j;
-
if (pair->eflag_either) {
- if (pair->eflag_global) eng_coul_thr[tid] += ecoul;
+ if (pair->eflag_global) thr->eng_coul += ecoul;
if (pair->eflag_atom) {
- double epairatom = ecoul/n;
- for (i = 0; i < n; i++) eatom_thr[tid][list[i]] += epairatom;
+ double epairatom = ecoul/static_cast<double>(n);
+ for (int i = 0; i < n; i++) thr->eatom_pair[list[i]] += epairatom;
}
}
if (pair->vflag_either) {
- if (pair->vflag_global) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
- }
+ if (pair->vflag_global)
+ v_tally(thr->virial_pair,v);
if (pair->vflag_atom) {
- v[0] /= n;
- v[1] /= n;
- v[2] /= n;
- v[3] /= n;
- v[4] /= n;
- v[5] /= n;
- for (i = 0; i < n; i++) {
- j = list[i];
- vatom_thr[tid][j][0] += v[0];
- vatom_thr[tid][j][1] += v[1];
- vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3];
- vatom_thr[tid][j][4] += v[4];
- vatom_thr[tid][j][5] += v[5];
+ const double s = 1.0/static_cast<double>(n);
+ double vtmp[6];
+
+ vtmp[0] = s * v[0];
+ vtmp[1] = s * v[1];
+ vtmp[2] = s * v[2];
+ vtmp[3] = s * v[3];
+ vtmp[4] = s * v[4];
+ vtmp[5] = s * v[5];
+
+ for (int i = 0; i < n; i++) {
+ const int j = list[i];
+ v_tally(thr->vatom_pair[j],vtmp);
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally_thr(Bond * const bond, const int i, const int j, const int nlocal,
+ const int newton_bond, const double ebond, const double fbond,
+ const double delx, const double dely, const double delz,
+ ThrData * const thr)
+{
+ if (bond->eflag_either) {
+ const double ebondhalf = 0.5*ebond;
+ if (newton_bond) {
+ if (bond->eflag_global)
+ thr->eng_bond += ebond;
+ if (bond->eflag_atom) {
+ thr->eatom_bond[i] += ebondhalf;
+ thr->eatom_bond[j] += ebondhalf;
+ }
+ } else {
+ if (bond->eflag_global) {
+ if (i < nlocal) thr->eng_bond += ebondhalf;
+ if (j < nlocal) thr->eng_bond += ebondhalf;
+ }
+ if (bond->eflag_atom) {
+ if (i < nlocal) thr->eatom_bond[i] += ebondhalf;
+ if (j < nlocal) thr->eatom_bond[j] += ebondhalf;
+ }
+ }
+ }
+
+ if (bond->vflag_either) {
+ double v[6];
+
+ v[0] = delx*delx*fbond;
+ v[1] = dely*dely*fbond;
+ v[2] = delz*delz*fbond;
+ v[3] = delx*dely*fbond;
+ v[4] = delx*delz*fbond;
+ v[5] = dely*delz*fbond;
+
+ if (bond->vflag_global) {
+ if (newton_bond)
+ v_tally(thr->virial_bond,v);
+ else {
+ if (i < nlocal)
+ v_tally(thr->virial_bond,0.5,v);
+ if (j < nlocal)
+ v_tally(thr->virial_bond,0.5,v);
+ }
+ }
+
+ if (bond->vflag_atom) {
+ v[0] *= 0.5;
+ v[1] *= 0.5;
+ v[2] *= 0.5;
+ v[3] *= 0.5;
+ v[4] *= 0.5;
+ v[5] *= 0.5;
+
+ if (newton_bond) {
+ v_tally(thr->vatom_bond[i],v);
+ v_tally(thr->vatom_bond[j],v);
+ } else {
+ if (j < nlocal)
+ v_tally(thr->vatom_bond[i],v);
+ if (j < nlocal)
+ v_tally(thr->vatom_bond[j],v);
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+ virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3
+------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally_thr(Angle * const angle, const int i, const int j, const int k,
+ const int nlocal, const int newton_bond, const double eangle,
+ const double * const f1, const double * const f3,
+ const double delx1, const double dely1, const double delz1,
+ const double delx2, const double dely2, const double delz2,
+ ThrData * const thr)
+{
+ if (angle->eflag_either) {
+ const double eanglethird = THIRD*eangle;
+ if (newton_bond) {
+ if (angle->eflag_global)
+ thr->eng_angle += eangle;
+ if (angle->eflag_atom) {
+ thr->eatom_angle[i] += eanglethird;
+ thr->eatom_angle[j] += eanglethird;
+ thr->eatom_angle[k] += eanglethird;
}
+ } else {
+ if (angle->eflag_global) {
+ if (i < nlocal) thr->eng_angle += eanglethird;
+ if (j < nlocal) thr->eng_angle += eanglethird;
+ if (k < nlocal) thr->eng_angle += eanglethird;
+ }
+ if (angle->eflag_atom) {
+ if (i < nlocal) thr->eatom_angle[i] += eanglethird;
+ if (j < nlocal) thr->eatom_angle[j] += eanglethird;
+ if (k < nlocal) thr->eatom_angle[k] += eanglethird;
+ }
+ }
+ }
+
+ if (angle->vflag_either) {
+ double v[6];
+
+ v[0] = delx1*f1[0] + delx2*f3[0];
+ v[1] = dely1*f1[1] + dely2*f3[1];
+ v[2] = delz1*f1[2] + delz2*f3[2];
+ v[3] = delx1*f1[1] + delx2*f3[1];
+ v[4] = delx1*f1[2] + delx2*f3[2];
+ v[5] = dely1*f1[2] + dely2*f3[2];
+
+ if (angle->vflag_global) {
+ if (newton_bond) {
+ v_tally(thr->virial_angle,v);
+ } else {
+ int cnt = 0;
+ if (i < nlocal) ++cnt;
+ if (j < nlocal) ++cnt;
+ if (k < nlocal) ++cnt;
+ v_tally(thr->virial_angle,cnt*THIRD,v);
+ }
+ }
+
+ if (angle->vflag_atom) {
+ v[0] *= THIRD;
+ v[1] *= THIRD;
+ v[2] *= THIRD;
+ v[3] *= THIRD;
+ v[4] *= THIRD;
+ v[5] *= THIRD;
+
+ if (newton_bond) {
+ v_tally(thr->vatom_angle[i],v);
+ v_tally(thr->vatom_angle[j],v);
+ v_tally(thr->vatom_angle[k],v);
+ } else {
+ if (j < nlocal) v_tally(thr->vatom_angle[i],v);
+ if (j < nlocal) v_tally(thr->vatom_angle[j],v);
+ if (k < nlocal) v_tally(thr->vatom_angle[k],v);
+ }
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial from 1-3 repulsion of SDK angle into accumulators
+------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally13_thr(Angle * const angle, const int i1, const int i3,
+ const int nlocal, const int newton_bond,
+ const double epair, const double fpair,
+ const double delx, const double dely,
+ const double delz, ThrData * const thr)
+{
+
+ if (angle->eflag_either) {
+ const double epairhalf = 0.5 * epair;
+
+ if (angle->eflag_global) {
+ if (newton_bond || i1 < nlocal)
+ thr->eng_angle += epairhalf;
+ if (newton_bond || i3 < nlocal)
+ thr->eng_angle += epairhalf;
+ }
+
+ if (angle->eflag_atom) {
+ if (newton_bond || i1 < nlocal) thr->eatom_angle[i1] += epairhalf;
+ if (newton_bond || i3 < nlocal) thr->eatom_angle[i3] += epairhalf;
}
}
+
+ if (angle->vflag_either) {
+ double v[6];
+ v[0] = delx*delx*fpair;
+ v[1] = dely*dely*fpair;
+ v[2] = delz*delz*fpair;
+ v[3] = delx*dely*fpair;
+ v[4] = delx*delz*fpair;
+ v[5] = dely*delz*fpair;
+
+ if (angle->vflag_global) {
+ double * const va = thr->virial_angle;
+ if (newton_bond || i1 < nlocal) v_tally(va,0.5,v);
+ if (newton_bond || i3 < nlocal) v_tally(va,0.5,v);
+ }
+
+ if (angle->vflag_atom) {
+ if (newton_bond || i1 < nlocal) {
+ double * const va = thr->vatom_angle[i1];
+ v_tally(va,0.5,v);
+ }
+ if (newton_bond || i3 < nlocal) {
+ double * const va = thr->vatom_angle[i3];
+ v_tally(va,0.5,v);
+ }
+ }
+ }
}
+
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4
= (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4
= vb1*f1 + vb2*f3 + (vb3+vb2)*f4
------------------------------------------------------------------------- */
-void ThrOMP::ev_tally_thr(Dihedral *dihed, int i1, int i2, int i3, int i4,
- int nlocal, int newton_bond,
- double edihedral, double *f1, double *f3, double *f4,
- double vb1x, double vb1y, double vb1z,
- double vb2x, double vb2y, double vb2z,
- double vb3x, double vb3y, double vb3z, int tid)
+void ThrOMP::ev_tally_thr(Dihedral * const dihed, const int i1, const int i2,
+ const int i3, const int i4, const int nlocal,
+ const int newton_bond, const double edihedral,
+ const double * const f1, const double * const f3,
+ const double * const f4, const double vb1x,
+ const double vb1y, const double vb1z, const double vb2x,
+ const double vb2y, const double vb2z, const double vb3x,
+ const double vb3y, const double vb3z, ThrData * const thr)
{
- double edihedralquarter,v[6];
- int cnt;
if (dihed->eflag_either) {
if (dihed->eflag_global) {
if (newton_bond) {
- eng_bond_thr[tid] += edihedral;
+ thr->eng_dihed += edihedral;
} else {
- edihedralquarter = 0.25*edihedral;
- cnt = 0;
+ const double edihedralquarter = 0.25*edihedral;
+ int cnt = 0;
if (i1 < nlocal) ++cnt;
if (i2 < nlocal) ++cnt;
if (i3 < nlocal) ++cnt;
if (i4 < nlocal) ++cnt;
- eng_bond_thr[tid] += static_cast<double>(cnt) * edihedralquarter;
+ thr->eng_dihed += static_cast<double>(cnt)*edihedralquarter;
}
}
if (dihed->eflag_atom) {
- edihedralquarter = 0.25*edihedral;
- if (newton_bond || i1 < nlocal) eatom_thr[tid][i1] += edihedralquarter;
- if (newton_bond || i2 < nlocal) eatom_thr[tid][i2] += edihedralquarter;
- if (newton_bond || i3 < nlocal) eatom_thr[tid][i3] += edihedralquarter;
- if (newton_bond || i4 < nlocal) eatom_thr[tid][i4] += edihedralquarter;
+ const double edihedralquarter = 0.25*edihedral;
+ if (newton_bond) {
+ thr->eatom_dihed[i1] += edihedralquarter;
+ thr->eatom_dihed[i2] += edihedralquarter;
+ thr->eatom_dihed[i3] += edihedralquarter;
+ thr->eatom_dihed[i4] += edihedralquarter;
+ } else {
+ if (i1 < nlocal) thr->eatom_dihed[i1] += edihedralquarter;
+ if (i2 < nlocal) thr->eatom_dihed[i2] += edihedralquarter;
+ if (i3 < nlocal) thr->eatom_dihed[i3] += edihedralquarter;
+ if (i4 < nlocal) thr->eatom_dihed[i4] += edihedralquarter;
+ }
}
}
if (dihed->vflag_either) {
+ double v[6];
v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0];
v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1];
v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2];
v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1];
v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2];
v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2];
if (dihed->vflag_global) {
if (newton_bond) {
- virial_thr[tid][0] += v[0];
- virial_thr[tid][1] += v[1];
- virial_thr[tid][2] += v[2];
- virial_thr[tid][3] += v[3];
- virial_thr[tid][4] += v[4];
- virial_thr[tid][5] += v[5];
+ v_tally(thr->virial_dihed,v);
} else {
- if (i1 < nlocal) {
- virial_thr[tid][0] += 0.25*v[0];
- virial_thr[tid][1] += 0.25*v[1];
- virial_thr[tid][2] += 0.25*v[2];
- virial_thr[tid][3] += 0.25*v[3];
- virial_thr[tid][4] += 0.25*v[4];
- virial_thr[tid][5] += 0.25*v[5];
- }
- if (i2 < nlocal) {
- virial_thr[tid][0] += 0.25*v[0];
- virial_thr[tid][1] += 0.25*v[1];
- virial_thr[tid][2] += 0.25*v[2];
- virial_thr[tid][3] += 0.25*v[3];
- virial_thr[tid][4] += 0.25*v[4];
- virial_thr[tid][5] += 0.25*v[5];
- }
- if (i3 < nlocal) {
- virial_thr[tid][0] += 0.25*v[0];
- virial_thr[tid][1] += 0.25*v[1];
- virial_thr[tid][2] += 0.25*v[2];
- virial_thr[tid][3] += 0.25*v[3];
- virial_thr[tid][4] += 0.25*v[4];
- virial_thr[tid][5] += 0.25*v[5];
- }
- if (i4 < nlocal) {
- virial_thr[tid][0] += 0.25*v[0];
- virial_thr[tid][1] += 0.25*v[1];
- virial_thr[tid][2] += 0.25*v[2];
- virial_thr[tid][3] += 0.25*v[3];
- virial_thr[tid][4] += 0.25*v[4];
- virial_thr[tid][5] += 0.25*v[5];
- }
+ int cnt = 0;
+ if (i1 < nlocal) ++cnt;
+ if (i2 < nlocal) ++cnt;
+ if (i3 < nlocal) ++cnt;
+ if (i4 < nlocal) ++cnt;
+ v_tally(thr->virial_dihed,0.25*static_cast<double>(cnt),v);
}
}
+ v[0] *= 0.25;
+ v[1] *= 0.25;
+ v[2] *= 0.25;
+ v[3] *= 0.25;
+ v[4] *= 0.25;
+ v[5] *= 0.25;
+
if (dihed->vflag_atom) {
- if (newton_bond || i1 < nlocal) {
- vatom_thr[tid][i1][0] += 0.25*v[0];
- vatom_thr[tid][i1][1] += 0.25*v[1];
- vatom_thr[tid][i1][2] += 0.25*v[2];
- vatom_thr[tid][i1][3] += 0.25*v[3];
- vatom_thr[tid][i1][4] += 0.25*v[4];
- vatom_thr[tid][i1][5] += 0.25*v[5];
- }
- if (newton_bond || i2 < nlocal) {
- vatom_thr[tid][i2][0] += 0.25*v[0];
- vatom_thr[tid][i2][1] += 0.25*v[1];
- vatom_thr[tid][i2][2] += 0.25*v[2];
- vatom_thr[tid][i2][3] += 0.25*v[3];
- vatom_thr[tid][i2][4] += 0.25*v[4];
- vatom_thr[tid][i2][5] += 0.25*v[5];
+ if (newton_bond) {
+ v_tally(thr->vatom_dihed[i1],v);
+ v_tally(thr->vatom_dihed[i2],v);
+ v_tally(thr->vatom_dihed[i3],v);
+ v_tally(thr->vatom_dihed[i4],v);
+ } else {
+ if (i1 < nlocal) v_tally(thr->vatom_dihed[i1],v);
+ if (i2 < nlocal) v_tally(thr->vatom_dihed[i2],v);
+ if (i3 < nlocal) v_tally(thr->vatom_dihed[i3],v);
+ if (i4 < nlocal) v_tally(thr->vatom_dihed[i4],v);
}
- if (newton_bond || i3 < nlocal) {
- vatom_thr[tid][i3][0] += 0.25*v[0];
- vatom_thr[tid][i3][1] += 0.25*v[1];
- vatom_thr[tid][i3][2] += 0.25*v[2];
- vatom_thr[tid][i3][3] += 0.25*v[3];
- vatom_thr[tid][i3][4] += 0.25*v[4];
- vatom_thr[tid][i3][5] += 0.25*v[5];
- }
- if (newton_bond || i4 < nlocal) {
- vatom_thr[tid][i4][0] += 0.25*v[0];
- vatom_thr[tid][i4][1] += 0.25*v[1];
- vatom_thr[tid][i4][2] += 0.25*v[2];
- vatom_thr[tid][i4][3] += 0.25*v[3];
- vatom_thr[tid][i4][4] += 0.25*v[4];
- vatom_thr[tid][i4][5] += 0.25*v[5];
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ tally energy and virial into global and per-atom accumulators
+ virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4
+ = (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4
+ = vb1*f1 + vb2*f3 + (vb3+vb2)*f4
+------------------------------------------------------------------------- */
+
+void ThrOMP::ev_tally_thr(Improper * const imprp, const int i1, const int i2,
+ const int i3, const int i4, const int nlocal,
+ const int newton_bond, const double eimproper,
+ const double * const f1, const double * const f3,
+ const double * const f4, const double vb1x,
+ const double vb1y, const double vb1z, const double vb2x,
+ const double vb2y, const double vb2z, const double vb3x,
+ const double vb3y, const double vb3z, ThrData * const thr)
+{
+
+ if (imprp->eflag_either) {
+ if (imprp->eflag_global) {
+ if (newton_bond) {
+ thr->eng_imprp += eimproper;
+ } else {
+ const double eimproperquarter = 0.25*eimproper;
+ int cnt = 0;
+ if (i1 < nlocal) ++cnt;
+ if (i2 < nlocal) ++cnt;
+ if (i3 < nlocal) ++cnt;
+ if (i4 < nlocal) ++cnt;
+ thr->eng_imprp += static_cast<double>(cnt)*eimproperquarter;
+ }
+ }
+ if (imprp->eflag_atom) {
+ const double eimproperquarter = 0.25*eimproper;
+ if (newton_bond) {
+ thr->eatom_imprp[i1] += eimproperquarter;
+ thr->eatom_imprp[i2] += eimproperquarter;
+ thr->eatom_imprp[i3] += eimproperquarter;
+ thr->eatom_imprp[i4] += eimproperquarter;
+ } else {
+ if (i1 < nlocal) thr->eatom_imprp[i1] += eimproperquarter;
+ if (i2 < nlocal) thr->eatom_imprp[i2] += eimproperquarter;
+ if (i3 < nlocal) thr->eatom_imprp[i3] += eimproperquarter;
+ if (i4 < nlocal) thr->eatom_imprp[i4] += eimproperquarter;
+ }
+ }
+ }
+
+ if (imprp->vflag_either) {
+ double v[6];
+ v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0];
+ v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1];
+ v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2];
+ v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1];
+ v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2];
+ v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2];
+
+ if (imprp->vflag_global) {
+ if (newton_bond) {
+ v_tally(thr->virial_imprp,v);
+ } else {
+ int cnt = 0;
+ if (i1 < nlocal) ++cnt;
+ if (i2 < nlocal) ++cnt;
+ if (i3 < nlocal) ++cnt;
+ if (i4 < nlocal) ++cnt;
+ v_tally(thr->virial_imprp,0.25*static_cast<double>(cnt),v);
+ }
+ }
+
+ v[0] *= 0.25;
+ v[1] *= 0.25;
+ v[2] *= 0.25;
+ v[3] *= 0.25;
+ v[4] *= 0.25;
+ v[5] *= 0.25;
+
+ if (imprp->vflag_atom) {
+ if (newton_bond) {
+ v_tally(thr->vatom_imprp[i1],v);
+ v_tally(thr->vatom_imprp[i2],v);
+ v_tally(thr->vatom_imprp[i3],v);
+ v_tally(thr->vatom_imprp[i4],v);
+ } else {
+ if (i1 < nlocal) v_tally(thr->vatom_imprp[i1],v);
+ if (i2 < nlocal) v_tally(thr->vatom_imprp[i2],v);
+ if (i3 < nlocal) v_tally(thr->vatom_imprp[i3],v);
+ if (i4 < nlocal) v_tally(thr->vatom_imprp[i4],v);
}
}
}
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO potential, newton_pair is always on
fpair is magnitude of force on atom I
------------------------------------------------------------------------- */
-void ThrOMP::v_tally2_thr(int i, int j, double fpair, double *drij, int tid)
+void ThrOMP::v_tally2_thr(const int i, const int j, const double fpair,
+ const double * const drij, ThrData * const thr)
{
double v[6];
v[0] = 0.5 * drij[0]*drij[0]*fpair;
v[1] = 0.5 * drij[1]*drij[1]*fpair;
v[2] = 0.5 * drij[2]*drij[2]*fpair;
v[3] = 0.5 * drij[0]*drij[1]*fpair;
v[4] = 0.5 * drij[0]*drij[2]*fpair;
v[5] = 0.5 * drij[1]*drij[2]*fpair;
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
- vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
+ v_tally(thr->vatom_pair[i],v);
+ v_tally(thr->vatom_pair[j],v);
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO and Tersoff potential, newton_pair is always on
------------------------------------------------------------------------- */
-void ThrOMP::v_tally3_thr(int i, int j, int k, double *fi, double *fj,
- double *drik, double *drjk, int tid)
+void ThrOMP::v_tally3_thr(const int i, const int j, const int k,
+ const double * const fi, const double * const fj,
+ const double * const drik, const double * const drjk,
+ ThrData * const thr)
{
double v[6];
v[0] = THIRD * (drik[0]*fi[0] + drjk[0]*fj[0]);
v[1] = THIRD * (drik[1]*fi[1] + drjk[1]*fj[1]);
v[2] = THIRD * (drik[2]*fi[2] + drjk[2]*fj[2]);
v[3] = THIRD * (drik[0]*fi[1] + drjk[0]*fj[1]);
v[4] = THIRD * (drik[0]*fi[2] + drjk[0]*fj[2]);
v[5] = THIRD * (drik[1]*fi[2] + drjk[1]*fj[2]);
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
- vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
- vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
+ v_tally(thr->vatom_pair[i],v);
+ v_tally(thr->vatom_pair[j],v);
+ v_tally(thr->vatom_pair[k],v);
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO potential, newton_pair is always on
------------------------------------------------------------------------- */
-void ThrOMP::v_tally4_thr(int i, int j, int k, int m,
- double *fi, double *fj, double *fk,
- double *drim, double *drjm, double *drkm, int tid)
+void ThrOMP::v_tally4_thr(const int i, const int j, const int k, const int m,
+ const double * const fi, const double * const fj,
+ const double * const fk, const double * const drim,
+ const double * const drjm, const double * const drkm,
+ ThrData * const thr)
{
double v[6];
v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
- vatom_thr[tid][i][0] += v[0]; vatom_thr[tid][i][1] += v[1]; vatom_thr[tid][i][2] += v[2];
- vatom_thr[tid][i][3] += v[3]; vatom_thr[tid][i][4] += v[4]; vatom_thr[tid][i][5] += v[5];
- vatom_thr[tid][j][0] += v[0]; vatom_thr[tid][j][1] += v[1]; vatom_thr[tid][j][2] += v[2];
- vatom_thr[tid][j][3] += v[3]; vatom_thr[tid][j][4] += v[4]; vatom_thr[tid][j][5] += v[5];
- vatom_thr[tid][k][0] += v[0]; vatom_thr[tid][k][1] += v[1]; vatom_thr[tid][k][2] += v[2];
- vatom_thr[tid][k][3] += v[3]; vatom_thr[tid][k][4] += v[4]; vatom_thr[tid][k][5] += v[5];
- vatom_thr[tid][m][0] += v[0]; vatom_thr[tid][m][1] += v[1]; vatom_thr[tid][m][2] += v[2];
- vatom_thr[tid][m][3] += v[3]; vatom_thr[tid][m][4] += v[4]; vatom_thr[tid][m][5] += v[5];
-}
-
-/* ---------------------------------------------------------------------- */
-
-// set loop range thread id, and force array offset for threaded runs.
-double **ThrOMP::loop_setup_thr(double **f, int &ifrom, int &ito, int &tid,
- int inum, int nall, int nthreads)
-{
-#if defined(_OPENMP)
- tid = omp_get_thread_num();
-
- // each thread works on a fixed chunk of atoms.
- const int idelta = 1 + inum/nthreads;
- ifrom = tid*idelta;
- ito = ifrom + idelta;
- if (ito > inum)
- ito = inum;
-
- return f + nall*tid;
-#else
- tid = 0;
- ifrom = 0;
- ito = inum;
- return f;
-#endif
-}
-
-/* ---------------------------------------------------------------------- */
-
-// reduce per thread data into the first part of the data
-// array that is used for the non-threaded parts and reset
-// the temporary storage to 0.0. this routine depends on
-// multi-dimensional arrays like force stored in this order
-// x1,y1,z1,x2,y2,z2,...
-// we need to post a barrier to wait until all threads are done
-// with writing to the array .
-void ThrOMP::data_reduce_thr(double *dall, int nall, int nthreads,
- int ndim, int tid)
-{
-#if defined(_OPENMP)
- // NOOP in non-threaded execution.
- if (nthreads == 1) return;
-#pragma omp barrier
- {
- const int nvals = ndim*nall;
- const int idelta = nvals/nthreads + 1;
- const int ifrom = tid*idelta;
- const int ito = ((ifrom + idelta) > nvals) ? nvals : (ifrom + idelta);
-
- for (int m = ifrom; m < ito; ++m) {
- for (int n = 1; n < nthreads; ++n) {
- dall[m] += dall[n*nvals + m];
- dall[n*nvals + m] = 0.0;
- }
- }
- }
-#else
- // NOOP in non-threaded execution.
- return;
-#endif
+ v_tally(thr->vatom_pair[i],v);
+ v_tally(thr->vatom_pair[j],v);
+ v_tally(thr->vatom_pair[k],v);
+ v_tally(thr->vatom_pair[m],v);
}
/* ---------------------------------------------------------------------- */
double ThrOMP::memory_usage_thr()
{
- const int nthreads=lmp->comm->nthreads;
-
- double bytes = nthreads * (3 + 7) * sizeof(double);
- bytes += nthreads * maxeatom_thr * sizeof(double);
- bytes += nthreads * maxvatom_thr * 6 * sizeof(double);
+ double bytes=0.0;
+
return bytes;
}
diff --git a/src/USER-OMP/thr_omp.h b/src/USER-OMP/thr_omp.h
index 9966c9de0..32f704512 100644
--- a/src/USER-OMP/thr_omp.h
+++ b/src/USER-OMP/thr_omp.h
@@ -1,114 +1,158 @@
/* -*- c++ -*- -------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifndef LMP_THR_OMP_H
#define LMP_THR_OMP_H
#include "pointers.h"
+#include "fix_omp.h"
+#include "thr_data.h"
namespace LAMMPS_NS {
// forward declarations
class Pair;
+class Bond;
+class Angle;
class Dihedral;
+class Improper;
+class KSpace;
+class Fix;
class ThrOMP {
- public:
- struct global {
- double eng_vdwl;
- double eng_coul;
- double eng_bond;
- double virial[6];
- };
protected:
- const int thr_style;
- enum {PAIR=1, BOND, ANGLE, DIHEDRAL, IMPROPER, KSPACE, FIX, COMPUTE};
-
- LAMMPS *lmp; // reference to base lammps object.
-
- double *eng_vdwl_thr; // per thread accumulated vdw energy
- double *eng_coul_thr; // per thread accumulated coulomb energies
- double *eng_bond_thr; // per thread accumlated bonded energy
+ LAMMPS *lmp; // reference to base lammps object.
+ FixOMP *fix; // pointer to fix_omp;
- double **virial_thr; // per thread virial
- double **eatom_thr; // per thread per atom energy
- double ***vatom_thr; // per thread per atom virial
+ const int thr_style;
- int maxeatom_thr, maxvatom_thr;
- int evflag_global, evflag_atom;
-
public:
ThrOMP(LAMMPS *, int);
virtual ~ThrOMP();
double memory_usage_thr();
inline void sync_threads() {
#if defined(_OPENMP)
#pragma omp barrier
#endif
{ ; }
};
+ enum {THR_NONE=0,THR_PAIR=1,THR_BOND=1<<1,THR_ANGLE=1<<2,
+ THR_DIHEDRAL=1<<3,THR_IMPROPER=1<<4,THR_KSPACE=1<<5,
+ THR_CHARMM=1<<6,THR_PROXY=1<<7,THR_HYBRID=1<<8,THR_FIX=1<<9};
+
protected:
- // extra ev_tally work for threaded styles
- void ev_setup_thr(Pair *);
- void ev_setup_thr(Dihedral *);
+ // extra ev_tally setup work for threaded styles
+ void ev_setup_thr(int, int, int, double *, double **, ThrData *);
- void ev_reduce_thr(Pair *);
- void ev_reduce_thr(Dihedral *);
+ // compute global per thread virial contribution from per-thread force
+ void virial_fdotr_compute_thr(double * const, const double * const * const,
+ const double * const * const,
+ const int, const int, const int);
- private:
- // internal method to be used by multiple ev_setup_thr() methods
- void ev_setup_acc_thr(int, int, int, int, int, int);
+ // reduce per thread data as needed
+ void reduce_thr(void * const style, const int eflag, const int vflag, ThrData * const thr, const int nproxy=0);
protected:
+
// threading adapted versions of the ev_tally infrastructure
// style specific versions (need access to style class flags)
- void ev_tally_thr(Pair *, int, int, int, int, double, double,
- double, double, double, double, int);
- void ev_tally_xyz_thr(Pair *, int, int, int, int, double, double,
- double, double, double, double, double, double, int);
- void ev_tally3_thr(Pair *, int, int, int, double, double,
- double *, double *, double *, double *, int);
- void ev_tally4_thr(Pair *, int, int, int, int, double,
- double *, double *, double *,
- double *, double *, double *, int);
- void ev_tally_list_thr(Pair *, int, int *, double , double *, int);
-
- void ev_tally_thr(Dihedral *, int, int, int, int, int, int, double,
- double *, double *, double *, double, double, double,
- double, double, double, double, double, double, int);
- // style independent versions
- void v_tally2_thr(int, int, double, double *, int);
- void v_tally3_thr(int, int, int, double *, double *, double *, double *, int);
- void v_tally4_thr(int, int, int, int, double *, double *, double *,
- double *, double *, double *, int);
+ // Pair
+ void e_tally_thr(Pair * const, const int, const int, const int,
+ const int, const double, const double, ThrData * const);
+ void v_tally_thr(Pair * const, const int, const int, const int,
+ const int, const double * const, ThrData * const);
+
+ void ev_tally_thr(Pair * const, const int, const int, const int, const int,
+ const double, const double, const double, const double,
+ const double, const double, ThrData * const);
+ void ev_tally_xyz_thr(Pair * const, const int, const int, const int,
+ const int, const double, const double, const double,
+ const double, const double, const double,
+ const double, const double, ThrData * const);
+ void ev_tally3_thr(Pair * const, const int, const int, const int, const double,
+ const double, const double * const, const double * const,
+ const double * const, const double * const, ThrData * const);
+ void ev_tally4_thr(Pair * const, const int, const int, const int, const int,
+ const double, const double * const, const double * const,
+ const double * const, const double * const, const double * const,
+ const double * const, ThrData * const);
+
+ // Bond
+ void ev_tally_thr(Bond * const, const int, const int, const int, const int,
+ const double, const double, const double, const double,
+ const double, ThrData * const);
+
+ // Angle
+ void ev_tally_thr(Angle * const, const int, const int, const int, const int, const int,
+ const double, const double * const, const double * const,
+ const double, const double, const double, const double, const double,
+ const double, ThrData * const thr);
+ void ev_tally13_thr(Angle * const, const int, const int, const int, const int,
+ const double, const double, const double, const double,
+ const double, ThrData * const thr);
+
+ // Dihedral
+ void ev_tally_thr(Dihedral * const, const int, const int, const int, const int, const int,
+ const int, const double, const double * const, const double * const,
+ const double * const, const double, const double, const double,
+ const double, const double, const double, const double, const double,
+ const double, ThrData * const);
+
+ // Improper
+ void ev_tally_thr(Improper * const, const int, const int, const int, const int, const int,
+ const int, const double, const double * const, const double * const,
+ const double * const, const double, const double, const double,
+ const double, const double, const double, const double, const double,
+ const double, ThrData * const);
- protected:
- // set loop range, thread id, and force array offset for threaded runs.
- double **loop_setup_thr(double **, int &, int &, int &, int, int, int);
-
- // reduce per thread data into the first part of the array
- void data_reduce_thr(double *, int, int, int, int);
+ // style independent versions
+ void v_tally2_thr(const int, const int, const double, const double * const, ThrData * const);
+ void v_tally3_thr(const int, const int, const int, const double * const, const double * const,
+ const double * const, const double * const, ThrData * const);
+ void v_tally4_thr(const int, const int, const int, const int, const double * const,
+ const double * const, const double * const, const double * const,
+ const double * const, const double * const, ThrData * const);
+ void ev_tally_list_thr(Pair * const, const int, const int * const,
+ const double , const double * const , ThrData * const);
};
+// set loop range thread id, and force array offset for threaded runs.
+static inline void loop_setup_thr(int &ifrom, int &ito, int &tid,
+ int inum, int nthreads, int nproxy=0)
+{
+#if defined(_OPENMP)
+ tid = omp_get_thread_num();
+
+ // each thread works on a fixed chunk of atoms.
+ const int idelta = 1 + inum/(nthreads-nproxy);
+ ifrom = (tid-nproxy)*idelta;
+ ito = ((ifrom + idelta) > inum) ? inum : ifrom + idelta;
+#else
+ tid = 0;
+ ifrom = 0;
+ ito = inum;
+#endif
+}
+
}
#endif
diff --git a/src/accelerator_omp.h b/src/accelerator_omp.h
new file mode 100644
index 000000000..5ad4277b9
--- /dev/null
+++ b/src/accelerator_omp.h
@@ -0,0 +1,92 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifndef LMP_ACCELERATOR_OMP_H
+#define LMP_ACCELERATOR_OMP_H
+
+// true interface to USER-OMP, used in Neighbor class header file
+// used when USER-OMP is installed
+
+#ifdef LMP_USER_OMP
+
+ void half_nsq_no_newton_omp(class NeighList *);
+ void half_nsq_newton_omp(class NeighList *);
+
+ void half_bin_no_newton_omp(class NeighList *);
+ void half_bin_newton_omp(class NeighList *);
+ void half_bin_newton_tri_omp(class NeighList *);
+
+ void half_multi_no_newton_omp(class NeighList *);
+ void half_multi_newton_omp(class NeighList *);
+ void half_multi_newton_tri_omp(class NeighList *);
+
+ void full_nsq_omp(class NeighList *);
+ void full_nsq_ghost_omp(class NeighList *);
+ void full_bin_omp(class NeighList *);
+ void full_bin_ghost_omp(class NeighList *);
+ void full_multi_omp(class NeighList *);
+
+ void half_from_full_no_newton_omp(class NeighList *);
+ void half_from_full_newton_omp(class NeighList *);
+
+ void granular_nsq_no_newton_omp(class NeighList *);
+ void granular_nsq_newton_omp(class NeighList *);
+ void granular_bin_no_newton_omp(class NeighList *);
+ void granular_bin_newton_omp(class NeighList *);
+ void granular_bin_newton_tri_omp(class NeighList *);
+
+ void respa_nsq_no_newton_omp(class NeighList *);
+ void respa_nsq_newton_omp(class NeighList *);
+ void respa_bin_no_newton_omp(class NeighList *);
+ void respa_bin_newton_omp(class NeighList *);
+ void respa_bin_newton_tri_omp(class NeighList *);
+
+#else
+
+// dummy interface to USER-OMP
+// needed for compiling Neighbor class when USER-OMP is not installed
+
+ void half_nsq_no_newton_omp(class NeighList *) {}
+ void half_nsq_newton_omp(class NeighList *) {}
+
+ void half_bin_no_newton_omp(class NeighList *) {}
+ void half_bin_newton_omp(class NeighList *) {}
+ void half_bin_newton_tri_omp(class NeighList *) {}
+
+ void half_multi_no_newton_omp(class NeighList *) {}
+ void half_multi_newton_omp(class NeighList *) {}
+ void half_multi_newton_tri_omp(class NeighList *) {}
+
+ void full_nsq_omp(class NeighList *) {}
+ void full_nsq_ghost_omp(class NeighList *) {}
+ void full_bin_omp(class NeighList *) {}
+ void full_bin_ghost_omp(class NeighList *) {}
+ void full_multi_omp(class NeighList *) {}
+
+ void half_from_full_no_newton_omp(class NeighList *) {}
+ void half_from_full_newton_omp(class NeighList *) {}
+
+ void granular_nsq_no_newton_omp(class NeighList *) {}
+ void granular_nsq_newton_omp(class NeighList *) {}
+ void granular_bin_no_newton_omp(class NeighList *) {}
+ void granular_bin_newton_omp(class NeighList *) {}
+ void granular_bin_newton_tri_omp(class NeighList *) {}
+
+ void respa_nsq_no_newton_omp(class NeighList *) {}
+ void respa_nsq_newton_omp(class NeighList *) {}
+ void respa_bin_no_newton_omp(class NeighList *) {}
+ void respa_bin_newton_omp(class NeighList *) {}
+ void respa_bin_newton_tri_omp(class NeighList *) {}
+
+#endif
+#endif
diff --git a/src/angle.cpp b/src/angle.cpp
index 54a3a5d05..709ace182 100644
--- a/src/angle.cpp
+++ b/src/angle.cpp
@@ -1,223 +1,225 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "angle.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
Angle::Angle(LAMMPS *lmp) : Pointers(lmp)
{
energy = 0.0;
allocated = 0;
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Angle::~Angle()
{
memory->destroy(eatom);
memory->destroy(vatom);
}
/* ----------------------------------------------------------------------
check if all coeffs are set
------------------------------------------------------------------------- */
void Angle::init()
{
if (!allocated) error->all(FLERR,"Angle coeffs are not set");
for (int i = 1; i <= atom->nangletypes; i++)
if (setflag[i] == 0) error->all(FLERR,"All angle coeffs are not set");
+
+ init_style();
}
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Angle::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->destroy(eatom);
memory->create(eatom,comm->nthreads*maxeatom,"bond:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy(vatom);
memory->create(vatom,comm->nthreads*maxvatom,6,"bond:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3
------------------------------------------------------------------------- */
void Angle::ev_tally(int i, int j, int k, int nlocal, int newton_bond,
double eangle, double *f1, double *f3,
double delx1, double dely1, double delz1,
double delx2, double dely2, double delz2)
{
double eanglethird,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) energy += eangle;
else {
eanglethird = THIRD*eangle;
if (i < nlocal) energy += eanglethird;
if (j < nlocal) energy += eanglethird;
if (k < nlocal) energy += eanglethird;
}
}
if (eflag_atom) {
eanglethird = THIRD*eangle;
if (newton_bond || i < nlocal) eatom[i] += eanglethird;
if (newton_bond || j < nlocal) eatom[j] += eanglethird;
if (newton_bond || k < nlocal) eatom[k] += eanglethird;
}
}
if (vflag_either) {
v[0] = delx1*f1[0] + delx2*f3[0];
v[1] = dely1*f1[1] + dely2*f3[1];
v[2] = delz1*f1[2] + delz2*f3[2];
v[3] = delx1*f1[1] + delx2*f3[1];
v[4] = delx1*f1[2] + delx2*f3[2];
v[5] = dely1*f1[2] + dely2*f3[2];
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
if (j < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
if (k < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i < nlocal) {
vatom[i][0] += THIRD*v[0];
vatom[i][1] += THIRD*v[1];
vatom[i][2] += THIRD*v[2];
vatom[i][3] += THIRD*v[3];
vatom[i][4] += THIRD*v[4];
vatom[i][5] += THIRD*v[5];
}
if (newton_bond || j < nlocal) {
vatom[j][0] += THIRD*v[0];
vatom[j][1] += THIRD*v[1];
vatom[j][2] += THIRD*v[2];
vatom[j][3] += THIRD*v[3];
vatom[j][4] += THIRD*v[4];
vatom[j][5] += THIRD*v[5];
}
if (newton_bond || k < nlocal) {
vatom[k][0] += THIRD*v[0];
vatom[k][1] += THIRD*v[1];
vatom[k][2] += THIRD*v[2];
vatom[k][3] += THIRD*v[3];
vatom[k][4] += THIRD*v[4];
vatom[k][5] += THIRD*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double Angle::memory_usage()
{
double bytes = comm->nthreads*maxeatom * sizeof(double);
bytes += comm->nthreads*maxvatom*6 * sizeof(double);
return bytes;
}
diff --git a/src/angle.h b/src/angle.h
index 46ee5e1dc..95a35a5a5 100644
--- a/src/angle.h
+++ b/src/angle.h
@@ -1,56 +1,57 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_ANGLE_H
#define LMP_ANGLE_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Angle : protected Pointers {
friend class ThrOMP;
public:
int allocated;
int *setflag;
double energy; // accumulated energies
double virial[6]; // accumlated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
Angle(class LAMMPS *);
virtual ~Angle();
virtual void init();
virtual void compute(int, int) = 0;
virtual void settings(int, char **) {}
virtual void coeff(int, char **) = 0;
+ virtual void init_style() {};
virtual double equilibrium_angle(int) = 0;
virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0;
virtual double single(int, int, int, int) = 0;
virtual double memory_usage();
protected:
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, int, double, double *, double *,
double, double, double, double, double, double);
};
}
#endif
diff --git a/src/bond.h b/src/bond.h
index 29f9862fb..5ba822f52 100644
--- a/src/bond.h
+++ b/src/bond.h
@@ -1,57 +1,56 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_BOND_H
#define LMP_BOND_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Bond : protected Pointers {
friend class ThrOMP;
public:
int allocated;
int *setflag;
double energy; // accumulated energies
double virial[6]; // accumlated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
Bond(class LAMMPS *);
virtual ~Bond();
virtual void init();
virtual void init_style() {}
-
virtual void compute(int, int) = 0;
virtual void settings(int, char **) {}
virtual void coeff(int, char **) = 0;
virtual double equilibrium_distance(int) = 0;
virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0;
virtual double single(int, double, int, int) = 0;
virtual double memory_usage();
protected:
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, double, double, double, double, double);
};
}
#endif
diff --git a/src/bond_hybrid.h b/src/bond_hybrid.h
index acdee7506..6c607ec6c 100644
--- a/src/bond_hybrid.h
+++ b/src/bond_hybrid.h
@@ -1,60 +1,61 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef BOND_CLASS
BondStyle(hybrid,BondHybrid)
#else
#ifndef LMP_BOND_HYBRID_H
#define LMP_BOND_HYBRID_H
#include "stdio.h"
#include "bond.h"
namespace LAMMPS_NS {
class BondHybrid : public Bond {
friend class Force;
public:
+ int nstyles; // # of different bond styles
+ Bond **styles; // class list for each Bond style
+ char **keywords; // keyword for each Bond style
+
BondHybrid(class LAMMPS *);
~BondHybrid();
void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
void init_style();
double equilibrium_distance(int);
void write_restart(FILE *);
void read_restart(FILE *);
double single(int, double, int, int);
double memory_usage();
private:
- int nstyles; // # of different bond styles
- Bond **styles; // class list for each Bond style
- char **keywords; // keyword for each Bond style
int *map; // which style each bond type points to
int *nbondlist; // # of bonds in sub-style bondlists
int *maxbond; // max # of bonds sub-style lists can store
int ***bondlist; // bondlist for each sub-style
void allocate();
};
}
#endif
#endif
diff --git a/src/comm.cpp b/src/comm.cpp
index d1ba20e69..e35726279 100644
--- a/src/comm.cpp
+++ b/src/comm.cpp
@@ -1,1702 +1,1798 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author (triclinic) : Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "comm.h"
+#include "universe.h"
#include "atom.h"
#include "atom_vec.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "neighbor.h"
#include "group.h"
#include "modify.h"
#include "fix.h"
#include "compute.h"
#include "output.h"
#include "dump.h"
+#include "procmap.h"
+#include "math_extra.h"
#include "error.h"
#include "memory.h"
#ifdef _OPENMP
#include "omp.h"
#endif
using namespace LAMMPS_NS;
#define BUFFACTOR 1.5
#define BUFMIN 1000
#define BUFEXTRA 1000
#define BIG 1.0e20
enum{SINGLE,MULTI};
+enum{MULTIPLE}; // same as in ProcMap
+enum{ONELEVEL,TWOLEVEL,NUMA,CUSTOM};
+enum{CART,CARTREORDER,XYZ};
/* ----------------------------------------------------------------------
setup MPI and allocate buffer space
------------------------------------------------------------------------- */
Comm::Comm(LAMMPS *lmp) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
user_procgrid[0] = user_procgrid[1] = user_procgrid[2] = 0;
+ gridflag = ONELEVEL;
+ mapflag = CART;
+ customfile = NULL;
+ recv_from_partition = send_to_partition = -1;
+ otherflag = 0;
+ outfile = NULL;
+
grid2proc = NULL;
bordergroup = 0;
style = SINGLE;
multilo = multihi = NULL;
cutghostmulti = NULL;
cutghostuser = 0.0;
ghost_velocity = 0;
// use of OpenMP threads
// query OpenMP for number of threads/process set by user at run-time
// need to be in a parallel area for this operation
nthreads = 1;
#ifdef _OPENMP
#pragma omp parallel default(shared)
{
#pragma omp master
{ nthreads = omp_get_num_threads(); }
}
if (me == 0) {
if (screen)
fprintf(screen," using %d OpenMP thread(s) per MPI task\n",nthreads);
if (logfile)
fprintf(logfile," using %d OpenMP thread(s) per MPI task\n",nthreads);
}
#endif
// initialize comm buffers & exchange memory
maxsend = BUFMIN;
memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send");
maxrecv = BUFMIN;
memory->create(buf_recv,maxrecv,"comm:buf_recv");
maxswap = 6;
allocate_swap(maxswap);
sendlist = (int **) memory->smalloc(maxswap*sizeof(int *),"comm:sendlist");
memory->create(maxsendlist,maxswap,"comm:maxsendlist");
for (int i = 0; i < maxswap; i++) {
maxsendlist[i] = BUFMIN;
memory->create(sendlist[i],BUFMIN,"comm:sendlist[i]");
}
numa_nodes = 0;
#ifdef NUMA_NODES
numa_nodes = NUMA_NODES;
#endif
}
/* ---------------------------------------------------------------------- */
Comm::~Comm()
{
- if (grid2proc) memory->destroy(grid2proc);
+ delete [] customfile;
+ delete [] outfile;
+
+ memory->destroy(grid2proc);
free_swap();
if (style == MULTI) {
free_multi();
memory->destroy(cutghostmulti);
}
if (sendlist) for (int i = 0; i < maxswap; i++) memory->destroy(sendlist[i]);
memory->sfree(sendlist);
memory->destroy(maxsendlist);
memory->destroy(buf_send);
memory->destroy(buf_recv);
}
/* ----------------------------------------------------------------------
- setup 3d grid of procs based on box size
+ create 3d grid of procs based on Nprocs and box size & shape
+ map processors to grid
------------------------------------------------------------------------- */
-void Comm::set_procs()
+void Comm::set_proc_grid()
{
-#ifdef NUMA_NODES
- if (numa_nodes) {
- numa_set_procs();
- return;
+ // recv 3d proc grid of another partition if my 3d grid depends on it
+
+ if (recv_from_partition >= 0) {
+ MPI_Status status;
+ if (me == 0) MPI_Recv(other_procgrid,3,MPI_INT,
+ universe->root_proc[recv_from_partition],0,
+ universe->uworld,&status);
+ MPI_Bcast(other_procgrid,3,MPI_INT,0,world);
}
-#endif
- procs2box();
+ // create ProcMap class
+
+ ProcMap *pmap = new ProcMap(lmp);
+
+ // create 3d grid of processors, produces procgrid
+ // can fail (on one partition) if constrained by other partition
+ // if numa_grid() fails, try onelevel_grid()
+
+ int flag;
+ if (gridflag == ONELEVEL) {
+ flag = pmap->onelevel_grid(nprocs,user_procgrid,procgrid,
+ otherflag,other_style,other_procgrid);
+ if (!flag) error->all(FLERR,"Could not create grid of processors");
+
+ } else if (gridflag == TWOLEVEL) {
+ flag = pmap->twolevel_grid(nprocs,user_procgrid,procgrid,
+ ncores,user_coregrid,coregrid,
+ otherflag,other_style,other_procgrid);
+ if (!flag) error->all(FLERR,"Could not create grid of processors");
+
+ } else if (gridflag == NUMA) {
+ flag = pmap->numa_grid(nprocs,user_procgrid,procgrid,coregrid);
+ if (!flag) error->all(FLERR,"Could not create grid of processors");
+
+ } else if (gridflag == CUSTOM) {
+ pmap->custom_grid(customfile,nprocs,user_procgrid,procgrid);
+ }
+
+ // error check on procgrid
if (procgrid[0]*procgrid[1]*procgrid[2] != nprocs)
error->all(FLERR,"Bad grid of processors");
if (domain->dimension == 2 && procgrid[2] != 1)
error->all(FLERR,"Processor count in z must be 1 for 2d simulation");
+ // grid2proc[i][j][k] = proc that owns i,j,k location in 3d grid
+
if (grid2proc) memory->destroy(grid2proc);
memory->create(grid2proc,procgrid[0],procgrid[1],procgrid[2],
"comm:grid2proc");
- // use MPI Cartesian routines to setup 3d grid of procs
- // grid2proc[i][j][k] = proc that owns i,j,k location in grid
- // let MPI compute it instead of LAMMPS in case it is machine optimized
+ // map processor IDs to 3d processor grid
+ // produces myloc, procneigh, grid2proc
+
+ if (gridflag == ONELEVEL) {
+ if (mapflag == CART)
+ pmap->cart_map(0,procgrid,myloc,procneigh,grid2proc);
+ else if (mapflag == CARTREORDER)
+ pmap->cart_map(1,procgrid,myloc,procneigh,grid2proc);
+ else if (mapflag == XYZ)
+ pmap->xyz_map(xyz,procgrid,myloc,procneigh,grid2proc);
+
+ } else if (gridflag == TWOLEVEL) {
+ if (mapflag == CART)
+ pmap->cart_map(0,procgrid,coregrid,myloc,procneigh,grid2proc);
+ else if (mapflag == CARTREORDER)
+ pmap->cart_map(1,procgrid,coregrid,myloc,procneigh,grid2proc);
+ else if (mapflag == XYZ)
+ pmap->xyz_map(xyz,procgrid,coregrid,myloc,procneigh,grid2proc);
+
+ } else if (gridflag == NUMA) {
+ pmap->numa_map(coregrid,myloc,procneigh,grid2proc);
+
+ } else if (gridflag == CUSTOM) {
+ pmap->custom_map(procgrid,myloc,procneigh,grid2proc);
+ }
- int reorder = 0;
- int periods[3];
- periods[0] = periods[1] = periods[2] = 1;
- MPI_Comm cartesian;
-
- MPI_Cart_create(world,3,procgrid,periods,reorder,&cartesian);
- MPI_Cart_get(cartesian,3,procgrid,periods,myloc);
- MPI_Cart_shift(cartesian,0,1,&procneigh[0][0],&procneigh[0][1]);
- MPI_Cart_shift(cartesian,1,1,&procneigh[1][0],&procneigh[1][1]);
- MPI_Cart_shift(cartesian,2,1,&procneigh[2][0],&procneigh[2][1]);
-
- int coords[3];
- int i,j,k;
- for (i = 0; i < procgrid[0]; i++)
- for (j = 0; j < procgrid[1]; j++)
- for (k = 0; k < procgrid[2]; k++) {
- coords[0] = i; coords[1] = j; coords[2] = k;
- MPI_Cart_rank(cartesian,coords,&grid2proc[i][j][k]);
- }
+ // print 3d grid info to screen and logfile
+
+ if (me == 0) {
+ if (screen) {
+ fprintf(screen," %d by %d by %d MPI processor grid\n",
+ procgrid[0],procgrid[1],procgrid[2]);
+ if (gridflag == NUMA || gridflag == TWOLEVEL)
+ fprintf(screen," %d by %d by %d core grid within node\n",
+ coregrid[0],coregrid[1],coregrid[2]);
+ }
+ if (logfile) {
+ fprintf(logfile," %d by %d by %d MPI processor grid\n",
+ procgrid[0],procgrid[1],procgrid[2]);
+ if (gridflag == NUMA || gridflag == TWOLEVEL)
+ fprintf(logfile," %d by %d by %d core grid within node\n",
+ coregrid[0],coregrid[1],coregrid[2]);
+ }
+ }
- MPI_Comm_free(&cartesian);
+ // print 3d grid details to outfile
+
+ if (outfile) pmap->output(outfile,procgrid,grid2proc);
// set lamda box params after procs are assigned
if (domain->triclinic) domain->set_lamda_box();
- if (me == 0) {
- if (screen) fprintf(screen," %d by %d by %d processor grid\n",
- procgrid[0],procgrid[1],procgrid[2]);
- if (logfile) fprintf(logfile," %d by %d by %d processor grid\n",
- procgrid[0],procgrid[1],procgrid[2]);
+ // free ProcMap class
+
+ delete pmap;
+
+ // send my 3d proc grid to another partition if requested
+
+ if (send_to_partition >= 0) {
+ if (me == 0) MPI_Send(procgrid,3,MPI_INT,
+ universe->root_proc[send_to_partition],0,
+ universe->uworld);
}
}
/* ---------------------------------------------------------------------- */
void Comm::init()
{
triclinic = domain->triclinic;
map_style = atom->map_style;
// comm_only = 1 if only x,f are exchanged in forward/reverse comm
// comm_x_only = 0 if ghost_velocity since velocities are added
comm_x_only = atom->avec->comm_x_only;
comm_f_only = atom->avec->comm_f_only;
if (ghost_velocity) comm_x_only = 0;
// set per-atom sizes for forward/reverse/border comm
// augment by velocity quantities if needed
size_forward = atom->avec->size_forward;
size_reverse = atom->avec->size_reverse;
size_border = atom->avec->size_border;
if (ghost_velocity) size_forward += atom->avec->size_velocity;
if (ghost_velocity) size_border += atom->avec->size_velocity;
// maxforward = # of datums in largest forward communication
// maxreverse = # of datums in largest reverse communication
// query pair,fix,compute,dump for their requirements
maxforward = MAX(size_forward,size_border);
maxreverse = size_reverse;
if (force->pair) maxforward = MAX(maxforward,force->pair->comm_forward);
if (force->pair) maxreverse = MAX(maxreverse,force->pair->comm_reverse);
for (int i = 0; i < modify->nfix; i++) {
maxforward = MAX(maxforward,modify->fix[i]->comm_forward);
maxreverse = MAX(maxreverse,modify->fix[i]->comm_reverse);
}
for (int i = 0; i < modify->ncompute; i++) {
maxforward = MAX(maxforward,modify->compute[i]->comm_forward);
maxreverse = MAX(maxreverse,modify->compute[i]->comm_reverse);
}
for (int i = 0; i < output->ndump; i++) {
maxforward = MAX(maxforward,output->dump[i]->comm_forward);
maxreverse = MAX(maxreverse,output->dump[i]->comm_reverse);
}
if (force->newton == 0) maxreverse = 0;
// memory for multi-style communication
if (style == MULTI && multilo == NULL) {
allocate_multi(maxswap);
memory->create(cutghostmulti,atom->ntypes+1,3,"comm:cutghostmulti");
}
if (style == SINGLE && multilo) {
free_multi();
memory->destroy(cutghostmulti);
}
}
/* ----------------------------------------------------------------------
setup spatial-decomposition communication patterns
function of neighbor cutoff(s) & cutghostuser & current box size
single style sets slab boundaries (slablo,slabhi) based on max cutoff
multi style sets type-dependent slab boundaries (multilo,multihi)
------------------------------------------------------------------------- */
void Comm::setup()
{
// cutghost[] = max distance at which ghost atoms need to be acquired
// for orthogonal:
// cutghost is in box coords = neigh->cutghost in all 3 dims
// for triclinic:
// neigh->cutghost = distance between tilted planes in box coords
// cutghost is in lamda coords = distance between those planes
// for multi:
// cutghostmulti = same as cutghost, only for each atom type
int i;
int ntypes = atom->ntypes;
double *prd,*sublo,*subhi;
double cut = MAX(neighbor->cutneighmax,cutghostuser);
if (triclinic == 0) {
prd = domain->prd;
sublo = domain->sublo;
subhi = domain->subhi;
cutghost[0] = cutghost[1] = cutghost[2] = cut;
if (style == MULTI) {
double *cuttype = neighbor->cuttype;
for (i = 1; i <= ntypes; i++)
cutghostmulti[i][0] = cutghostmulti[i][1] = cutghostmulti[i][2] =
cuttype[i];
}
} else {
prd = domain->prd_lamda;
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
double *h_inv = domain->h_inv;
double length0,length1,length2;
length0 = sqrt(h_inv[0]*h_inv[0] + h_inv[5]*h_inv[5] + h_inv[4]*h_inv[4]);
cutghost[0] = cut * length0;
length1 = sqrt(h_inv[1]*h_inv[1] + h_inv[3]*h_inv[3]);
cutghost[1] = cut * length1;
length2 = h_inv[2];
cutghost[2] = cut * length2;
if (style == MULTI) {
double *cuttype = neighbor->cuttype;
for (i = 1; i <= ntypes; i++) {
cutghostmulti[i][0] = cuttype[i] * length0;
cutghostmulti[i][1] = cuttype[i] * length1;
cutghostmulti[i][2] = cuttype[i] * length2;
}
}
}
// need = # of procs I need atoms from in each dim based on max cutoff
// for 2d, don't communicate in z
need[0] = static_cast<int> (cutghost[0] * procgrid[0] / prd[0]) + 1;
need[1] = static_cast<int> (cutghost[1] * procgrid[1] / prd[1]) + 1;
need[2] = static_cast<int> (cutghost[2] * procgrid[2] / prd[2]) + 1;
if (domain->dimension == 2) need[2] = 0;
// if non-periodic, do not communicate further than procgrid-1 away
// this enables very large cutoffs in non-periodic systems
int *periodicity = domain->periodicity;
if (periodicity[0] == 0) need[0] = MIN(need[0],procgrid[0]-1);
if (periodicity[1] == 0) need[1] = MIN(need[1],procgrid[1]-1);
if (periodicity[2] == 0) need[2] = MIN(need[2],procgrid[2]-1);
// allocate comm memory
nswap = 2 * (need[0]+need[1]+need[2]);
if (nswap > maxswap) grow_swap(nswap);
// setup parameters for each exchange:
// sendproc = proc to send to at each swap
// recvproc = proc to recv from at each swap
// for style SINGLE:
// slablo/slabhi = boundaries for slab of atoms to send at each swap
// use -BIG/midpt/BIG to insure all atoms included even if round-off occurs
// if round-off, atoms recvd across PBC can be < or > than subbox boundary
// note that borders() only loops over subset of atoms during each swap
// set slablo > slabhi for swaps across non-periodic boundaries
// this insures no atoms are swapped
// only for procs owning sub-box at non-periodic end of global box
// for style MULTI:
// multilo/multihi is same as slablo/slabhi, only for each atom type
// pbc_flag: 0 = nothing across a boundary, 1 = something across a boundary
// pbc = -1/0/1 for PBC factor in each of 3/6 orthog/triclinic dirs
// for triclinic, slablo/hi and pbc_border will be used in lamda (0-1) coords
// 1st part of if statement is sending to the west/south/down
// 2nd part of if statement is sending to the east/north/up
int dim,ineed;
int iswap = 0;
for (dim = 0; dim < 3; dim++) {
for (ineed = 0; ineed < 2*need[dim]; ineed++) {
pbc_flag[iswap] = 0;
pbc[iswap][0] = pbc[iswap][1] = pbc[iswap][2] =
pbc[iswap][3] = pbc[iswap][4] = pbc[iswap][5] = 0;
if (ineed % 2 == 0) {
sendproc[iswap] = procneigh[dim][0];
recvproc[iswap] = procneigh[dim][1];
if (style == SINGLE) {
if (ineed < 2) slablo[iswap] = -BIG;
else slablo[iswap] = 0.5 * (sublo[dim] + subhi[dim]);
slabhi[iswap] = sublo[dim] + cutghost[dim];
} else {
for (i = 1; i <= ntypes; i++) {
if (ineed < 2) multilo[iswap][i] = -BIG;
else multilo[iswap][i] = 0.5 * (sublo[dim] + subhi[dim]);
multihi[iswap][i] = sublo[dim] + cutghostmulti[i][dim];
}
}
if (myloc[dim] == 0) {
if (periodicity[dim] == 0) {
if (style == SINGLE) slabhi[iswap] = slablo[iswap] - 1.0;
else
for (i = 1; i <= ntypes; i++)
multihi[iswap][i] = multilo[iswap][i] - 1.0;
} else {
pbc_flag[iswap] = 1;
pbc[iswap][dim] = 1;
if (triclinic) {
if (dim == 1) pbc[iswap][5] = 1;
else if (dim == 2) pbc[iswap][4] = pbc[iswap][3] = 1;
}
}
}
} else {
sendproc[iswap] = procneigh[dim][1];
recvproc[iswap] = procneigh[dim][0];
if (style == SINGLE) {
slablo[iswap] = subhi[dim] - cutghost[dim];
if (ineed < 2) slabhi[iswap] = BIG;
else slabhi[iswap] = 0.5 * (sublo[dim] + subhi[dim]);
} else {
for (i = 1; i <= ntypes; i++) {
multilo[iswap][i] = subhi[dim] - cutghostmulti[i][dim];
if (ineed < 2) multihi[iswap][i] = BIG;
else multihi[iswap][i] = 0.5 * (sublo[dim] + subhi[dim]);
}
}
if (myloc[dim] == procgrid[dim]-1) {
if (periodicity[dim] == 0) {
if (style == SINGLE) slabhi[iswap] = slablo[iswap] - 1.0;
else
for (i = 1; i <= ntypes; i++)
multihi[iswap][i] = multilo[iswap][i] - 1.0;
} else {
pbc_flag[iswap] = 1;
pbc[iswap][dim] = -1;
if (triclinic) {
if (dim == 1) pbc[iswap][5] = -1;
else if (dim == 2) pbc[iswap][4] = pbc[iswap][3] = -1;
}
}
}
}
iswap++;
}
}
}
/* ----------------------------------------------------------------------
forward communication of atom coords every timestep
other per-atom attributes may also be sent via pack/unpack routines
------------------------------------------------------------------------- */
void Comm::forward_comm(int dummy)
{
int n;
MPI_Request request;
MPI_Status status;
AtomVec *avec = atom->avec;
double **x = atom->x;
double *buf;
// exchange data with another proc
// if other proc is self, just copy
// if comm_x_only set, exchange or copy directly to x, don't unpack
for (int iswap = 0; iswap < nswap; iswap++) {
if (sendproc[iswap] != me) {
if (comm_x_only) {
if (size_forward_recv[iswap]) buf = x[firstrecv[iswap]];
else buf = NULL;
MPI_Irecv(buf,size_forward_recv[iswap],MPI_DOUBLE,
recvproc[iswap],0,world,&request);
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
} else if (ghost_velocity) {
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
recvproc[iswap],0,world,&request);
n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_recv);
} else {
MPI_Irecv(buf_recv,size_forward_recv[iswap],MPI_DOUBLE,
recvproc[iswap],0,world,&request);
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_recv);
}
} else {
if (comm_x_only) {
if (sendnum[iswap])
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
x[firstrecv[iswap]],pbc_flag[iswap],
pbc[iswap]);
} else if (ghost_velocity) {
n = avec->pack_comm_vel(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
avec->unpack_comm_vel(recvnum[iswap],firstrecv[iswap],buf_send);
} else {
n = avec->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
avec->unpack_comm(recvnum[iswap],firstrecv[iswap],buf_send);
}
}
}
}
/* ----------------------------------------------------------------------
reverse communication of forces on atoms every timestep
other per-atom attributes may also be sent via pack/unpack routines
------------------------------------------------------------------------- */
void Comm::reverse_comm()
{
int n;
MPI_Request request;
MPI_Status status;
AtomVec *avec = atom->avec;
double **f = atom->f;
double *buf;
// exchange data with another proc
// if other proc is self, just copy
// if comm_f_only set, exchange or copy directly from f, don't pack
for (int iswap = nswap-1; iswap >= 0; iswap--) {
if (sendproc[iswap] != me) {
if (comm_f_only) {
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
sendproc[iswap],0,world,&request);
if (size_reverse_send[iswap]) buf = f[firstrecv[iswap]];
else buf = NULL;
MPI_Send(buf,size_reverse_send[iswap],MPI_DOUBLE,
recvproc[iswap],0,world);
MPI_Wait(&request,&status);
} else {
MPI_Irecv(buf_recv,size_reverse_recv[iswap],MPI_DOUBLE,
sendproc[iswap],0,world,&request);
n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
MPI_Send(buf_send,n,MPI_DOUBLE,recvproc[iswap],0,world);
MPI_Wait(&request,&status);
}
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],buf_recv);
} else {
if (comm_f_only) {
if (sendnum[iswap])
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],
f[firstrecv[iswap]]);
} else {
n = avec->pack_reverse(recvnum[iswap],firstrecv[iswap],buf_send);
avec->unpack_reverse(sendnum[iswap],sendlist[iswap],buf_send);
}
}
}
}
/* ----------------------------------------------------------------------
exchange: move atoms to correct processors
atoms exchanged with all 6 stencil neighbors
send out atoms that have left my box, receive ones entering my box
atoms will be lost if not inside some proc's box
can happen if atom moves outside of non-periodic bounary
or if atom moves more than one proc away
this routine called before every reneighboring
for triclinic, atoms must be in lamda coords (0-1) before exchange is called
------------------------------------------------------------------------- */
void Comm::exchange()
{
int i,m,nsend,nrecv,nrecv1,nrecv2,nlocal;
double lo,hi,value;
double **x;
double *sublo,*subhi,*buf;
MPI_Request request;
MPI_Status status;
AtomVec *avec = atom->avec;
// clear global->local map for owned and ghost atoms
// b/c atoms migrate to new procs in exchange() and
// new ghosts are created in borders()
// map_set() is done at end of borders()
if (map_style) atom->map_clear();
// subbox bounds for orthogonal or triclinic
if (triclinic == 0) {
sublo = domain->sublo;
subhi = domain->subhi;
} else {
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
}
// loop over dimensions
for (int dim = 0; dim < 3; dim++) {
// fill buffer with atoms leaving my box, using < and >=
// when atom is deleted, fill it in with last atom
x = atom->x;
lo = sublo[dim];
hi = subhi[dim];
nlocal = atom->nlocal;
i = nsend = 0;
while (i < nlocal) {
if (x[i][dim] < lo || x[i][dim] >= hi) {
if (nsend > maxsend) grow_send(nsend,1);
nsend += avec->pack_exchange(i,&buf_send[nsend]);
avec->copy(nlocal-1,i,1);
nlocal--;
} else i++;
}
atom->nlocal = nlocal;
// send/recv atoms in both directions
// if 1 proc in dimension, no send/recv, set recv buf to send buf
// if 2 procs in dimension, single send/recv
// if more than 2 procs in dimension, send/recv to both neighbors
if (procgrid[dim] == 1) {
nrecv = nsend;
buf = buf_send;
} else {
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0,
&nrecv1,1,MPI_INT,procneigh[dim][1],0,world,&status);
nrecv = nrecv1;
if (procgrid[dim] > 2) {
MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0,
&nrecv2,1,MPI_INT,procneigh[dim][0],0,world,&status);
nrecv += nrecv2;
}
if (nrecv > maxrecv) grow_recv(nrecv);
MPI_Irecv(buf_recv,nrecv1,MPI_DOUBLE,procneigh[dim][1],0,
world,&request);
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][0],0,world);
MPI_Wait(&request,&status);
if (procgrid[dim] > 2) {
MPI_Irecv(&buf_recv[nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,
world,&request);
MPI_Send(buf_send,nsend,MPI_DOUBLE,procneigh[dim][1],0,world);
MPI_Wait(&request,&status);
}
buf = buf_recv;
}
// check incoming atoms to see if they are in my box
// if so, add to my list
m = 0;
while (m < nrecv) {
value = buf[m+dim+1];
if (value >= lo && value < hi) m += avec->unpack_exchange(&buf[m]);
else m += static_cast<int> (buf[m]);
}
}
if (atom->firstgroupname) atom->first_reorder();
}
/* ----------------------------------------------------------------------
borders: list nearby atoms to send to neighboring procs at every timestep
one list is created for every swap that will be made
as list is made, actually do swaps
this does equivalent of a communicate (so don't need to explicitly
call communicate routine on reneighboring timestep)
this routine is called before every reneighboring
for triclinic, atoms must be in lamda coords (0-1) before borders is called
------------------------------------------------------------------------- */
void Comm::borders()
{
int i,n,itype,iswap,dim,ineed,maxneed,smax,rmax;
int nsend,nrecv,nfirst,nlast,ngroup;
double lo,hi;
int *type;
double **x;
double *buf,*mlo,*mhi;
MPI_Request request;
MPI_Status status;
AtomVec *avec = atom->avec;
// clear old ghosts and any ghost bonus data internal to AtomVec
atom->nghost = 0;
atom->avec->clear_bonus();
// do swaps over all 3 dimensions
iswap = 0;
smax = rmax = 0;
for (dim = 0; dim < 3; dim++) {
nlast = 0;
maxneed = 2*need[dim];
for (ineed = 0; ineed < maxneed; ineed++) {
// find atoms within slab boundaries lo/hi using <= and >=
// check atoms between nfirst and nlast
// for first swaps in a dim, check owned and ghost
// for later swaps in a dim, only check newly arrived ghosts
// store sent atom indices in list for use in future timesteps
x = atom->x;
if (style == SINGLE) {
lo = slablo[iswap];
hi = slabhi[iswap];
} else {
type = atom->type;
mlo = multilo[iswap];
mhi = multihi[iswap];
}
if (ineed % 2 == 0) {
nfirst = nlast;
nlast = atom->nlocal + atom->nghost;
}
nsend = 0;
// find send atoms according to SINGLE vs MULTI
// all atoms eligible versus atoms in bordergroup
// only need to limit loop to bordergroup for first sends (ineed < 2)
// on these sends, break loop in two: owned (in group) and ghost
if (!bordergroup || ineed >= 2) {
if (style == SINGLE) {
for (i = nfirst; i < nlast; i++)
if (x[i][dim] >= lo && x[i][dim] <= hi) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
} else {
for (i = nfirst; i < nlast; i++) {
itype = type[i];
if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
}
}
} else {
if (style == SINGLE) {
ngroup = atom->nfirst;
for (i = 0; i < ngroup; i++)
if (x[i][dim] >= lo && x[i][dim] <= hi) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
for (i = atom->nlocal; i < nlast; i++)
if (x[i][dim] >= lo && x[i][dim] <= hi) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
} else {
ngroup = atom->nfirst;
for (i = 0; i < ngroup; i++) {
itype = type[i];
if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
}
for (i = atom->nlocal; i < nlast; i++) {
itype = type[i];
if (x[i][dim] >= mlo[itype] && x[i][dim] <= mhi[itype]) {
if (nsend == maxsendlist[iswap]) grow_list(iswap,nsend);
sendlist[iswap][nsend++] = i;
}
}
}
}
// pack up list of border atoms
if (nsend*size_border > maxsend)
grow_send(nsend*size_border,0);
if (ghost_velocity)
n = avec->pack_border_vel(nsend,sendlist[iswap],buf_send,
pbc_flag[iswap],pbc[iswap]);
else
n = avec->pack_border(nsend,sendlist[iswap],buf_send,
pbc_flag[iswap],pbc[iswap]);
// swap atoms with other proc
// put incoming ghosts at end of my atom arrays
// if swapping with self, simply copy, no messages
if (sendproc[iswap] != me) {
MPI_Sendrecv(&nsend,1,MPI_INT,sendproc[iswap],0,
&nrecv,1,MPI_INT,recvproc[iswap],0,world,&status);
if (nrecv*size_border > maxrecv)
grow_recv(nrecv*size_border);
MPI_Irecv(buf_recv,nrecv*size_border,MPI_DOUBLE,
recvproc[iswap],0,world,&request);
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else {
nrecv = nsend;
buf = buf_send;
}
// unpack buffer
if (ghost_velocity)
avec->unpack_border_vel(nrecv,atom->nlocal+atom->nghost,buf);
else
avec->unpack_border(nrecv,atom->nlocal+atom->nghost,buf);
// set all pointers & counters
smax = MAX(smax,nsend);
rmax = MAX(rmax,nrecv);
sendnum[iswap] = nsend;
recvnum[iswap] = nrecv;
size_forward_recv[iswap] = nrecv*size_forward;
size_reverse_send[iswap] = nrecv*size_reverse;
size_reverse_recv[iswap] = nsend*size_reverse;
firstrecv[iswap] = atom->nlocal + atom->nghost;
atom->nghost += nrecv;
iswap++;
}
}
// insure send/recv buffers are long enough for all forward & reverse comm
int max = MAX(maxforward*smax,maxreverse*rmax);
if (max > maxsend) grow_send(max,0);
max = MAX(maxforward*rmax,maxreverse*smax);
if (max > maxrecv) grow_recv(max);
// reset global->local map
if (map_style) atom->map_set();
}
/* ----------------------------------------------------------------------
forward communication invoked by a Pair
------------------------------------------------------------------------- */
void Comm::forward_comm_pair(Pair *pair)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = 0; iswap < nswap; iswap++) {
// pack buffer
n = pair->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
pair->unpack_comm(recvnum[iswap],firstrecv[iswap],buf);
}
}
/* ----------------------------------------------------------------------
reverse communication invoked by a Pair
------------------------------------------------------------------------- */
void Comm::reverse_comm_pair(Pair *pair)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = nswap-1; iswap >= 0; iswap--) {
// pack buffer
n = pair->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
pair->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf);
}
}
/* ----------------------------------------------------------------------
forward communication invoked by a Fix
------------------------------------------------------------------------- */
void Comm::forward_comm_fix(Fix *fix)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = 0; iswap < nswap; iswap++) {
// pack buffer
n = fix->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
fix->unpack_comm(recvnum[iswap],firstrecv[iswap],buf);
}
}
/* ----------------------------------------------------------------------
reverse communication invoked by a Fix
------------------------------------------------------------------------- */
void Comm::reverse_comm_fix(Fix *fix)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = nswap-1; iswap >= 0; iswap--) {
// pack buffer
n = fix->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
fix->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf);
}
}
/* ----------------------------------------------------------------------
forward communication invoked by a Compute
------------------------------------------------------------------------- */
void Comm::forward_comm_compute(Compute *compute)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = 0; iswap < nswap; iswap++) {
// pack buffer
n = compute->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
compute->unpack_comm(recvnum[iswap],firstrecv[iswap],buf);
}
}
/* ----------------------------------------------------------------------
reverse communication invoked by a Compute
------------------------------------------------------------------------- */
void Comm::reverse_comm_compute(Compute *compute)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = nswap-1; iswap >= 0; iswap--) {
// pack buffer
n = compute->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
compute->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf);
}
}
/* ----------------------------------------------------------------------
forward communication invoked by a Dump
------------------------------------------------------------------------- */
void Comm::forward_comm_dump(Dump *dump)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = 0; iswap < nswap; iswap++) {
// pack buffer
n = dump->pack_comm(sendnum[iswap],sendlist[iswap],
buf_send,pbc_flag[iswap],pbc[iswap]);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
dump->unpack_comm(recvnum[iswap],firstrecv[iswap],buf);
}
}
/* ----------------------------------------------------------------------
reverse communication invoked by a Dump
------------------------------------------------------------------------- */
void Comm::reverse_comm_dump(Dump *dump)
{
int iswap,n;
double *buf;
MPI_Request request;
MPI_Status status;
for (iswap = nswap-1; iswap >= 0; iswap--) {
// pack buffer
n = dump->pack_reverse_comm(recvnum[iswap],firstrecv[iswap],buf_send);
// exchange with another proc
// if self, set recv buffer to send buffer
if (sendproc[iswap] != me) {
MPI_Irecv(buf_recv,n*sendnum[iswap],MPI_DOUBLE,sendproc[iswap],0,
world,&request);
MPI_Send(buf_send,n*recvnum[iswap],MPI_DOUBLE,recvproc[iswap],0,world);
MPI_Wait(&request,&status);
buf = buf_recv;
} else buf = buf_send;
// unpack buffer
dump->unpack_reverse_comm(sendnum[iswap],sendlist[iswap],buf);
}
}
-/* ----------------------------------------------------------------------
- assign nprocs to 3d xprd,yprd,zprd box so as to minimize surface area
- area = surface area of each of 3 faces of simulation box
- for triclinic, area = cross product of 2 edge vectors stored in h matrix
-------------------------------------------------------------------------- */
-
-void Comm::procs2box()
-{
- procgrid[0] = user_procgrid[0];
- procgrid[1] = user_procgrid[1];
- procgrid[2] = user_procgrid[2];
-
- // all 3 proc counts are specified
-
- if (procgrid[0] && procgrid[1] && procgrid[2]) return;
-
- // 2 out of 3 proc counts are specified
-
- if (procgrid[0] > 0 && procgrid[1] > 0) {
- procgrid[2] = nprocs/(procgrid[0]*procgrid[1]);
- return;
- } else if (procgrid[0] > 0 && procgrid[2] > 0) {
- procgrid[1] = nprocs/(procgrid[0]*procgrid[2]);
- return;
- } else if (procgrid[1] > 0 && procgrid[2] > 0) {
- procgrid[0] = nprocs/(procgrid[1]*procgrid[2]);
- return;
- }
-
- // determine cross-sectional areas for orthogonal and triclinic boxes
- // area[0] = xy, area[1] = xz, area[2] = yz
-
- double area[3];
- if (domain->triclinic == 0) {
- area[0] = domain->xprd * domain->yprd;
- area[1] = domain->xprd * domain->zprd;
- area[2] = domain->yprd * domain->zprd;
- } else {
- double *h = domain->h;
- double x,y,z;
- cross(h[0],0.0,0.0,h[5],h[1],0.0,x,y,z);
- area[0] = sqrt(x*x + y*y + z*z);
- cross(h[0],0.0,0.0,h[4],h[3],h[2],x,y,z);
- area[1] = sqrt(x*x + y*y + z*z);
- cross(h[5],h[1],0.0,h[4],h[3],h[2],x,y,z);
- area[2] = sqrt(x*x + y*y + z*z);
- }
-
- double bestsurf = 2.0 * (area[0]+area[1]+area[2]);
-
- // loop thru all possible factorizations of nprocs
- // only consider valid cases that match procgrid settings
- // surf = surface area of a proc sub-domain
-
- int ipx,ipy,ipz,valid;
- double surf;
-
- ipx = 1;
- while (ipx <= nprocs) {
- valid = 1;
- if (user_procgrid[0] && ipx != user_procgrid[0]) valid = 0;
- if (nprocs % ipx) valid = 0;
- if (!valid) {
- ipx++;
- continue;
- }
-
- ipy = 1;
- while (ipy <= nprocs/ipx) {
- valid = 1;
- if (user_procgrid[1] && ipy != user_procgrid[1]) valid = 0;
- if ((nprocs/ipx) % ipy) valid = 0;
- if (!valid) {
- ipy++;
- continue;
- }
-
- ipz = nprocs/ipx/ipy;
- valid = 1;
- if (user_procgrid[2] && ipz != user_procgrid[2]) valid = 0;
- if (domain->dimension == 2 && ipz != 1) valid = 0;
- if (!valid) {
- ipy++;
- continue;
- }
-
- surf = area[0]/ipx/ipy + area[1]/ipx/ipz + area[2]/ipy/ipz;
- if (surf < bestsurf) {
- bestsurf = surf;
- procgrid[0] = ipx;
- procgrid[1] = ipy;
- procgrid[2] = ipz;
- }
- ipy++;
- }
-
- ipx++;
- }
-}
-
-/* ----------------------------------------------------------------------
- vector cross product: c = a x b
-------------------------------------------------------------------------- */
-
-void Comm::cross(double ax, double ay, double az,
- double bx, double by, double bz,
- double &cx, double &cy, double &cz)
-{
- cx = ay*bz - az*by;
- cy = az*bx - ax*bz;
- cz = ax*by - ay*bx;
-}
-
/* ----------------------------------------------------------------------
realloc the size of the send buffer as needed with BUFFACTOR & BUFEXTRA
if flag = 1, realloc
if flag = 0, don't need to realloc with copy, just free/malloc
------------------------------------------------------------------------- */
void Comm::grow_send(int n, int flag)
{
maxsend = static_cast<int> (BUFFACTOR * n);
if (flag)
memory->grow(buf_send,(maxsend+BUFEXTRA),"comm:buf_send");
else {
memory->destroy(buf_send);
memory->create(buf_send,maxsend+BUFEXTRA,"comm:buf_send");
}
}
/* ----------------------------------------------------------------------
free/malloc the size of the recv buffer as needed with BUFFACTOR
------------------------------------------------------------------------- */
void Comm::grow_recv(int n)
{
maxrecv = static_cast<int> (BUFFACTOR * n);
memory->destroy(buf_recv);
memory->create(buf_recv,maxrecv,"comm:buf_recv");
}
/* ----------------------------------------------------------------------
realloc the size of the iswap sendlist as needed with BUFFACTOR
------------------------------------------------------------------------- */
void Comm::grow_list(int iswap, int n)
{
maxsendlist[iswap] = static_cast<int> (BUFFACTOR * n);
memory->grow(sendlist[iswap],maxsendlist[iswap],"comm:sendlist[iswap]");
}
/* ----------------------------------------------------------------------
realloc the buffers needed for swaps
------------------------------------------------------------------------- */
void Comm::grow_swap(int n)
{
free_swap();
allocate_swap(n);
if (style == MULTI) {
free_multi();
allocate_multi(n);
}
sendlist = (int **)
memory->srealloc(sendlist,n*sizeof(int *),"comm:sendlist");
memory->grow(maxsendlist,n,"comm:maxsendlist");
for (int i = maxswap; i < n; i++) {
maxsendlist[i] = BUFMIN;
memory->create(sendlist[i],BUFMIN,"comm:sendlist[i]");
}
maxswap = n;
}
/* ----------------------------------------------------------------------
allocation of swap info
------------------------------------------------------------------------- */
void Comm::allocate_swap(int n)
{
memory->create(sendnum,n,"comm:sendnum");
memory->create(recvnum,n,"comm:recvnum");
memory->create(sendproc,n,"comm:sendproc");
memory->create(recvproc,n,"comm:recvproc");
memory->create(size_forward_recv,n,"comm:size");
memory->create(size_reverse_send,n,"comm:size");
memory->create(size_reverse_recv,n,"comm:size");
memory->create(slablo,n,"comm:slablo");
memory->create(slabhi,n,"comm:slabhi");
memory->create(firstrecv,n,"comm:firstrecv");
memory->create(pbc_flag,n,"comm:pbc_flag");
memory->create(pbc,n,6,"comm:pbc");
}
/* ----------------------------------------------------------------------
allocation of multi-type swap info
------------------------------------------------------------------------- */
void Comm::allocate_multi(int n)
{
multilo = memory->create(multilo,n,atom->ntypes+1,"comm:multilo");
multihi = memory->create(multihi,n,atom->ntypes+1,"comm:multihi");
}
/* ----------------------------------------------------------------------
free memory for swaps
------------------------------------------------------------------------- */
void Comm::free_swap()
{
memory->destroy(sendnum);
memory->destroy(recvnum);
memory->destroy(sendproc);
memory->destroy(recvproc);
memory->destroy(size_forward_recv);
memory->destroy(size_reverse_send);
memory->destroy(size_reverse_recv);
memory->destroy(slablo);
memory->destroy(slabhi);
memory->destroy(firstrecv);
memory->destroy(pbc_flag);
memory->destroy(pbc);
}
/* ----------------------------------------------------------------------
free memory for multi-type swaps
------------------------------------------------------------------------- */
void Comm::free_multi()
{
memory->destroy(multilo);
memory->destroy(multihi);
}
/* ----------------------------------------------------------------------
set communication style
+ invoked from input script by communicate command
------------------------------------------------------------------------- */
void Comm::set(int narg, char **arg)
{
if (narg < 1) error->all(FLERR,"Illegal communicate command");
if (strcmp(arg[0],"single") == 0) style = SINGLE;
else if (strcmp(arg[0],"multi") == 0) style = MULTI;
else error->all(FLERR,"Illegal communicate command");
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"group") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command");
bordergroup = group->find(arg[iarg+1]);
if (bordergroup < 0)
error->all(FLERR,"Invalid group in communicate command");
if (bordergroup && (atom->firstgroupname == NULL ||
strcmp(arg[iarg+1],atom->firstgroupname) != 0))
error->all(FLERR,"Communicate group != atom_modify first group");
iarg += 2;
} else if (strcmp(arg[iarg],"cutoff") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command");
cutghostuser = atof(arg[iarg+1]);
if (cutghostuser < 0.0)
error->all(FLERR,"Invalid cutoff in communicate command");
iarg += 2;
} else if (strcmp(arg[iarg],"vel") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal communicate command");
if (strcmp(arg[iarg+1],"yes") == 0) ghost_velocity = 1;
else if (strcmp(arg[iarg+1],"no") == 0) ghost_velocity = 0;
else error->all(FLERR,"Illegal communicate command");
iarg += 2;
} else error->all(FLERR,"Illegal communicate command");
}
}
+/* ----------------------------------------------------------------------
+ set dimensions for 3d grid of processors, and associated flags
+ invoked from input script by processors command
+------------------------------------------------------------------------- */
+
+void Comm::set_processors(int narg, char **arg)
+{
+ if (narg < 3) error->all(FLERR,"Illegal processors command");
+
+ if (strcmp(arg[0],"*") == 0) user_procgrid[0] = 0;
+ else user_procgrid[0] = atoi(arg[0]);
+ if (strcmp(arg[1],"*") == 0) user_procgrid[1] = 0;
+ else user_procgrid[1] = atoi(arg[1]);
+ if (strcmp(arg[2],"*") == 0) user_procgrid[2] = 0;
+ else user_procgrid[2] = atoi(arg[2]);
+
+ if (user_procgrid[0] < 0 || user_procgrid[1] < 0 || user_procgrid[2] < 0)
+ error->all(FLERR,"Illegal processors command");
+
+ int iarg = 3;
+ while (iarg < narg) {
+ if (strcmp(arg[iarg],"grid") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal processors command");
+
+ if (strcmp(arg[iarg+1],"onelevel") == 0) {
+ gridflag = ONELEVEL;
+
+ } else if (strcmp(arg[iarg+1],"twolevel") == 0) {
+ if (iarg+6 > narg) error->all(FLERR,"Illegal processors command");
+ gridflag = TWOLEVEL;
+
+ ncores = atoi(arg[2]);
+ if (strcmp(arg[3],"*") == 0) user_coregrid[0] = 0;
+ else user_coregrid[0] = atoi(arg[3]);
+ if (strcmp(arg[4],"*") == 0) user_coregrid[1] = 0;
+ else user_coregrid[1] = atoi(arg[4]);
+ if (strcmp(arg[5],"*") == 0) user_coregrid[2] = 0;
+ else user_coregrid[2] = atoi(arg[5]);
+
+ if (ncores <= 0 || user_coregrid[0] < 0 ||
+ user_coregrid[1] < 0 || user_coregrid[2] < 0)
+ error->all(FLERR,"Illegal processors command");
+ iarg += 4;
+
+ } else if (strcmp(arg[iarg+1],"numa") == 0) {
+ gridflag = NUMA;
+
+ } else if (strcmp(arg[iarg],"custom") == 0) {
+ if (iarg+3 > narg) error->all(FLERR,"Illegal processors command");
+ gridflag = CUSTOM;
+ delete [] customfile;
+ int n = strlen(arg[iarg+2]) + 1;
+ customfile = new char(n);
+ strcpy(customfile,arg[iarg+2]);
+ iarg += 1;
+
+ } else error->all(FLERR,"Illegal processors command");
+ iarg += 2;
+
+ } else if (strcmp(arg[iarg],"map") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal processors command");
+ if (strcmp(arg[iarg+1],"cart") == 0) mapflag = CART;
+ else if (strcmp(arg[iarg+1],"cart/reorder") == 0) mapflag = CARTREORDER;
+ else if (strcmp(arg[iarg+1],"xyz") == 0 ||
+ strcmp(arg[iarg+1],"xzy") == 0 ||
+ strcmp(arg[iarg+1],"yxz") == 0 ||
+ strcmp(arg[iarg+1],"yzx") == 0 ||
+ strcmp(arg[iarg+1],"zxy") == 0 ||
+ strcmp(arg[iarg+1],"zyx") == 0) {
+ mapflag = XYZ;
+ strcpy(xyz,arg[iarg+1]);
+ } else error->all(FLERR,"Illegal processors command");
+ iarg += 2;
+
+ } else if (strcmp(arg[iarg],"part") == 0) {
+ if (iarg+4 > narg) error->all(FLERR,"Illegal processors command");
+ if (universe->nworlds == 1)
+ error->all(FLERR,
+ "Cannot use processors part command "
+ "without using partitions");
+ int isend = atoi(arg[iarg+1]);
+ int irecv = atoi(arg[iarg+2]);
+ if (isend < 1 || isend > universe->nworlds ||
+ irecv < 1 || irecv > universe->nworlds || isend == irecv)
+ error->all(FLERR,"Invalid partitions in processors part command");
+ if (isend-1 == universe->iworld) {
+ if (send_to_partition >= 0)
+ error->all(FLERR,
+ "Sending partition in processors part command "
+ "is already a sender");
+ send_to_partition = irecv-1;
+ }
+ if (irecv-1 == universe->iworld) {
+ if (recv_from_partition >= 0)
+ error->all(FLERR,
+ "Receiving partition in processors part command "
+ "is already a receiver");
+ recv_from_partition = isend-1;
+ }
+
+ // only receiver has otherflag dependency
+
+ if (strcmp(arg[iarg+3],"multiple") == 0) {
+ if (universe->iworld == irecv-1) {
+ otherflag = 1;
+ other_style = MULTIPLE;
+ }
+ } else error->all(FLERR,"Illegal processors command");
+ iarg += 4;
+
+ } else if (strcmp(arg[iarg],"file") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal processors command");
+ delete [] outfile;
+ int n = strlen(arg[iarg+1]) + 1;
+ outfile = new char(n);
+ strcpy(outfile,arg[iarg+1]);
+ iarg += 2;
+
+ } else error->all(FLERR,"Illegal processors command");
+ }
+
+ // error checks
+
+ if (gridflag == NUMA && mapflag != CART)
+ error->all(FLERR,"Processors grid numa and map style are incompatible");
+ if (otherflag && (gridflag == NUMA || gridflag == CUSTOM))
+ error->all(FLERR,
+ "Processors part option and grid style are incompatible");
+}
+
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
------------------------------------------------------------------------- */
bigint Comm::memory_usage()
{
bigint bytes = 0;
for (int i = 0; i < nswap; i++)
bytes += memory->usage(sendlist[i],maxsendlist[i]);
bytes += memory->usage(buf_send,maxsend+BUFEXTRA);
bytes += memory->usage(buf_recv,maxrecv);
return bytes;
}
#ifdef NUMA_NODES
#include <map>
#include <string>
/* ----------------------------------------------------------------------
Get the index to the neighboring processors in a dimension
------------------------------------------------------------------------- */
void Comm::numa_shift(int myloc, int num_procs, int &minus, int &plus)
{
minus = myloc - 1;
if (minus < 0)
minus = num_procs - 1;
plus = myloc + 1;
if (plus == num_procs)
plus = 0;
}
/* ----------------------------------------------------------------------
setup 3d grid of procs based on box size, group neighbors by numa node
------------------------------------------------------------------------- */
void Comm::numa_set_procs()
{
// Get the names of all nodes
int name_length;
char node_name[MPI_MAX_PROCESSOR_NAME];
char node_names[MPI_MAX_PROCESSOR_NAME*nprocs];
MPI_Get_processor_name(node_name,&name_length);
MPI_Allgather(&node_name,MPI_MAX_PROCESSOR_NAME,MPI_CHAR,&node_names,
MPI_MAX_PROCESSOR_NAME,MPI_CHAR,world);
std::string node_string = std::string(node_name);
// Get the number of procs per node
std::map<std::string,int> name_map;
std::map<std::string,int>::iterator np;
for (int i = 0; i < nprocs; i++) {
std::string i_string = std::string(&node_names[i*MPI_MAX_PROCESSOR_NAME]);
np = name_map.find(i_string);
if (np == name_map.end())
name_map[i_string] = 1;
else
np->second++;
}
int procs_per_node = name_map.begin()->second;
int procs_per_numa = procs_per_node / numa_nodes;
// Use regular mapping if:
if (procs_per_numa < 4 || // 3 or less procs per numa node
procs_per_node % numa_nodes != 0 || // Different # of procs per numa node
nprocs % procs_per_numa != 0 || // Different # of procs per numa node
nprocs <= procs_per_numa || // Only 1 numa node used
user_procgrid[0] > 1 || // User specified grid dimension
user_procgrid[1] > 1 || // that is greater than 1
user_procgrid[2] > 1) { // in any dimension
numa_nodes = 0;
if (me == 0) {
if (screen) fprintf(screen," 1 by 1 by 1 Node grid\n");
if (logfile) fprintf(logfile," 1 by 1 by 1 Node grid\n");
}
set_procs();
return;
}
// User settings for the factorization per numa node - currently always zero
int user_numagrid[3];
user_numagrid[0] = user_numagrid[1] = user_numagrid[2] = 0;
// If the 1 is specified by user for a proc grid dimension, also use
// 1 for the node grid dimension
if (user_procgrid[0] == 1) user_numagrid[0] = 1;
if (user_procgrid[1] == 1) user_numagrid[1] = 1;
if (user_procgrid[2] == 1) user_numagrid[2] = 1;
// Get an initial factorization for each numa node if the user has not
// set the number of processors
int numagrid[3];
numa_factor_box(procs_per_numa,user_numagrid,numagrid,1,1,1);
if (numagrid[0] * numagrid[1] * numagrid[2] != procs_per_numa)
error->all(FLERR,"Bad Node grid of processors");
// Get a factorization for the grid of numa nodes
int node_count = nprocs / procs_per_numa;
numa_factor_box(node_count,user_procgrid,procgrid,numagrid[0],numagrid[1],
numagrid[2]);
if (procgrid[0] * procgrid[1] * procgrid[2] != node_count)
error->all(FLERR,"Bad grid of processors");
// Repeat the numa node factorization using the subdomain sizes
// This will refine the factorization if the user specified the node layout
numa_factor_box(procs_per_numa,user_numagrid,numagrid,procgrid[0],
procgrid[1],procgrid[2]);
if (numagrid[0]*numagrid[1]*numagrid[2] != procs_per_numa)
error->all(FLERR,"Bad Node grid of processors");
if (domain->dimension == 2 && (procgrid[2] != 1 || numagrid[2] != 1))
error->all(FLERR,"Processor count in z must be 1 for 2d simulation");
// Assign a unique id to each node
int node_num = 0, node_id = 0;
for (np = name_map.begin(); np != name_map.end(); ++np) {
if (np->first == node_string)
node_id = node_num;
node_num++;
}
// Set up a per node communicator and find rank within
MPI_Comm node_comm;
MPI_Comm_split(world, node_id, 0, &node_comm);
int node_rank;
MPI_Comm_rank(node_comm, &node_rank);
// Set up a per numa communicator and find rank within
MPI_Comm numa_comm;
int local_numa = node_rank / procs_per_numa;
MPI_Comm_split(node_comm, local_numa, 0, &numa_comm);
int numa_rank;
MPI_Comm_rank(numa_comm, &numa_rank);
// Set up a communicator with the rank 0 procs from each numa node
MPI_Comm numa_leaders;
MPI_Comm_split(world, numa_rank, 0, &numa_leaders);
// Use the MPI Cartesian routines to map the nodes to the grid
int reorder = 0;
int periods[3];
periods[0] = periods[1] = periods[2] = 1;
MPI_Comm cartesian;
if (numa_rank == 0) {
MPI_Cart_create(numa_leaders,3,procgrid,periods,reorder,&cartesian);
MPI_Cart_get(cartesian,3,procgrid,periods,myloc);
}
// Broadcast numa node location in grid to other procs in numa node
MPI_Bcast(myloc,3,MPI_INT,0,numa_comm);
// Get storage for the process mapping
if (grid2proc) memory->destroy(grid2proc);
memory->create(grid2proc,procgrid[0]*numagrid[0],procgrid[1]*numagrid[1],
procgrid[2]*numagrid[2],"comm:grid2proc");
// Compute my location within the grid
int z_offset = numa_rank / (numagrid[0] * numagrid[1]);
int y_offset = (numa_rank % (numagrid[0] * numagrid[1]))/numagrid[0];
int x_offset = numa_rank % numagrid[0];
myloc[0] = myloc[0] * numagrid[0] + x_offset;
myloc[1] = myloc[1] * numagrid[1] + y_offset;
myloc[2] = myloc[2] * numagrid[2] + z_offset;
procgrid[0] *= numagrid[0];
procgrid[1] *= numagrid[1];
procgrid[2] *= numagrid[2];
// Allgather of locations to fill grid2proc
int **gridi;
memory->create(gridi,nprocs,3,"comm:gridi");
MPI_Allgather(&myloc,3,MPI_INT,gridi[0],3,MPI_INT,world);
for (int i = 0; i < nprocs; i++)
grid2proc[gridi[i][0]][gridi[i][1]][gridi[i][2]] = i;
memory->destroy(gridi);
// Get my neighbors
int minus, plus;
for (int i = 0; i < 3; i++) {
numa_shift(myloc[i],procgrid[i],minus,plus);
procneigh[i][0] = minus;
procneigh[i][1] = plus;
}
procneigh[0][0] = grid2proc[procneigh[0][0]][myloc[1]][myloc[2]];
procneigh[0][1] = grid2proc[procneigh[0][1]][myloc[1]][myloc[2]];
procneigh[1][0] = grid2proc[myloc[0]][procneigh[1][0]][myloc[2]];
procneigh[1][1] = grid2proc[myloc[0]][procneigh[1][1]][myloc[2]];
procneigh[2][0] = grid2proc[myloc[0]][myloc[1]][procneigh[2][0]];
procneigh[2][1] = grid2proc[myloc[0]][myloc[1]][procneigh[2][1]];
if (numa_rank == 0)
MPI_Comm_free(&cartesian);
MPI_Comm_free(&numa_leaders);
MPI_Comm_free(&numa_comm);
MPI_Comm_free(&node_comm);
// set lamda box params after procs are assigned
if (domain->triclinic) domain->set_lamda_box();
if (me == 0) {
if (screen) fprintf(screen," %d by %d by %d Node grid\n",
numagrid[0],numagrid[1],numagrid[2]);
if (logfile) fprintf(logfile," %d by %d by %d Node grid\n",
numagrid[0],numagrid[1],numagrid[2]);
if (screen) fprintf(screen," %d by %d by %d processor grid\n",
procgrid[0],procgrid[1],procgrid[2]);
if (logfile) fprintf(logfile," %d by %d by %d processor grid\n",
procgrid[0],procgrid[1],procgrid[2]);
}
}
/* ----------------------------------------------------------------------
factor num_procs to 3d box to minimize the surface area
user_factors = if non-zero, dimension specified by user
factors = resulting # procs in each dimension
sx = box x dimension is divided by sx
sy = box y dimension is divided by sy
sz = box z dimension is divided by sz
area = surface area of each of 3 faces of simulation box
for triclinic, area = cross product of 2 edge vectors stored in h matrix
------------------------------------------------------------------------- */
void Comm::numa_factor_box(int num_procs, int user_factors[3], int factors[3],
const int sx, const int sy, const int sz) {
factors[0] = user_factors[0];
factors[1] = user_factors[1];
factors[2] = user_factors[2];
// all 3 proc counts are specified
if (factors[0] && factors[1] && factors[2]) return;
// 2 out of 3 proc counts are specified
if (factors[0] > 0 && factors[1] > 0) {
factors[2] = nprocs/(factors[0]*factors[1]);
return;
} else if (factors[0] > 0 && factors[2] > 0) {
factors[1] = nprocs/(factors[0]*factors[2]);
return;
} else if (factors[1] > 0 && factors[2] > 0) {
factors[0] = nprocs/(factors[1]*factors[2]);
return;
}
// determine cross-sectional areas for orthogonal and triclinic boxes
// area[0] = xy, area[1] = xz, area[2] = yz
double area[3];
if (domain->triclinic == 0) {
area[0] = domain->xprd * domain->yprd / (sx * sy);
area[1] = domain->xprd * domain->zprd / (sx * sz);
area[2] = domain->yprd * domain->zprd / (sy * sz);
} else {
double *h = domain->h;
double x,y,z;
cross(h[0],0.0,0.0,h[5],h[1],0.0,x,y,z);
area[0] = sqrt(x*x + y*y + z*z) / (sx * sy);
cross(h[0],0.0,0.0,h[4],h[3],h[2],x,y,z);
area[1] = sqrt(x*x + y*y + z*z) / (sx * sz);
cross(h[5],h[1],0.0,h[4],h[3],h[2],x,y,z);
area[2] = sqrt(x*x + y*y + z*z) / (sy * sz);
}
double bestsurf = 2.0 * (area[0]+area[1]+area[2]);
// loop thru all possible factorizations of num_procs
// only consider valid cases that match procgrid settings
// surf = surface area of a proc sub-domain
int ipx,ipy,ipz,valid;
double surf;
ipx = 1;
while (ipx <= num_procs) {
valid = 1;
if (user_factors[0] && ipx != user_factors[0]) valid = 0;
if (num_procs % ipx) valid = 0;
if (!valid) {
ipx++;
continue;
}
ipy = 1;
while (ipy <= num_procs/ipx) {
valid = 1;
if (user_factors[1] && ipy != user_factors[1]) valid = 0;
if ((num_procs/ipx) % ipy) valid = 0;
if (!valid) {
ipy++;
continue;
}
ipz = num_procs/ipx/ipy;
valid = 1;
if (user_factors[2] && ipz != user_factors[2]) valid = 0;
if (domain->dimension == 2 && ipz != 1) valid = 0;
if (!valid) {
ipy++;
continue;
}
surf = area[0]/ipx/ipy + area[1]/ipx/ipz + area[2]/ipy/ipz;
if (surf < bestsurf) {
bestsurf = surf;
factors[0] = ipx;
factors[1] = ipy;
factors[2] = ipz;
}
ipy++;
}
ipx++;
}
}
#endif
diff --git a/src/comm.h b/src/comm.h
index f889c5f9d..faa0df6c1 100644
--- a/src/comm.h
+++ b/src/comm.h
@@ -1,117 +1,131 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_COMM_H
#define LMP_COMM_H
#include "pointers.h"
#ifdef NODE_PARTITION
#define NUMA_NODES 1
#endif
namespace LAMMPS_NS {
class Comm : protected Pointers {
public:
int me,nprocs; // proc info
- int procgrid[3]; // assigned # of procs in each dim
+ int procgrid[3]; // procs assigned in each dim of 3d grid
int user_procgrid[3]; // user request for procs in each dim
int myloc[3]; // which proc I am in each dim
int procneigh[3][2]; // my 6 neighboring procs
int ghost_velocity; // 1 if ghost atoms have velocity, 0 if not
double cutghost[3]; // cutoffs used for acquiring ghost atoms
double cutghostuser; // user-specified ghost cutoff
int ***grid2proc; // which proc owns i,j,k loc in 3d grid
+ int recv_from_partition; // recv proc layout from this partition
+ int send_to_partition; // send my proc layout to this partition
+ // -1 if no recv or send
+ int other_partition_style; // 0 = recv layout dims must be multiple of
+ // my layout dims
int nthreads; // OpenMP threads per MPI process
Comm(class LAMMPS *);
virtual ~Comm();
virtual void init();
- virtual void set_procs(); // setup 3d grid of procs
- virtual void setup(); // setup 3d communication pattern
- virtual void forward_comm(int dummy = 0); // forward communication of atom coords
- virtual void reverse_comm(); // reverse communication of forces
- virtual void exchange(); // move atoms to new procs
- virtual void borders(); // setup list of atoms to communicate
+ virtual void set_proc_grid(); // setup 3d grid of procs
+ virtual void setup(); // setup 3d comm pattern
+ virtual void forward_comm(int dummy = 0); // forward comm of atom coords
+ virtual void reverse_comm(); // reverse comm of forces
+ virtual void exchange(); // move atoms to new procs
+ virtual void borders(); // setup list of atoms to comm
virtual void forward_comm_pair(class Pair *); // forward comm from a Pair
virtual void reverse_comm_pair(class Pair *); // reverse comm from a Pair
virtual void forward_comm_fix(class Fix *); // forward comm from a Fix
virtual void reverse_comm_fix(class Fix *); // reverse comm from a Fix
virtual void forward_comm_compute(class Compute *); // forward from a Compute
virtual void reverse_comm_compute(class Compute *); // reverse from a Compute
virtual void forward_comm_dump(class Dump *); // forward comm from a Dump
virtual void reverse_comm_dump(class Dump *); // reverse comm from a Dump
- virtual void set(int, char **); // set communication style
+ virtual void set(int, char **); // set communication style
+ void set_processors(int, char **); // set 3d processor grid attributes
+
virtual bigint memory_usage();
protected:
int style; // single vs multi-type comm
int nswap; // # of swaps to perform
int need[3]; // procs I need atoms from in each dim
int triclinic; // 0 if domain is orthog, 1 if triclinic
int maxswap; // max # of swaps memory is allocated for
int size_forward; // # of per-atom datums in forward comm
int size_reverse; // # of datums in reverse comm
int size_border; // # of datums in forward border comm
int *sendnum,*recvnum; // # of atoms to send/recv in each swap
int *sendproc,*recvproc; // proc to send/recv to/from at each swap
int *size_forward_recv; // # of values to recv in each forward comm
int *size_reverse_send; // # to send in each reverse comm
int *size_reverse_recv; // # to recv in each reverse comm
double *slablo,*slabhi; // bounds of slab to send at each swap
double **multilo,**multihi; // bounds of slabs for multi-type swap
double **cutghostmulti; // cutghost on a per-type basis
int *pbc_flag; // general flag for sending atoms thru PBC
int **pbc; // dimension flags for PBC adjustments
int comm_x_only,comm_f_only; // 1 if only exchange x,f in for/rev comm
int map_style; // non-0 if global->local mapping is done
int bordergroup; // only communicate this group in borders
- int numa_nodes; // >0 if twolevel factorization for grid map
+ int gridflag; // option for creating 3d grid
+ int mapflag; // option for mapping procs to 3d grid
+ char xyz[4]; // xyz mapping of procs to 3d grid
+ char *customfile; // file with custom proc map
+ char *outfile; // proc grid/map output file
+
+ int otherflag; // 1 if this partition dependent on another
+ int other_style; // style of dependency
+ int other_procgrid[3]; // proc layout of another partition
+ int ncores; // # of cores per node
+ int coregrid[3]; // 3d grid of cores within a node
+ int user_coregrid[3]; // user request for cores in each dim
int *firstrecv; // where to put 1st recv atom in each swap
int **sendlist; // list of atoms to send in each swap
int *maxsendlist; // max size of send list for each swap
double *buf_send; // send buffer for all comm
double *buf_recv; // recv buffer for all comm
int maxsend,maxrecv; // current size of send/recv buffer
int maxforward,maxreverse; // max # of datums in forward/reverse comm
-
- virtual void procs2box(); // map procs to 3d box
- virtual void cross(double, double, double,
- double, double, double,
- double &, double &, double &); // cross product
+
virtual void grow_send(int,int); // reallocate send buffer
virtual void grow_recv(int); // free/allocate recv buffer
virtual void grow_list(int, int); // reallocate one sendlist
virtual void grow_swap(int); // grow swap and multi arrays
virtual void allocate_swap(int); // allocate swap arrays
virtual void allocate_multi(int); // allocate multi arrays
virtual void free_swap(); // free swap arrays
virtual void free_multi(); // free multi arrays
#ifdef NUMA_NODES
void numa_shift(int, int, int &, int &);
void numa_set_procs();
void numa_factor_box(int, int[3], int[3], const int, const int, const int);
#endif
};
}
#endif
diff --git a/src/compute_pair_local.cpp b/src/compute_pair_local.cpp
index 8c35f0170..af1c415e7 100644
--- a/src/compute_pair_local.cpp
+++ b/src/compute_pair_local.cpp
@@ -1,229 +1,267 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
+#include "stdlib.h"
#include "compute_pair_local.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "pair.h"
#include "neighbor.h"
#include "neigh_request.h"
#include "neigh_list.h"
#include "group.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 10000
+enum{DIST,ENG,FORCE,FX,FY,FZ,PN};
+
/* ---------------------------------------------------------------------- */
ComputePairLocal::ComputePairLocal(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal compute pair/local command");
local_flag = 1;
nvalues = narg - 3;
if (nvalues == 1) size_local_cols = 0;
else size_local_cols = nvalues;
- dflag = eflag = fflag = -1;
- nvalues = 0;
+ pstyle = new int[nvalues];
+ pindex = new int[nvalues];
- int i;
+ nvalues = 0;
for (int iarg = 3; iarg < narg; iarg++) {
- i = iarg-3;
- if (strcmp(arg[iarg],"dist") == 0) dflag = nvalues++;
- else if (strcmp(arg[iarg],"eng") == 0) eflag = nvalues++;
- else if (strcmp(arg[iarg],"force") == 0) fflag = nvalues++;
- else error->all(FLERR,"Invalid keyword in compute pair/local command");
+ if (strcmp(arg[iarg],"dist") == 0) pstyle[nvalues++] = DIST;
+ else if (strcmp(arg[iarg],"eng") == 0) pstyle[nvalues++] = ENG;
+ else if (strcmp(arg[iarg],"force") == 0) pstyle[nvalues++] = FORCE;
+ else if (strcmp(arg[iarg],"fx") == 0) pstyle[nvalues++] = FX;
+ else if (strcmp(arg[iarg],"fy") == 0) pstyle[nvalues++] = FY;
+ else if (strcmp(arg[iarg],"fz") == 0) pstyle[nvalues++] = FZ;
+ else if (arg[iarg][0] == 'p') {
+ int n = atoi(&arg[iarg][1]);
+ if (n <= 0) error->all(FLERR,
+ "Invalid keyword in compute pair/local command");
+ pstyle[nvalues] = PN;
+ pindex[nvalues++] = n-1;
+ } else error->all(FLERR,"Invalid keyword in compute pair/local command");
}
+ // set singleflag if need to call pair->single()
+
+ singleflag = 0;
+ for (int i = 0; i < nvalues; i++)
+ if (pstyle[i] != DIST) singleflag = 1;
+
nmax = 0;
vector = NULL;
array = NULL;
}
/* ---------------------------------------------------------------------- */
ComputePairLocal::~ComputePairLocal()
{
memory->destroy(vector);
memory->destroy(array);
+ delete [] pstyle;
+ delete [] pindex;
}
/* ---------------------------------------------------------------------- */
void ComputePairLocal::init()
{
- if (force->pair == NULL)
+ if (singleflag && force->pair == NULL)
error->all(FLERR,"No pair style is defined for compute pair/local");
- if (force->pair->single_enable == 0)
+ if (singleflag && force->pair->single_enable == 0)
error->all(FLERR,"Pair style does not support compute pair/local");
+ for (int i = 0; i < nvalues; i++)
+ if (pstyle[i] == PN && pindex[i] >= force->pair->single_extra)
+ error->all(FLERR,"Pair style does not have single field"
+ " requested by compute pair/local");
+
// need an occasional half neighbor list
int irequest = neighbor->request((void *) this);
neighbor->requests[irequest]->pair = 0;
neighbor->requests[irequest]->compute = 1;
neighbor->requests[irequest]->occasional = 1;
}
/* ---------------------------------------------------------------------- */
void ComputePairLocal::init_list(int id, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputePairLocal::compute_local()
{
invoked_local = update->ntimestep;
// count local entries and compute pair info
ncount = compute_pairs(0);
if (ncount > nmax) reallocate(ncount);
size_local_rows = ncount;
- ncount = compute_pairs(1);
+ compute_pairs(1);
}
/* ----------------------------------------------------------------------
count pairs and compute pair info on this proc
only count pair once if newton_pair is off
both atom I,J must be in group
if flag is set, compute requested info about pair
------------------------------------------------------------------------- */
int ComputePairLocal::compute_pairs(int flag)
{
int i,j,m,n,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz;
double rsq,eng,fpair,factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
- double *dbuf,*ebuf,*fbuf;
+ double *ptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
// invoke half neighbor list (will copy or build if necessary)
if (flag == 0) neighbor->build_one(list->index);
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
// skip if I or J are not in group
-
- if (flag) {
- if (nvalues == 1) {
- if (dflag >= 0) dbuf = vector;
- if (eflag >= 0) ebuf = vector;
- if (fflag >= 0) fbuf = vector;
- } else {
- if (dflag >= 0) dbuf = &array[0][dflag];
- if (eflag >= 0) ebuf = &array[0][eflag];
- if (fflag >= 0) fbuf = &array[0][fflag];
- }
- }
+ // for flag = 0, just count pair interactions within force cutoff
+ // for flag = 1, calculate requested output fields
Pair *pair = force->pair;
double **cutsq = force->pair->cutsq;
- m = n = 0;
+ m = 0;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
if (!(mask[i] & groupbit)) continue;
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
factor_coul = special_coul[sbmask(j)];
j &= NEIGHMASK;
if (!(mask[j] & groupbit)) continue;
if (newton_pair == 0 && j >= nlocal) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq >= cutsq[itype][jtype]) continue;
if (flag) {
- if (dflag >= 0) dbuf[n] = sqrt(rsq);
- if (eflag >= 0 || fflag >= 0) {
+ if (singleflag)
eng = pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair);
- if (eflag >= 0) ebuf[n] = eng;
- if (fflag >= 0) fbuf[n] = sqrt(rsq)*fpair;
+
+ if (nvalues == 1) ptr = &vector[m];
+ else ptr = array[m];
+
+ for (n = 0; n < nvalues; n++) {
+ switch (pstyle[n]) {
+ case DIST:
+ ptr[n] = sqrt(rsq);
+ break;
+ case ENG:
+ ptr[n] = eng;
+ break;
+ case FORCE:
+ ptr[n] = sqrt(rsq)*fpair;
+ break;
+ case FX:
+ ptr[n] = delx*fpair;
+ break;
+ case FY:
+ ptr[n] = dely*fpair;
+ break;
+ case FZ:
+ ptr[n] = delz*fpair;
+ break;
+ case PN:
+ ptr[n] = pair->svector[pindex[n]];
+ break;
+ }
}
- n += nvalues;
}
m++;
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void ComputePairLocal::reallocate(int n)
{
// grow vector or array and indices array
while (nmax < n) nmax += DELTA;
if (nvalues == 1) {
memory->destroy(vector);
memory->create(vector,nmax,"pair/local:vector");
vector_local = vector;
} else {
memory->destroy(array);
memory->create(array,nmax,nvalues,"pair/local:array");
array_local = array;
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double ComputePairLocal::memory_usage()
{
double bytes = nmax*nvalues * sizeof(double);
return bytes;
}
diff --git a/src/compute_pair_local.h b/src/compute_pair_local.h
index e6706c193..aaa8cdf4c 100644
--- a/src/compute_pair_local.h
+++ b/src/compute_pair_local.h
@@ -1,53 +1,57 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
ComputeStyle(pair/local,ComputePairLocal)
#else
#ifndef LMP_COMPUTE_PAIR_LOCAL_H
#define LMP_COMPUTE_PAIR_LOCAL_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputePairLocal : public Compute {
public:
ComputePairLocal(class LAMMPS *, int, char **);
~ComputePairLocal();
void init();
void init_list(int, class NeighList *);
void compute_local();
double memory_usage();
private:
int nvalues,dflag,eflag,fflag;
int ncount;
+ int *pstyle; // style of each requested output
+ int *pindex; // for pI, index of the output (0 to M-1)
+ int singleflag;
+
int nmax;
double *vector;
double **array;
class NeighList *list;
int compute_pairs(int);
void reallocate(int);
};
}
#endif
#endif
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index c1cdc6d83..5f1301201 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -1,484 +1,486 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "create_atoms.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "modify.h"
#include "fix.h"
#include "domain.h"
#include "lattice.h"
#include "region.h"
#include "random_park.h"
#include "error.h"
using namespace LAMMPS_NS;
#define BIG 1.0e30
#define EPSILON 1.0e-6
enum{BOX,REGION,SINGLE,RANDOM};
/* ---------------------------------------------------------------------- */
CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void CreateAtoms::command(int narg, char **arg)
{
if (domain->box_exist == 0)
error->all(FLERR,"Create_atoms command before simulation box is defined");
if (modify->nfix_restart_peratom)
error->all(FLERR,"Cannot create_atoms after "
"reading restart file with per-atom info");
// parse arguments
if (narg < 2) error->all(FLERR,"Illegal create_atoms command");
itype = atoi(arg[0]);
if (itype <= 0 || itype > atom->ntypes)
error->all(FLERR,"Invalid atom type in create_atoms command");
int iarg;
if (strcmp(arg[1],"box") == 0) {
style = BOX;
iarg = 2;
} else if (strcmp(arg[1],"region") == 0) {
style = REGION;
if (narg < 3) error->all(FLERR,"Illegal create_atoms command");
nregion = domain->find_region(arg[2]);
- if (nregion == -1) error->all(FLERR,"Create_atoms region ID does not exist");
+ if (nregion == -1) error->all(FLERR,
+ "Create_atoms region ID does not exist");
iarg = 3;;
} else if (strcmp(arg[1],"single") == 0) {
style = SINGLE;
if (narg < 5) error->all(FLERR,"Illegal create_atoms command");
xone[0] = atof(arg[2]);
xone[1] = atof(arg[3]);
xone[2] = atof(arg[4]);
iarg = 5;
} else if (strcmp(arg[1],"random") == 0) {
style = RANDOM;
if (narg < 5) error->all(FLERR,"Illegal create_atoms command");
nrandom = atoi(arg[2]);
seed = atoi(arg[3]);
if (strcmp(arg[4],"NULL") == 0) nregion = -1;
else {
nregion = domain->find_region(arg[4]);
- if (nregion == -1) error->all(FLERR,"Create_atoms region ID does not exist");
+ if (nregion == -1) error->all(FLERR,
+ "Create_atoms region ID does not exist");
}
iarg = 5;
} else error->all(FLERR,"Illegal create_atoms command");
// process optional keywords
int scaleflag = 1;
if (domain->lattice) {
nbasis = domain->lattice->nbasis;
basistype = new int[nbasis];
for (int i = 0; i < nbasis; i++) basistype[i] = itype;
}
while (iarg < narg) {
if (strcmp(arg[iarg],"basis") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal create_atoms command");
if (domain->lattice == NULL)
error->all(FLERR,"Cannot create atoms with undefined lattice");
int ibasis = atoi(arg[iarg+1]);
itype = atoi(arg[iarg+2]);
if (ibasis <= 0 || ibasis > nbasis ||
itype <= 0 || itype > atom->ntypes)
error->all(FLERR,"Illegal create_atoms command");
basistype[ibasis-1] = itype;
iarg += 3;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal create_atoms command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal create_atoms command");
iarg += 2;
} else error->all(FLERR,"Illegal create_atoms command");
}
// error checks
if (style == RANDOM) {
if (nrandom < 0) error->all(FLERR,"Illegal create_atoms command");
if (seed <= 0) error->all(FLERR,"Illegal create_atoms command");
}
// demand lattice be defined
// else setup scaling for single atom
// could use domain->lattice->lattice2box() to do conversion of
// lattice to box, but not consistent with other uses of units=lattice
// triclinic remapping occurs in add_single()
if (style == BOX || style == REGION) {
if (domain->lattice == NULL)
error->all(FLERR,"Cannot create atoms with undefined lattice");
} else if (scaleflag == 1) {
if (domain->lattice == NULL)
error->all(FLERR,"Cannot create atoms with undefined lattice");
xone[0] *= domain->lattice->xlattice;
xone[1] *= domain->lattice->ylattice;
xone[2] *= domain->lattice->zlattice;
}
// add atoms
bigint natoms_previous = atom->natoms;
int nlocal_previous = atom->nlocal;
if (style == SINGLE) add_single();
else if (style == RANDOM) add_random();
else add_lattice();
// invoke set_arrays() for fixes that need initialization of new atoms
int nlocal = atom->nlocal;
for (int m = 0; m < modify->nfix; m++) {
Fix *fix = modify->fix[m];
if (fix->create_attribute)
for (int i = nlocal_previous; i < nlocal; i++)
fix->set_arrays(i);
}
// clean up
if (domain->lattice) delete [] basistype;
// new total # of atoms
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
error->all(FLERR,"Too many total atoms");
// print status
if (comm->me == 0) {
if (screen)
fprintf(screen,"Created " BIGINT_FORMAT " atoms\n",
atom->natoms-natoms_previous);
if (logfile)
fprintf(logfile,"Created " BIGINT_FORMAT " atoms\n",
atom->natoms-natoms_previous);
}
// reset simulation now that more atoms are defined
// add tags for newly created atoms if possible
// if global map exists, reset it
// if a molecular system, set nspecial to 0 for new atoms
if (atom->natoms > MAXTAGINT) atom->tag_enable = 0;
if (atom->natoms <= MAXTAGINT) atom->tag_extend();
if (atom->map_style) {
atom->nghost = 0;
atom->map_init();
atom->map_set();
}
if (atom->molecular) {
int **nspecial = atom->nspecial;
for (int i = nlocal_previous; i < atom->nlocal; i++) {
nspecial[i][0] = 0;
nspecial[i][1] = 0;
nspecial[i][2] = 0;
}
}
}
/* ----------------------------------------------------------------------
add single atom with coords at xone if it's in my sub-box
if triclinic, xone is in lamda coords
------------------------------------------------------------------------- */
void CreateAtoms::add_single()
{
double *sublo,*subhi;
// sub-domain bounding box, in lamda units if triclinic
if (domain->triclinic == 0) {
sublo = domain->sublo;
subhi = domain->subhi;
} else {
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
}
// if triclinic, convert to lamda coords (0-1)
double lamda[3],*coord;
if (domain->triclinic) {
domain->x2lamda(xone,lamda);
coord = lamda;
} else coord = xone;
// if atom is in my subbox, create it
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2])
atom->avec->create_atom(itype,xone);
}
/* ----------------------------------------------------------------------
add Nrandom atoms at random locations
------------------------------------------------------------------------- */
void CreateAtoms::add_random()
{
double xlo,ylo,zlo,xhi,yhi,zhi,zmid;
double lamda[3],*coord;
double *sublo,*subhi,*boxlo,*boxhi;
// random number generator, same for all procs
RanPark *random = new RanPark(lmp,seed);
// bounding box for atom creation
// in real units, even if triclinic
// only limit bbox by region if its bboxflag is set (interior region)
if (domain->triclinic == 0) {
xlo = domain->boxlo[0]; xhi = domain->boxhi[0];
ylo = domain->boxlo[1]; yhi = domain->boxhi[1];
zlo = domain->boxlo[2]; zhi = domain->boxhi[2];
zmid = zlo + 0.5*(zhi-zlo);
} else {
xlo = domain->boxlo_bound[0]; xhi = domain->boxhi_bound[0];
ylo = domain->boxlo_bound[1]; yhi = domain->boxhi_bound[1];
zlo = domain->boxlo_bound[2]; zhi = domain->boxhi_bound[2];
zmid = zlo + 0.5*(zhi-zlo);
}
if (nregion >= 0 && domain->regions[nregion]->bboxflag) {
xlo = MAX(xlo,domain->regions[nregion]->extent_xlo);
xhi = MIN(xhi,domain->regions[nregion]->extent_xhi);
ylo = MAX(ylo,domain->regions[nregion]->extent_ylo);
yhi = MIN(yhi,domain->regions[nregion]->extent_yhi);
zlo = MAX(zlo,domain->regions[nregion]->extent_zlo);
zhi = MIN(zhi,domain->regions[nregion]->extent_zhi);
}
// sub-domain bounding box, in lamda units if triclinic
if (domain->triclinic == 0) {
sublo = domain->sublo;
subhi = domain->subhi;
} else {
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
}
// generate random positions for each new atom within bounding box
// iterate until atom is within region and triclinic simulation box
// if final atom position is in my subbox, create it
int valid;
for (int i = 0; i < nrandom; i++) {
while (1) {
xone[0] = xlo + random->uniform() * (xhi-xlo);
xone[1] = ylo + random->uniform() * (yhi-ylo);
xone[2] = zlo + random->uniform() * (zhi-zlo);
if (domain->dimension == 2) xone[2] = zmid;
valid = 1;
if (nregion >= 0 &&
domain->regions[nregion]->match(xone[0],xone[1],xone[2]) == 0)
valid = 0;
if (domain->triclinic) {
domain->x2lamda(xone,lamda);
coord = lamda;
if (coord[0] < boxlo[0] || coord[0] >= boxhi[0] ||
coord[1] < boxlo[1] || coord[1] >= boxhi[1] ||
coord[2] < boxlo[2] || coord[2] >= boxhi[2]) valid = 0;
} else coord = xone;
if (valid) break;
}
// if triclinic, coord is now in lamda units
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2])
atom->avec->create_atom(itype,xone);
}
// clean-up
delete random;
}
/* ----------------------------------------------------------------------
add many atoms by looping over lattice
------------------------------------------------------------------------- */
void CreateAtoms::add_lattice()
{
// convert 8 corners of my subdomain from box coords to lattice coords
// for orthogonal, use corner pts of my subbox
// for triclinic, use bounding box of my subbox
// xyz min to max = bounding box around the domain corners in lattice space
int triclinic = domain->triclinic;
double bboxlo[3],bboxhi[3];
if (triclinic == 0) {
bboxlo[0] = domain->sublo[0]; bboxhi[0] = domain->subhi[0];
bboxlo[1] = domain->sublo[1]; bboxhi[1] = domain->subhi[1];
bboxlo[2] = domain->sublo[2]; bboxhi[2] = domain->subhi[2];
} else domain->bbox(domain->sublo_lamda,domain->subhi_lamda,bboxlo,bboxhi);
double xmin,ymin,zmin,xmax,ymax,zmax;
xmin = ymin = zmin = BIG;
xmax = ymax = zmax = -BIG;
domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxlo[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxlo[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxlo[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxlo[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxhi[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxhi[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxhi[2],
xmin,ymin,zmin,xmax,ymax,zmax);
domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxhi[2],
xmin,ymin,zmin,xmax,ymax,zmax);
// ilo:ihi,jlo:jhi,klo:khi = loop bounds for lattice overlap of my subbox
// overlap = any part of a unit cell (face,edge,pt) in common with my subbox
// in lattice space, subbox is a tilted box
// but bbox of subbox is aligned with lattice axes
// so ilo:khi unit cells should completely tile bounding box
// decrement lo, increment hi to avoid round-off issues in lattice->bbox(),
// which can lead to missing atoms in rare cases
// extra decrement of lo if min < 0, since static_cast(-1.5) = -1
int ilo,ihi,jlo,jhi,klo,khi;
ilo = static_cast<int> (xmin) - 1;
jlo = static_cast<int> (ymin) - 1;
klo = static_cast<int> (zmin) - 1;
ihi = static_cast<int> (xmax) + 1;
jhi = static_cast<int> (ymax) + 1;
khi = static_cast<int> (zmax) + 1;
if (xmin < 0.0) ilo--;
if (ymin < 0.0) jlo--;
if (zmin < 0.0) klo--;
// set bounds for my proc
// if periodic:
// should create exactly 1 atom when 2 images are both "on" the boundary
// either image may be slightly inside/outside true box due to round-off
// if I am lo proc, decrement lower bound by EPSILON
// this will insure lo image is created
// if I am hi proc, decrement upper bound by 2.0*EPSILON
// this will insure hi image is not created
// thus insertion box is EPSILON smaller than true box
// and is shifted away from true boundary
// which is where atoms are likely to be generated
double epsilon[3];
if (triclinic) epsilon[0] = epsilon[1] = epsilon[2] = EPSILON;
else {
epsilon[0] = domain->prd[0] * EPSILON;
epsilon[1] = domain->prd[1] * EPSILON;
epsilon[2] = domain->prd[2] * EPSILON;
}
double sublo[3],subhi[3];
if (triclinic == 0) {
sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
} else {
sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
}
if (domain->xperiodic) {
if (comm->myloc[0] == 0) sublo[0] -= epsilon[0];
if (comm->myloc[0] == comm->procgrid[0]-1) subhi[0] -= 2.0*epsilon[0];
}
if (domain->yperiodic) {
if (comm->myloc[1] == 0) sublo[1] -= epsilon[1];
if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] -= 2.0*epsilon[1];
}
if (domain->zperiodic) {
if (comm->myloc[2] == 0) sublo[2] -= epsilon[2];
if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] -= 2.0*epsilon[2];
}
// iterate on 3d periodic lattice of unit cells using loop bounds
// iterate on nbasis atoms in each unit cell
// convert lattice coords to box coords
// add atom if it meets all criteria
double **basis = domain->lattice->basis;
double x[3],lamda[3];
double *coord;
int i,j,k,m;
for (k = klo; k <= khi; k++)
for (j = jlo; j <= jhi; j++)
for (i = ilo; i <= ihi; i++)
for (m = 0; m < nbasis; m++) {
x[0] = i + basis[m][0];
x[1] = j + basis[m][1];
x[2] = k + basis[m][2];
// convert from lattice coords to box coords
domain->lattice->lattice2box(x[0],x[1],x[2]);
// if a region was specified, test if atom is in it
if (style == REGION)
if (!domain->regions[nregion]->match(x[0],x[1],x[2])) continue;
// test if atom is in my subbox
if (triclinic) {
domain->x2lamda(x,lamda);
coord = lamda;
} else coord = x;
if (coord[0] < sublo[0] || coord[0] >= subhi[0] ||
coord[1] < sublo[1] || coord[1] >= subhi[1] ||
coord[2] < sublo[2] || coord[2] >= subhi[2]) continue;
// add the atom to my list of atoms
atom->avec->create_atom(basistype[m],x);
}
}
diff --git a/src/create_box.cpp b/src/create_box.cpp
index 7cdb03365..be437d072 100644
--- a/src/create_box.cpp
+++ b/src/create_box.cpp
@@ -1,115 +1,115 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "stdlib.h"
#include "string.h"
#include "create_box.h"
#include "atom.h"
#include "force.h"
#include "domain.h"
#include "region.h"
#include "region_prism.h"
#include "comm.h"
#include "update.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
CreateBox::CreateBox(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void CreateBox::command(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal create_box command");
if (domain->box_exist)
error->all(FLERR,"Cannot create_box after simulation box is defined");
if (domain->dimension == 2 && domain->zperiodic == 0)
error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension");
domain->box_exist = 1;
// region check
int iregion = domain->find_region(arg[1]);
if (iregion == -1) error->all(FLERR,"Create_box region ID does not exist");
if (domain->regions[iregion]->bboxflag == 0)
error->all(FLERR,"Create_box region does not support a bounding box");
// if region not prism:
// setup orthogonal domain
// set simulation domain from region extent
// if region is prism:
// seutp triclinic domain
// set simulation domain params from prism params
if (strcmp(domain->regions[iregion]->style,"prism") != 0) {
domain->triclinic = 0;
domain->boxlo[0] = domain->regions[iregion]->extent_xlo;
domain->boxhi[0] = domain->regions[iregion]->extent_xhi;
domain->boxlo[1] = domain->regions[iregion]->extent_ylo;
domain->boxhi[1] = domain->regions[iregion]->extent_yhi;
domain->boxlo[2] = domain->regions[iregion]->extent_zlo;
domain->boxhi[2] = domain->regions[iregion]->extent_zhi;
} else {
domain->triclinic = 1;
RegPrism *region = (RegPrism *) domain->regions[iregion];
domain->boxlo[0] = region->xlo;
domain->boxhi[0] = region->xhi;
domain->boxlo[1] = region->ylo;
domain->boxhi[1] = region->yhi;
domain->boxlo[2] = region->zlo;
domain->boxhi[2] = region->zhi;
domain->xy = region->xy;
domain->xz = region->xz;
domain->yz = region->yz;
}
// if molecular, zero out topology info
if (atom->molecular) {
atom->bond_per_atom = 0;
atom->angle_per_atom = 0;
atom->dihedral_per_atom = 0;
atom->improper_per_atom = 0;
atom->nbonds = 0;
atom->nangles = 0;
atom->ndihedrals = 0;
atom->nimpropers = 0;
}
// set atom and topology type quantities
atom->ntypes = atoi(arg[0]);
atom->nbondtypes = 0;
atom->nangletypes = 0;
atom->ndihedraltypes = 0;
atom->nimpropertypes = 0;
// problem setup using info from header
// no call to atom->grow since create_atoms or fixes will do it
update->ntimestep = 0;
atom->allocate_type_arrays();
domain->print_box("Created ");
domain->set_initial_box();
domain->set_global_box();
- comm->set_procs();
+ comm->set_proc_grid();
domain->set_local_box();
}
diff --git a/src/domain.cpp b/src/domain.cpp
index 3140ea6a5..54f1f528b 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -1,1288 +1,1290 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author (triclinic) : Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "math.h"
#include "domain.h"
#include "style_region.h"
#include "atom.h"
#include "force.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "region.h"
#include "lattice.h"
#include "comm.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define BIG 1.0e20
#define SMALL 1.0e-4
#define DELTA 1
enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp
/* ----------------------------------------------------------------------
default is periodic
------------------------------------------------------------------------- */
Domain::Domain(LAMMPS *lmp) : Pointers(lmp)
{
box_exist = 0;
dimension = 3;
nonperiodic = 0;
xperiodic = yperiodic = zperiodic = 1;
periodicity[0] = xperiodic;
periodicity[1] = yperiodic;
periodicity[2] = zperiodic;
boundary[0][0] = boundary[0][1] = 0;
boundary[1][0] = boundary[1][1] = 0;
boundary[2][0] = boundary[2][1] = 0;
triclinic = 0;
boxlo[0] = boxlo[1] = boxlo[2] = -0.5;
boxhi[0] = boxhi[1] = boxhi[2] = 0.5;
xy = xz = yz = 0.0;
h[3] = h[4] = h[5] = 0.0;
h_inv[3] = h_inv[4] = h_inv[5] = 0.0;
h_rate[0] = h_rate[1] = h_rate[2] =
h_rate[3] = h_rate[4] = h_rate[5] = 0.0;
h_ratelo[0] = h_ratelo[1] = h_ratelo[2] = 0.0;
prd_lamda[0] = prd_lamda[1] = prd_lamda[2] = 1.0;
prd_half_lamda[0] = prd_half_lamda[1] = prd_half_lamda[2] = 0.5;
boxlo_lamda[0] = boxlo_lamda[1] = boxlo_lamda[2] = 0.0;
boxhi_lamda[0] = boxhi_lamda[1] = boxhi_lamda[2] = 1.0;
lattice = NULL;
nregion = maxregion = 0;
regions = NULL;
}
/* ---------------------------------------------------------------------- */
Domain::~Domain()
{
delete lattice;
for (int i = 0; i < nregion; i++) delete regions[i];
memory->sfree(regions);
}
/* ---------------------------------------------------------------------- */
void Domain::init()
{
// set box_change if box dimensions/shape ever changes
// due to shrink-wrapping, fixes that change volume (npt, vol/rescale, etc)
box_change = 0;
if (nonperiodic == 2) box_change = 1;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->box_change) box_change = 1;
// check for fix deform
deform_flag = deform_vremap = deform_groupbit = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
deform_flag = 1;
if (((FixDeform *) modify->fix[i])->remapflag == V_REMAP) {
deform_vremap = 1;
deform_groupbit = modify->fix[i]->groupbit;
}
}
// region inits
for (int i = 0; i < nregion; i++) regions[i]->init();
}
/* ----------------------------------------------------------------------
set initial global box
assumes boxlo/hi and triclinic tilts are already set
------------------------------------------------------------------------- */
void Domain::set_initial_box()
{
// error checks for orthogonal and triclinic domains
if (boxlo[0] >= boxhi[0] || boxlo[1] >= boxhi[1] || boxlo[2] >= boxhi[2])
error->one(FLERR,"Box bounds are invalid");
if (triclinic) {
if (domain->dimension == 2 && (xz != 0.0 || yz != 0.0))
error->all(FLERR,"Cannot skew triclinic box in z for 2d simulation");
if (xy != 0.0 && (!xperiodic || !yperiodic))
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
if (xz != 0.0 && (!xperiodic || !zperiodic))
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
if (yz != 0.0 && (!yperiodic || !zperiodic))
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
if (fabs(xy/(boxhi[0]-boxlo[0])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
if (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
if (fabs(yz/(boxhi[1]-boxlo[1])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
}
// adjust box lo/hi for shrink-wrapped dims
if (boundary[0][0] == 2) boxlo[0] -= SMALL;
else if (boundary[0][0] == 3) minxlo = boxlo[0];
if (boundary[0][1] == 2) boxhi[0] += SMALL;
else if (boundary[0][1] == 3) minxhi = boxhi[0];
if (boundary[1][0] == 2) boxlo[1] -= SMALL;
else if (boundary[1][0] == 3) minylo = boxlo[1];
if (boundary[1][1] == 2) boxhi[1] += SMALL;
else if (boundary[1][1] == 3) minyhi = boxhi[1];
if (boundary[2][0] == 2) boxlo[2] -= SMALL;
else if (boundary[2][0] == 3) minzlo = boxlo[2];
if (boundary[2][1] == 2) boxhi[2] += SMALL;
else if (boundary[2][1] == 3) minzhi = boxhi[2];
}
/* ----------------------------------------------------------------------
set global box params
assumes boxlo/hi and triclinic tilts are already set
------------------------------------------------------------------------- */
void Domain::set_global_box()
{
prd[0] = xprd = boxhi[0] - boxlo[0];
prd[1] = yprd = boxhi[1] - boxlo[1];
prd[2] = zprd = boxhi[2] - boxlo[2];
h[0] = xprd;
h[1] = yprd;
h[2] = zprd;
h_inv[0] = 1.0/h[0];
h_inv[1] = 1.0/h[1];
h_inv[2] = 1.0/h[2];
prd_half[0] = xprd_half = 0.5*xprd;
prd_half[1] = yprd_half = 0.5*yprd;
prd_half[2] = zprd_half = 0.5*zprd;
if (triclinic) {
h[3] = yz;
h[4] = xz;
h[5] = xy;
h_inv[3] = -h[3] / (h[1]*h[2]);
h_inv[4] = (h[3]*h[5] - h[1]*h[4]) / (h[0]*h[1]*h[2]);
h_inv[5] = -h[5] / (h[0]*h[1]);
boxlo_bound[0] = MIN(boxlo[0],boxlo[0]+xy);
boxlo_bound[0] = MIN(boxlo_bound[0],boxlo_bound[0]+xz);
boxlo_bound[1] = MIN(boxlo[1],boxlo[1]+yz);
boxlo_bound[2] = boxlo[2];
boxhi_bound[0] = MAX(boxhi[0],boxhi[0]+xy);
boxhi_bound[0] = MAX(boxhi_bound[0],boxhi_bound[0]+xz);
boxhi_bound[1] = MAX(boxhi[1],boxhi[1]+yz);
boxhi_bound[2] = boxhi[2];
}
}
/* ----------------------------------------------------------------------
set lamda box params, only need be done one time
assumes global box is defined and proc assignment has been made by comm
for uppermost proc, insure subhi = 1.0 (in case round-off occurs)
------------------------------------------------------------------------- */
void Domain::set_lamda_box()
{
int *myloc = comm->myloc;
int *procgrid = comm->procgrid;
sublo_lamda[0] = 1.0*myloc[0] / procgrid[0];
sublo_lamda[1] = 1.0*myloc[1] / procgrid[1];
sublo_lamda[2] = 1.0*myloc[2] / procgrid[2];
if (myloc[0] < procgrid[0]-1)
subhi_lamda[0] = 1.0*(myloc[0]+1) / procgrid[0];
else subhi_lamda[0] = 1.0;
if (myloc[1] < procgrid[1]-1)
subhi_lamda[1] = 1.0*(myloc[1]+1) / procgrid[1];
else subhi_lamda[1] = 1.0;
if (myloc[2] < procgrid[2]-1)
subhi_lamda[2] = 1.0*(myloc[2]+1) / procgrid[2];
else subhi_lamda[2] = 1.0;
}
/* ----------------------------------------------------------------------
set local subbox params
assumes global box is defined and proc assignment has been made
for uppermost proc, insure subhi = boxhi (in case round-off occurs)
------------------------------------------------------------------------- */
void Domain::set_local_box()
{
int *myloc = comm->myloc;
int *procgrid = comm->procgrid;
if (triclinic == 0) {
sublo[0] = boxlo[0] + myloc[0] * xprd / procgrid[0];
if (myloc[0] < procgrid[0]-1)
subhi[0] = boxlo[0] + (myloc[0]+1) * xprd / procgrid[0];
else subhi[0] = boxhi[0];
sublo[1] = boxlo[1] + myloc[1] * yprd / procgrid[1];
if (myloc[1] < procgrid[1]-1)
subhi[1] = boxlo[1] + (myloc[1]+1) * yprd / procgrid[1];
else subhi[1] = boxhi[1];
sublo[2] = boxlo[2] + myloc[2] * zprd / procgrid[2];
if (myloc[2] < procgrid[2]-1)
subhi[2] = boxlo[2] + (myloc[2]+1) * zprd / procgrid[2];
else subhi[2] = boxhi[2];
}
}
/* ----------------------------------------------------------------------
reset global & local boxes due to global box boundary changes
if shrink-wrapped, determine atom extent and reset boxlo/hi
if shrink-wrapped and triclinic, perform shrink-wrap in box coords
------------------------------------------------------------------------- */
void Domain::reset_box()
{
if (nonperiodic == 2) {
// convert back to box coords for shrink-wrap operation
if (triclinic) lamda2x(atom->nlocal);
// compute extent of atoms on this proc
double extent[3][2],all[3][2];
extent[2][0] = extent[1][0] = extent[0][0] = BIG;
extent[2][1] = extent[1][1] = extent[0][1] = -BIG;
double **x = atom->x;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
extent[0][0] = MIN(extent[0][0],x[i][0]);
extent[0][1] = MAX(extent[0][1],x[i][0]);
extent[1][0] = MIN(extent[1][0],x[i][1]);
extent[1][1] = MAX(extent[1][1],x[i][1]);
extent[2][0] = MIN(extent[2][0],x[i][2]);
extent[2][1] = MAX(extent[2][1],x[i][2]);
}
// compute extent across all procs
// flip sign of MIN to do it in one Allreduce MAX
extent[0][0] = -extent[0][0];
extent[1][0] = -extent[1][0];
extent[2][0] = -extent[2][0];
MPI_Allreduce(extent,all,6,MPI_DOUBLE,MPI_MAX,world);
// in shrink-wrapped dims, set box by atom extent
// if minimum set, enforce min box size settings
if (xperiodic == 0) {
if (boundary[0][0] == 2) boxlo[0] = -all[0][0] - SMALL;
else if (boundary[0][0] == 3) boxlo[0] = MIN(-all[0][0]-SMALL,minxlo);
if (boundary[0][1] == 2) boxhi[0] = all[0][1] + SMALL;
else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+SMALL,minxhi);
if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box");
}
if (yperiodic == 0) {
if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - SMALL;
else if (boundary[1][0] == 3) boxlo[1] = MIN(-all[1][0]-SMALL,minylo);
if (boundary[1][1] == 2) boxhi[1] = all[1][1] + SMALL;
else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+SMALL,minyhi);
if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box");
}
if (zperiodic == 0) {
if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - SMALL;
else if (boundary[2][0] == 3) boxlo[2] = MIN(-all[2][0]-SMALL,minzlo);
if (boundary[2][1] == 2) boxhi[2] = all[2][1] + SMALL;
else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+SMALL,minzhi);
if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box");
}
}
set_global_box();
set_local_box();
// if shrink-wrapped, convert to lamda coords for new box
// must re-invoke pbc() b/c x2lamda result can be outside 0,1 due to roundoff
if (nonperiodic == 2 && triclinic) {
x2lamda(atom->nlocal);
pbc();
}
}
/* ----------------------------------------------------------------------
enforce PBC and modify box image flags for each atom
called every reneighboring and by other commands that change atoms
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
if fix deform, remap velocity of fix group atoms by box edge velocities
for triclinic, atoms must be in lamda coords (0-1) before pbc is called
image = 10 bits for each dimension
increment/decrement in wrap-around fashion
------------------------------------------------------------------------- */
void Domain::pbc()
{
int i,idim,otherdims;
double *lo,*hi,*period;
int nlocal = atom->nlocal;
double **x = atom->x;
double **v = atom->v;
int *mask = atom->mask;
int *image = atom->image;
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
}
for (i = 0; i < nlocal; i++) {
if (xperiodic) {
if (x[i][0] < lo[0]) {
x[i][0] += period[0];
if (deform_vremap && mask[i] & deform_groupbit) v[i][0] += h_rate[0];
idim = image[i] & 1023;
otherdims = image[i] ^ idim;
idim--;
idim &= 1023;
image[i] = otherdims | idim;
}
if (x[i][0] >= hi[0]) {
x[i][0] -= period[0];
x[i][0] = MAX(x[i][0],lo[0]);
if (deform_vremap && mask[i] & deform_groupbit) v[i][0] -= h_rate[0];
idim = image[i] & 1023;
otherdims = image[i] ^ idim;
idim++;
idim &= 1023;
image[i] = otherdims | idim;
}
}
if (yperiodic) {
if (x[i][1] < lo[1]) {
x[i][1] += period[1];
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] += h_rate[5];
v[i][1] += h_rate[1];
}
idim = (image[i] >> 10) & 1023;
otherdims = image[i] ^ (idim << 10);
idim--;
idim &= 1023;
image[i] = otherdims | (idim << 10);
}
if (x[i][1] >= hi[1]) {
x[i][1] -= period[1];
x[i][1] = MAX(x[i][1],lo[1]);
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] -= h_rate[5];
v[i][1] -= h_rate[1];
}
idim = (image[i] >> 10) & 1023;
otherdims = image[i] ^ (idim << 10);
idim++;
idim &= 1023;
image[i] = otherdims | (idim << 10);
}
}
if (zperiodic) {
if (x[i][2] < lo[2]) {
x[i][2] += period[2];
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] += h_rate[4];
v[i][1] += h_rate[3];
v[i][2] += h_rate[2];
}
idim = image[i] >> 20;
otherdims = image[i] ^ (idim << 20);
idim--;
idim &= 1023;
image[i] = otherdims | (idim << 20);
}
if (x[i][2] >= hi[2]) {
x[i][2] -= period[2];
x[i][2] = MAX(x[i][2],lo[2]);
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] -= h_rate[4];
v[i][1] -= h_rate[3];
v[i][2] -= h_rate[2];
}
idim = image[i] >> 20;
otherdims = image[i] ^ (idim << 20);
idim++;
idim &= 1023;
image[i] = otherdims | (idim << 20);
}
}
}
}
/* ----------------------------------------------------------------------
minimum image convention check
return 1 if any distance > 1/2 of box size
------------------------------------------------------------------------- */
int Domain::minimum_image_check(double dx, double dy, double dz)
{
if (xperiodic && fabs(dx) > xprd_half) return 1;
if (yperiodic && fabs(dy) > yprd_half) return 1;
if (zperiodic && fabs(dz) > zprd_half) return 1;
return 0;
}
/* ----------------------------------------------------------------------
minimum image convention
use 1/2 of box size as test
for triclinic, also add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::minimum_image(double &dx, double &dy, double &dz)
{
if (triclinic == 0) {
if (xperiodic) {
if (fabs(dx) > xprd_half) {
if (dx < 0.0) dx += xprd;
else dx -= xprd;
}
}
if (yperiodic) {
if (fabs(dy) > yprd_half) {
if (dy < 0.0) dy += yprd;
else dy -= yprd;
}
}
if (zperiodic) {
if (fabs(dz) > zprd_half) {
if (dz < 0.0) dz += zprd;
else dz -= zprd;
}
}
} else {
if (zperiodic) {
if (fabs(dz) > zprd_half) {
if (dz < 0.0) {
dz += zprd;
dy += yz;
dx += xz;
} else {
dz -= zprd;
dy -= yz;
dx -= xz;
}
}
}
if (yperiodic) {
if (fabs(dy) > yprd_half) {
if (dy < 0.0) {
dy += yprd;
dx += xy;
} else {
dy -= yprd;
dx -= xy;
}
}
}
if (xperiodic) {
if (fabs(dx) > xprd_half) {
if (dx < 0.0) dx += xprd;
else dx -= xprd;
}
}
}
}
/* ----------------------------------------------------------------------
minimum image convention
use 1/2 of box size as test
for triclinic, also add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::minimum_image(double *delta)
{
if (triclinic == 0) {
if (xperiodic) {
if (fabs(delta[0]) > xprd_half) {
if (delta[0] < 0.0) delta[0] += xprd;
else delta[0] -= xprd;
}
}
if (yperiodic) {
if (fabs(delta[1]) > yprd_half) {
if (delta[1] < 0.0) delta[1] += yprd;
else delta[1] -= yprd;
}
}
if (zperiodic) {
if (fabs(delta[2]) > zprd_half) {
if (delta[2] < 0.0) delta[2] += zprd;
else delta[2] -= zprd;
}
}
} else {
if (zperiodic) {
if (fabs(delta[2]) > zprd_half) {
if (delta[2] < 0.0) {
delta[2] += zprd;
delta[1] += yz;
delta[0] += xz;
} else {
delta[2] -= zprd;
delta[1] -= yz;
delta[0] -= xz;
}
}
}
if (yperiodic) {
if (fabs(delta[1]) > yprd_half) {
if (delta[1] < 0.0) {
delta[1] += yprd;
delta[0] += xy;
} else {
delta[1] -= yprd;
delta[0] -= xy;
}
}
}
if (xperiodic) {
if (fabs(delta[0]) > xprd_half) {
if (delta[0] < 0.0) delta[0] += xprd;
else delta[0] -= xprd;
}
}
}
}
/* ----------------------------------------------------------------------
find Xj image = periodic image of Xj that is closest to Xi
for triclinic, also add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
-void Domain::closest_image(const double * const xi, const double * const xj, double * const xjimage)
+void Domain::closest_image(const double * const xi,
+ const double * const xj,
+ double * const xjimage)
{
double dx,dy,dz;
if (triclinic == 0) {
if (xperiodic) {
dx = xj[0] - xi[0];
if (dx < 0.0) {
while (dx < 0.0) dx += xprd;
if (dx > xprd_half) dx -= xprd;
} else {
while (dx > 0.0) dx -= xprd;
if (dx < -xprd_half) dx += xprd;
}
xjimage[0] = xi[0] + dx;
}
if (yperiodic) {
dy = xj[1] - xi[1];
if (dy < 0.0) {
while (dy < 0.0) dy += yprd;
if (dy > yprd_half) dy -= yprd;
} else {
while (dy > 0.0) dy -= yprd;
if (dy < -yprd_half) dy += yprd;
}
xjimage[1] = xi[1] + dy;
}
if (zperiodic) {
dz = xj[2] - xi[2];
if (dz < 0.0) {
while (dz < 0.0) dz += zprd;
if (dz > zprd_half) dz -= zprd;
} else {
while (dz > 0.0) dz -= zprd;
if (dz < -zprd_half) dz += zprd;
}
xjimage[2] = xi[2] + dz;
}
} else {
dx = xj[0] - xi[0];
dy = xj[1] - xi[1];
dz = xj[2] - xi[2];
if (zperiodic) {
if (dz < 0.0) {
while (dz < 0.0) {
dz += zprd;
dy += yz;
dx += xz;
}
if (dz > zprd_half) {
dz -= zprd;
dy -= yz;
dx -= xz;
}
} else {
while (dz > 0.0) {
dz -= zprd;
dy -= yz;
dx -= xz;
}
if (dz < -zprd_half) {
dz += zprd;
dy += yz;
dx += xz;
}
}
}
if (yperiodic) {
if (dy < 0.0) {
while (dy < 0.0) {
dy += yprd;
dx += xy;
}
if (dy > yprd_half) {
dy -= yprd;
dx -= xy;
}
} else {
while (dy > 0.0) {
dy -= yprd;
dx -= xy;
}
if (dy < -yprd_half) {
dy += yprd;
dx += xy;
}
}
}
if (xperiodic) {
if (dx < 0.0) {
while (dx < 0.0) dx += xprd;
if (dx > xprd_half) dx -= xprd;
} else {
while (dx > 0.0) dx -= xprd;
if (dx < -xprd_half) dx += xprd;
}
}
xjimage[0] = xi[0] + dx;
xjimage[1] = xi[1] + dy;
xjimage[2] = xi[2] + dz;
}
}
/* ----------------------------------------------------------------------
remap the point into the periodic box no matter how far away
adjust image accordingly
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
for triclinic, point is converted to lamda coords (0-1) before doing remap
image = 10 bits for each dimension
increment/decrement in wrap-around fashion
------------------------------------------------------------------------- */
void Domain::remap(double *x, int &image)
{
double *lo,*hi,*period,*coord;
double lamda[3];
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
coord = x;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
x2lamda(x,lamda);
coord = lamda;
}
if (xperiodic) {
while (coord[0] < lo[0]) {
coord[0] += period[0];
int idim = image & 1023;
int otherdims = image ^ idim;
idim--;
idim &= 1023;
image = otherdims | idim;
}
while (coord[0] >= hi[0]) {
coord[0] -= period[0];
int idim = image & 1023;
int otherdims = image ^ idim;
idim++;
idim &= 1023;
image = otherdims | idim;
}
coord[0] = MAX(coord[0],lo[0]);
}
if (yperiodic) {
while (coord[1] < lo[1]) {
coord[1] += period[1];
int idim = (image >> 10) & 1023;
int otherdims = image ^ (idim << 10);
idim--;
idim &= 1023;
image = otherdims | (idim << 10);
}
while (coord[1] >= hi[1]) {
coord[1] -= period[1];
int idim = (image >> 10) & 1023;
int otherdims = image ^ (idim << 10);
idim++;
idim &= 1023;
image = otherdims | (idim << 10);
}
coord[1] = MAX(coord[1],lo[1]);
}
if (zperiodic) {
while (coord[2] < lo[2]) {
coord[2] += period[2];
int idim = image >> 20;
int otherdims = image ^ (idim << 20);
idim--;
idim &= 1023;
image = otherdims | (idim << 20);
}
while (coord[2] >= hi[2]) {
coord[2] -= period[2];
int idim = image >> 20;
int otherdims = image ^ (idim << 20);
idim++;
idim &= 1023;
image = otherdims | (idim << 20);
}
coord[2] = MAX(coord[2],lo[2]);
}
if (triclinic) lamda2x(coord,x);
}
/* ----------------------------------------------------------------------
remap the point into the periodic box no matter how far away
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
for triclinic, point is converted to lamda coords (0-1) before remap
------------------------------------------------------------------------- */
void Domain::remap(double *x)
{
double *lo,*hi,*period,*coord;
double lamda[3];
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
coord = x;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
x2lamda(x,lamda);
coord = lamda;
}
if (xperiodic) {
while (coord[0] < lo[0]) coord[0] += period[0];
while (coord[0] >= hi[0]) coord[0] -= period[0];
coord[0] = MAX(coord[0],lo[0]);
}
if (yperiodic) {
while (coord[1] < lo[1]) coord[1] += period[1];
while (coord[1] >= hi[1]) coord[1] -= period[1];
coord[1] = MAX(coord[1],lo[1]);
}
if (zperiodic) {
while (coord[2] < lo[2]) coord[2] += period[2];
while (coord[2] >= hi[2]) coord[2] -= period[2];
coord[2] = MAX(coord[2],lo[2]);
}
if (triclinic) lamda2x(coord,x);
}
/* ----------------------------------------------------------------------
remap xnew to be within half box length of xold
do it directly, not iteratively, in case is far away
for triclinic, both points are converted to lamda coords (0-1) before remap
------------------------------------------------------------------------- */
void Domain::remap_near(double *xnew, double *xold)
{
int n;
double *coordnew,*coordold,*period,*half;
double lamdanew[3],lamdaold[3];
if (triclinic == 0) {
period = prd;
half = prd_half;
coordnew = xnew;
coordold = xold;
} else {
period = prd_lamda;
half = prd_half_lamda;
x2lamda(xnew,lamdanew);
coordnew = lamdanew;
x2lamda(xold,lamdaold);
coordold = lamdaold;
}
// iterative form
// if (xperiodic) {
// while (xnew[0]-xold[0] > half[0]) xnew[0] -= period[0];
// while (xold[0]-xnew[0] > half[0]) xnew[0] += period[0];
// }
if (xperiodic) {
if (coordnew[0]-coordold[0] > period[0]) {
n = static_cast<int> ((coordnew[0]-coordold[0])/period[0]);
xnew[0] -= n*period[0];
}
while (xnew[0]-xold[0] > half[0]) xnew[0] -= period[0];
if (xold[0]-xnew[0] > period[0]) {
n = static_cast<int> ((xold[0]-xnew[0])/period[0]);
xnew[0] += n*period[0];
}
while (xold[0]-xnew[0] > half[0]) xnew[0] += period[0];
}
if (yperiodic) {
if (coordnew[1]-coordold[1] > period[1]) {
n = static_cast<int> ((coordnew[1]-coordold[1])/period[1]);
xnew[1] -= n*period[1];
}
while (xnew[1]-xold[1] > half[1]) xnew[1] -= period[1];
if (xold[1]-xnew[1] > period[1]) {
n = static_cast<int> ((xold[1]-xnew[1])/period[1]);
xnew[1] += n*period[1];
}
while (xold[1]-xnew[1] > half[1]) xnew[1] += period[1];
}
if (zperiodic) {
if (coordnew[2]-coordold[2] > period[2]) {
n = static_cast<int> ((coordnew[2]-coordold[2])/period[2]);
xnew[2] -= n*period[2];
}
while (xnew[2]-xold[2] > half[2]) xnew[2] -= period[2];
if (xold[2]-xnew[2] > period[2]) {
n = static_cast<int> ((xold[2]-xnew[2])/period[2]);
xnew[2] += n*period[2];
}
while (xold[2]-xnew[2] > half[2]) xnew[2] += period[2];
}
if (triclinic) {
lamda2x(coordnew,xnew);
lamda2x(coordold,xold);
}
}
/* ----------------------------------------------------------------------
unmap the point via image flags
x overwritten with result, don't reset image flag
for triclinic, use h[] to add in tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::unmap(double *x, int image)
{
int xbox = (image & 1023) - 512;
int ybox = (image >> 10 & 1023) - 512;
int zbox = (image >> 20) - 512;
if (triclinic == 0) {
x[0] += xbox*xprd;
x[1] += ybox*yprd;
x[2] += zbox*zprd;
} else {
x[0] += h[0]*xbox + h[5]*ybox + h[4]*zbox;
x[1] += h[1]*ybox + h[3]*zbox;
x[2] += h[2]*zbox;
}
}
/* ----------------------------------------------------------------------
unmap the point via image flags
result returned in y, don't reset image flag
for triclinic, use h[] to add in tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::unmap(double *x, int image, double *y)
{
int xbox = (image & 1023) - 512;
int ybox = (image >> 10 & 1023) - 512;
int zbox = (image >> 20) - 512;
if (triclinic == 0) {
y[0] = x[0] + xbox*xprd;
y[1] = x[1] + ybox*yprd;
y[2] = x[2] + zbox*zprd;
} else {
y[0] = x[0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
y[1] = x[1] + h[1]*ybox + h[3]*zbox;
y[2] = x[2] + h[2]*zbox;
}
}
/* ----------------------------------------------------------------------
create a lattice
delete it if style = none
------------------------------------------------------------------------- */
void Domain::set_lattice(int narg, char **arg)
{
if (lattice) delete lattice;
lattice = new Lattice(lmp,narg,arg);
if (lattice->style == 0) {
delete lattice;
lattice = NULL;
}
}
/* ----------------------------------------------------------------------
create a new region
------------------------------------------------------------------------- */
void Domain::add_region(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Illegal region command");
if (strcmp(arg[1],"delete") == 0) {
delete_region(narg,arg);
return;
}
if (find_region(arg[0]) >= 0) error->all(FLERR,"Reuse of region ID");
// extend Region list if necessary
if (nregion == maxregion) {
maxregion += DELTA;
regions = (Region **)
memory->srealloc(regions,maxregion*sizeof(Region *),"domain:regions");
}
// create the Region
if (strcmp(arg[1],"none") == 0) error->all(FLERR,"Invalid region style");
#define REGION_CLASS
#define RegionStyle(key,Class) \
else if (strcmp(arg[1],#key) == 0) \
regions[nregion] = new Class(lmp,narg,arg);
#include "style_region.h"
#undef REGION_CLASS
else error->all(FLERR,"Invalid region style");
nregion++;
}
/* ----------------------------------------------------------------------
delete a region
------------------------------------------------------------------------- */
void Domain::delete_region(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal region command");
int iregion = find_region(arg[0]);
if (iregion == -1) error->all(FLERR,"Delete region ID does not exist");
delete regions[iregion];
regions[iregion] = regions[nregion-1];
nregion--;
}
/* ----------------------------------------------------------------------
return region index if name matches existing region ID
return -1 if no such region
------------------------------------------------------------------------- */
int Domain::find_region(char *name)
{
for (int iregion = 0; iregion < nregion; iregion++)
if (strcmp(name,regions[iregion]->id) == 0) return iregion;
return -1;
}
/* ----------------------------------------------------------------------
boundary settings from the input script
------------------------------------------------------------------------- */
void Domain::set_boundary(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Illegal boundary command");
char c;
for (int idim = 0; idim < 3; idim++)
for (int iside = 0; iside < 2; iside++) {
if (iside == 0) c = arg[idim][0];
else if (iside == 1 && strlen(arg[idim]) == 1) c = arg[idim][0];
else c = arg[idim][1];
if (c == 'p') boundary[idim][iside] = 0;
else if (c == 'f') boundary[idim][iside] = 1;
else if (c == 's') boundary[idim][iside] = 2;
else if (c == 'm') boundary[idim][iside] = 3;
else error->all(FLERR,"Illegal boundary command");
}
for (int idim = 0; idim < 3; idim++)
if ((boundary[idim][0] == 0 && boundary[idim][1]) ||
(boundary[idim][0] && boundary[idim][1] == 0))
error->all(FLERR,"Both sides of boundary must be periodic");
if (boundary[0][0] == 0) xperiodic = 1;
else xperiodic = 0;
if (boundary[1][0] == 0) yperiodic = 1;
else yperiodic = 0;
if (boundary[2][0] == 0) zperiodic = 1;
else zperiodic = 0;
periodicity[0] = xperiodic;
periodicity[1] = yperiodic;
periodicity[2] = zperiodic;
nonperiodic = 0;
if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
nonperiodic = 1;
if (boundary[0][0] >= 2 || boundary[0][1] >= 2 ||
boundary[1][0] >= 2 || boundary[1][1] >= 2 ||
boundary[2][0] >= 2 || boundary[2][1] >= 2) nonperiodic = 2;
}
}
/* ----------------------------------------------------------------------
print box info, orthogonal or triclinic
------------------------------------------------------------------------- */
void Domain::print_box(const char *str)
{
if (comm->me == 0) {
if (screen) {
if (triclinic == 0)
fprintf(screen,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n",
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]);
else {
char *format = (char *)
"%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n";
fprintf(screen,format,
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2],
xy,xz,yz);
}
}
if (logfile) {
if (triclinic == 0)
fprintf(logfile,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n",
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]);
else {
char *format = (char *)
"%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n";
fprintf(logfile,format,
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2],
xy,xz,yz);
}
}
}
}
/* ----------------------------------------------------------------------
convert triclinic 0-1 lamda coords to box coords for all N atoms
x = H lamda + x0;
------------------------------------------------------------------------- */
void Domain::lamda2x(int n)
{
double **x = atom->x;
for (int i = 0; i < n; i++) {
x[i][0] = h[0]*x[i][0] + h[5]*x[i][1] + h[4]*x[i][2] + boxlo[0];
x[i][1] = h[1]*x[i][1] + h[3]*x[i][2] + boxlo[1];
x[i][2] = h[2]*x[i][2] + boxlo[2];
}
}
/* ----------------------------------------------------------------------
convert box coords to triclinic 0-1 lamda coords for all N atoms
lamda = H^-1 (x - x0)
------------------------------------------------------------------------- */
void Domain::x2lamda(int n)
{
double delta[3];
double **x = atom->x;
for (int i = 0; i < n; i++) {
delta[0] = x[i][0] - boxlo[0];
delta[1] = x[i][1] - boxlo[1];
delta[2] = x[i][2] - boxlo[2];
x[i][0] = h_inv[0]*delta[0] + h_inv[5]*delta[1] + h_inv[4]*delta[2];
x[i][1] = h_inv[1]*delta[1] + h_inv[3]*delta[2];
x[i][2] = h_inv[2]*delta[2];
}
}
/* ----------------------------------------------------------------------
convert triclinic 0-1 lamda coords to box coords for one atom
x = H lamda + x0;
lamda and x can point to same 3-vector
------------------------------------------------------------------------- */
void Domain::lamda2x(double *lamda, double *x)
{
x[0] = h[0]*lamda[0] + h[5]*lamda[1] + h[4]*lamda[2] + boxlo[0];
x[1] = h[1]*lamda[1] + h[3]*lamda[2] + boxlo[1];
x[2] = h[2]*lamda[2] + boxlo[2];
}
/* ----------------------------------------------------------------------
convert box coords to triclinic 0-1 lamda coords for one atom
lamda = H^-1 (x - x0)
x and lamda can point to same 3-vector
------------------------------------------------------------------------- */
void Domain::x2lamda(double *x, double *lamda)
{
double delta[3];
delta[0] = x[0] - boxlo[0];
delta[1] = x[1] - boxlo[1];
delta[2] = x[2] - boxlo[2];
lamda[0] = h_inv[0]*delta[0] + h_inv[5]*delta[1] + h_inv[4]*delta[2];
lamda[1] = h_inv[1]*delta[1] + h_inv[3]*delta[2];
lamda[2] = h_inv[2]*delta[2];
}
/* ----------------------------------------------------------------------
convert 8 lamda corner pts of lo/hi box to box coords
return bboxlo/hi = bounding box around 8 corner pts in box coords
------------------------------------------------------------------------- */
void Domain::bbox(double *lo, double *hi, double *bboxlo, double *bboxhi)
{
double x[3];
bboxlo[0] = bboxlo[1] = bboxlo[2] = BIG;
bboxhi[0] = bboxhi[1] = bboxhi[2] = -BIG;
x[0] = lo[0]; x[1] = lo[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = lo[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = hi[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = hi[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = lo[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = lo[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = hi[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = hi[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
}
/* ----------------------------------------------------------------------
compute 8 corner pts of triclinic box
8 are ordered with x changing fastest, then y, finally z
could be more efficient if just coded with xy,yz,xz explicitly
------------------------------------------------------------------------- */
void Domain::box_corners()
{
corners[0][0] = 0.0; corners[0][1] = 0.0; corners[0][2] = 0.0;
lamda2x(corners[0],corners[0]);
corners[1][0] = 1.0; corners[1][1] = 0.0; corners[1][2] = 0.0;
lamda2x(corners[1],corners[1]);
corners[2][0] = 0.0; corners[2][1] = 1.0; corners[2][2] = 0.0;
lamda2x(corners[2],corners[2]);
corners[3][0] = 1.0; corners[3][1] = 1.0; corners[3][2] = 0.0;
lamda2x(corners[3],corners[3]);
corners[4][0] = 0.0; corners[4][1] = 0.0; corners[4][2] = 1.0;
lamda2x(corners[4],corners[4]);
corners[5][0] = 1.0; corners[5][1] = 0.0; corners[5][2] = 1.0;
lamda2x(corners[5],corners[5]);
corners[6][0] = 0.0; corners[6][1] = 1.0; corners[6][2] = 1.0;
lamda2x(corners[6],corners[6]);
corners[7][0] = 1.0; corners[7][1] = 1.0; corners[7][2] = 1.0;
lamda2x(corners[7],corners[7]);
}
diff --git a/src/error.cpp b/src/error.cpp
index c9297eb75..9465a6f97 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -1,147 +1,154 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "stdlib.h"
#include "error.h"
#include "universe.h"
#include "memory.h"
#include "output.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Error::Error(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
called by all procs in universe
close all output, screen, and log files in world and universe
+ no abort, so insure all procs in universe call, else will hang
------------------------------------------------------------------------- */
void Error::universe_all(const char *file, int line, const char *str)
{
MPI_Barrier(universe->uworld);
if (universe->me == 0) {
if (universe->uscreen) fprintf(universe->uscreen,
"ERROR: %s (%s:%d)\n",str,file,line);
if (universe->ulogfile) fprintf(universe->ulogfile,
"ERROR: %s (%s:%d)\n",str,file,line);
}
if (output) delete output;
if (universe->nworlds > 1) {
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
}
if (universe->ulogfile) fclose(universe->ulogfile);
MPI_Finalize();
exit(1);
}
/* ----------------------------------------------------------------------
called by one proc in universe
+ forces abort of entire universe if any proc in universe calls
------------------------------------------------------------------------- */
void Error::universe_one(const char *file, int line, const char *str)
{
if (universe->uscreen)
fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
universe->me,str,file,line);
MPI_Abort(universe->uworld,1);
}
/* ----------------------------------------------------------------------
called by all procs in one world
close all output, screen, and log files in world
+ insure all procs in world call, else will hang
+ force MPI_Abort if running in multi-partition mode
------------------------------------------------------------------------- */
void Error::all(const char *file, int line, const char *str)
{
MPI_Barrier(world);
int me;
MPI_Comm_rank(world,&me);
if (me == 0) {
if (screen) fprintf(screen,"ERROR: %s (%s:%d)\n",str,file,line);
if (logfile) fprintf(logfile,"ERROR: %s (%s:%d)\n",str,file,line);
}
if (output) delete output;
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
+ if (universe->nworlds > 1) MPI_Abort(universe->uworld,1);
MPI_Finalize();
exit(1);
}
/* ----------------------------------------------------------------------
called by one proc in world
write to world screen only if non-NULL on this proc
always write to universe screen
+ forces abort of entire world (and universe) if any proc in world calls
------------------------------------------------------------------------- */
void Error::one(const char *file, int line, const char *str)
{
int me;
MPI_Comm_rank(world,&me);
if (screen) fprintf(screen,"ERROR on proc %d: %s (%s:%d)\n",
me,str,file,line);
if (universe->nworlds > 1)
fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
universe->me,str,file,line);
MPI_Abort(world,1);
}
/* ----------------------------------------------------------------------
called by one proc in world
only write to screen if non-NULL on this proc since could be file
------------------------------------------------------------------------- */
void Error::warning(const char *file, int line, const char *str, int logflag)
{
if (screen) fprintf(screen,"WARNING: %s (%s:%d)\n",str,file,line);
if (logflag && logfile) fprintf(logfile,"WARNING: %s (%s:%d)\n",
str,file,line);
}
/* ----------------------------------------------------------------------
called by one proc in world, typically proc 0
write message to screen and logfile (if logflag is set)
------------------------------------------------------------------------- */
void Error::message(const char *file, int line, char *str, int logflag)
{
if (screen) fprintf(screen,"%s (%s:%d)\n",str,file,line);
if (logflag && logfile) fprintf(logfile,"%s (%s:%d)\n",str,file,line);
}
/* ----------------------------------------------------------------------
called by all procs in one world
close all output, screen, and log files in world
+ no abort, so insure all procs in world call, else will hang
------------------------------------------------------------------------- */
void Error::done()
{
MPI_Barrier(world);
if (output) delete output;
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
MPI_Finalize();
exit(1);
}
diff --git a/src/finish.cpp b/src/finish.cpp
index fb43f1c7b..92f6e45b2 100644
--- a/src/finish.cpp
+++ b/src/finish.cpp
@@ -1,670 +1,678 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "math.h"
#include "string.h"
#include "stdio.h"
#include "finish.h"
#include "timer.h"
+#include "universe.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "kspace.h"
#include "update.h"
#include "min.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "output.h"
#include "memory.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Finish::Finish(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void Finish::end(int flag)
{
int i,m,nneigh,nneighfull;
int histo[10];
int loopflag,minflag,prdflag,tadflag,timeflag,fftflag,histoflag,neighflag;
double time,tmp,ave,max,min;
double time_loop,time_other;
int me,nprocs;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
// choose flavors of statistical output
// flag determines caller
// flag = 0 = just loop summary
// flag = 1 = dynamics or minimization
// flag = 2 = PRD
// flag = 3 = TAD
-
+ // turn off neighflag for Kspace partition of verlet/split integrator
+
loopflag = 1;
minflag = prdflag = tadflag = timeflag = fftflag = histoflag = neighflag = 0;
if (flag == 1) {
if (update->whichflag == 2) minflag = 1;
- timeflag = histoflag = neighflag = 1;
- if (strstr(force->kspace_style,"pppm")) fftflag = 1;
+ timeflag = histoflag = 1;
+ neighflag = 1;
+ if (update->whichflag == 1 &&
+ strcmp(update->integrate_style,"verlet/split") == 0 &&
+ universe->iworld == 1) neighflag = 0;
+ if (force->kspace && force->kspace_match("pppm",0)) fftflag = 1;
}
if (flag == 2) prdflag = histoflag = neighflag = 1;
if (flag == 3) tadflag = histoflag = neighflag = 1;
// loop stats
if (loopflag) {
time_other = timer->array[TIME_LOOP] -
(timer->array[TIME_PAIR] + timer->array[TIME_BOND] +
timer->array[TIME_KSPACE] + timer->array[TIME_NEIGHBOR] +
timer->array[TIME_COMM] + timer->array[TIME_OUTPUT]);
time_loop = timer->array[TIME_LOOP];
MPI_Allreduce(&time_loop,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time_loop = tmp/nprocs;
// overall loop time
#if defined(_OPENMP)
if (me == 0) {
int ntasks = nprocs * comm->nthreads;
if (screen) fprintf(screen,
"Loop time of %g on %d procs (%d MPI x %d OpenMP) "
"for %d steps with " BIGINT_FORMAT " atoms\n",
time_loop,ntasks,nprocs,comm->nthreads,
update->nsteps,atom->natoms);
if (logfile) fprintf(logfile,
"Loop time of %g on %d procs (%d MPI x %d OpenMP) "
"for %d steps with " BIGINT_FORMAT " atoms\n",
time_loop,ntasks,nprocs,comm->nthreads,
update->nsteps,atom->natoms);
}
#else
if (me == 0) {
if (screen) fprintf(screen,
"Loop time of %g on %d procs for %d steps with "
BIGINT_FORMAT " atoms\n",
time_loop,nprocs,update->nsteps,atom->natoms);
if (logfile) fprintf(logfile,
"Loop time of %g on %d procs for %d steps with "
BIGINT_FORMAT " atoms\n",
time_loop,nprocs,update->nsteps,atom->natoms);
}
#endif
if (time_loop == 0.0) time_loop = 1.0;
}
// minimization stats
if (minflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
if (me == 0) {
if (screen) {
fprintf(screen,"Minimization stats:\n");
fprintf(screen," Stopping criterion = %s\n",
update->minimize->stopstr);
fprintf(screen," Energy initial, next-to-last, final = \n"
" %18.12g %18.12g %18.12g\n",
update->minimize->einitial,update->minimize->eprevious,
update->minimize->efinal);
fprintf(screen," Force two-norm initial, final = %g %g\n",
update->minimize->fnorm2_init,update->minimize->fnorm2_final);
fprintf(screen," Force max component initial, final = %g %g\n",
update->minimize->fnorminf_init,
update->minimize->fnorminf_final);
fprintf(screen," Final line search alpha, max atom move = %g %g\n",
update->minimize->alpha_final,
update->minimize->alpha_final*
update->minimize->fnorminf_final);
fprintf(screen," Iterations, force evaluations = %d %d\n",
update->minimize->niter,update->minimize->neval);
}
if (logfile) {
fprintf(logfile,"Minimization stats:\n");
fprintf(logfile," Stopping criterion = %s\n",
update->minimize->stopstr);
fprintf(logfile," Energy initial, next-to-last, final = \n"
" %18.12g %18.12g %18.12g\n",
update->minimize->einitial,update->minimize->eprevious,
update->minimize->efinal);
fprintf(logfile," Force two-norm initial, final = %g %g\n",
update->minimize->fnorm2_init,update->minimize->fnorm2_final);
fprintf(logfile," Force max component initial, final = %g %g\n",
update->minimize->fnorminf_init,
update->minimize->fnorminf_final);
fprintf(logfile," Final line search alpha, max atom move = %g %g\n",
update->minimize->alpha_final,
update->minimize->alpha_final*
update->minimize->fnorminf_final);
fprintf(logfile," Iterations, force evaluations = %d %d\n",
update->minimize->niter,update->minimize->neval);
}
}
}
// PRD stats using PAIR,BOND,KSPACE for dephase,dynamics,quench
if (prdflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
if (screen) fprintf(screen,"PRD stats:\n");
if (logfile) fprintf(logfile,"PRD stats:\n");
time = timer->array[TIME_PAIR];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Dephase time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Dephase time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_BOND];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Dynamics time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Dynamics time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_KSPACE];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Quench time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Quench time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
}
// TAD stats using PAIR,BOND,KSPACE for neb,dynamics,quench
if (tadflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
if (screen) fprintf(screen,"TAD stats:\n");
if (logfile) fprintf(logfile,"TAD stats:\n");
time = timer->array[TIME_PAIR];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," NEB time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," NEB time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_BOND];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Dynamics time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Dynamics time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_KSPACE];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Quench time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Quench time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_COMM];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Comm time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Comm time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_OUTPUT];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Output time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Output time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen," Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile," Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
}
// timing breakdowns
if (timeflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
time = timer->array[TIME_PAIR];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Pair time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Pair time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
if (atom->molecular) {
time = timer->array[TIME_BOND];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Bond time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Bond time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
}
if (force->kspace) {
time = timer->array[TIME_KSPACE];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Kspce time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Kspce time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
}
time = timer->array[TIME_NEIGHBOR];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Neigh time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Neigh time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_COMM];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Comm time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Comm time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = timer->array[TIME_OUTPUT];
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Outpt time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Outpt time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) {
if (screen)
fprintf(screen,"Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
if (logfile)
fprintf(logfile,"Other time (%%) = %g (%g)\n",
time,time/time_loop*100.0);
}
}
// FFT timing statistics
// time3d,time1d = total time during run for 3d and 1d FFTs
+ // time_kspace may be 0.0 if another partition is doing Kspace
if (fftflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
int nsteps = update->nsteps;
int nsample = 5;
double time3d,time1d;
force->kspace->timing(nsample,time3d,time1d);
time3d = nsteps * time3d / nsample;
MPI_Allreduce(&time3d,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time3d = tmp/nprocs;
time1d = nsteps * time1d / nsample;
MPI_Allreduce(&time1d,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time1d = tmp/nprocs;
double time_kspace = timer->array[TIME_KSPACE];
MPI_Allreduce(&time_kspace,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time_kspace = tmp/nprocs;
double ntotal = 1.0 * force->kspace->nx_pppm *
force->kspace->ny_pppm * force->kspace->nz_pppm;
double nflops = 5.0 * ntotal * log(ntotal);
double fraction,flop3,flop1;
if (nsteps) {
- fraction = time3d/time_kspace*100.0;
+ if (time_kspace) fraction = time3d/time_kspace*100.0;
+ else fraction = 0.0;
flop3 = nflops/1.0e9/(time3d/4.0/nsteps);
flop1 = nflops/1.0e9/(time1d/4.0/nsteps);
} else fraction = flop3 = flop1 = 0.0;
if (me == 0) {
if (screen) {
fprintf(screen,"FFT time (%% of Kspce) = %g (%g)\n",time3d,fraction);
fprintf(screen,"FFT Gflps 3d (1d only) = %g %g\n",flop3,flop1);
}
if (logfile) {
fprintf(logfile,"FFT time (%% of Kspce) = %g (%g)\n",time3d,fraction);
fprintf(logfile,"FFT Gflps 3d (1d only) = %g %g\n",flop3,flop1);
}
}
}
if (histoflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
tmp = atom->nlocal;
stats(1,&tmp,&ave,&max,&min,10,histo);
if (me == 0) {
if (screen) {
fprintf(screen,"Nlocal: %g ave %g max %g min\n",ave,max,min);
fprintf(screen,"Histogram:");
for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
fprintf(screen,"\n");
}
if (logfile) {
fprintf(logfile,"Nlocal: %g ave %g max %g min\n",ave,max,min);
fprintf(logfile,"Histogram:");
for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
fprintf(logfile,"\n");
}
}
tmp = atom->nghost;
stats(1,&tmp,&ave,&max,&min,10,histo);
if (me == 0) {
if (screen) {
fprintf(screen,"Nghost: %g ave %g max %g min\n",ave,max,min);
fprintf(screen,"Histogram:");
for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
fprintf(screen,"\n");
}
if (logfile) {
fprintf(logfile,"Nghost: %g ave %g max %g min\n",ave,max,min);
fprintf(logfile,"Histogram:");
for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
fprintf(logfile,"\n");
}
}
// find a non-skip neighbor list containing half the pairwise interactions
// count neighbors in that list for stats purposes
for (m = 0; m < neighbor->old_nrequest; m++)
if ((neighbor->old_requests[m]->half ||
neighbor->old_requests[m]->gran ||
neighbor->old_requests[m]->respaouter ||
neighbor->old_requests[m]->half_from_full) &&
neighbor->old_requests[m]->skip == 0 &&
neighbor->lists[m]->numneigh) break;
nneigh = 0;
if (m < neighbor->old_nrequest) {
int inum = neighbor->lists[m]->inum;
int *ilist = neighbor->lists[m]->ilist;
int *numneigh = neighbor->lists[m]->numneigh;
for (i = 0; i < inum; i++)
nneigh += numneigh[ilist[i]];
}
tmp = nneigh;
stats(1,&tmp,&ave,&max,&min,10,histo);
if (me == 0) {
if (screen) {
fprintf(screen,"Neighs: %g ave %g max %g min\n",ave,max,min);
fprintf(screen,"Histogram:");
for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
fprintf(screen,"\n");
}
if (logfile) {
fprintf(logfile,"Neighs: %g ave %g max %g min\n",ave,max,min);
fprintf(logfile,"Histogram:");
for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
fprintf(logfile,"\n");
}
}
// find a non-skip neighbor list containing full pairwise interactions
// count neighbors in that list for stats purposes
for (m = 0; m < neighbor->old_nrequest; m++)
if (neighbor->old_requests[m]->full &&
neighbor->old_requests[m]->skip == 0) break;
nneighfull = 0;
if (m < neighbor->old_nrequest) {
if (neighbor->lists[m]->numneigh > 0) {
int inum = neighbor->lists[m]->inum;
int *ilist = neighbor->lists[m]->ilist;
int *numneigh = neighbor->lists[m]->numneigh;
for (i = 0; i < inum; i++)
nneighfull += numneigh[ilist[i]];
}
tmp = nneighfull;
stats(1,&tmp,&ave,&max,&min,10,histo);
if (me == 0) {
if (screen) {
fprintf(screen,"FullNghs: %g ave %g max %g min\n",ave,max,min);
fprintf(screen,"Histogram:");
for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
fprintf(screen,"\n");
}
if (logfile) {
fprintf(logfile,"FullNghs: %g ave %g max %g min\n",ave,max,min);
fprintf(logfile,"Histogram:");
for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
fprintf(logfile,"\n");
}
}
}
}
if (neighflag) {
if (me == 0) {
if (screen) fprintf(screen,"\n");
if (logfile) fprintf(logfile,"\n");
}
tmp = MAX(nneigh,nneighfull);
double nall;
MPI_Allreduce(&tmp,&nall,1,MPI_DOUBLE,MPI_SUM,world);
int nspec;
double nspec_all;
if (atom->molecular) {
nspec = 0;
for (i = 0; i < atom->nlocal; i++) nspec += atom->nspecial[i][2];
tmp = nspec;
MPI_Allreduce(&tmp,&nspec_all,1,MPI_DOUBLE,MPI_SUM,world);
}
if (me == 0) {
if (screen) {
if (nall < 2.0e9)
fprintf(screen,
"Total # of neighbors = %d\n",static_cast<int> (nall));
else fprintf(screen,"Total # of neighbors = %g\n",nall);
if (atom->natoms > 0)
fprintf(screen,"Ave neighs/atom = %g\n",nall/atom->natoms);
if (atom->molecular && atom->natoms > 0)
fprintf(screen,"Ave special neighs/atom = %g\n",
nspec_all/atom->natoms);
fprintf(screen,"Neighbor list builds = %d\n",neighbor->ncalls);
fprintf(screen,"Dangerous builds = %d\n",neighbor->ndanger);
}
if (logfile) {
if (nall < 2.0e9)
fprintf(logfile,
"Total # of neighbors = %d\n",static_cast<int> (nall));
else fprintf(logfile,"Total # of neighbors = %g\n",nall);
if (atom->natoms > 0)
fprintf(logfile,"Ave neighs/atom = %g\n",nall/atom->natoms);
if (atom->molecular && atom->natoms > 0)
fprintf(logfile,"Ave special neighs/atom = %g\n",
nspec_all/atom->natoms);
fprintf(logfile,"Neighbor list builds = %d\n",neighbor->ncalls);
fprintf(logfile,"Dangerous builds = %d\n",neighbor->ndanger);
}
}
}
if (logfile) fflush(logfile);
}
/* ---------------------------------------------------------------------- */
void Finish::stats(int n, double *data,
double *pave, double *pmax, double *pmin,
int nhisto, int *histo)
{
int i,m;
int *histotmp;
double min = 1.0e20;
double max = -1.0e20;
double ave = 0.0;
for (i = 0; i < n; i++) {
ave += data[i];
if (data[i] < min) min = data[i];
if (data[i] > max) max = data[i];
}
int ntotal;
MPI_Allreduce(&n,&ntotal,1,MPI_INT,MPI_SUM,world);
double tmp;
MPI_Allreduce(&ave,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
ave = tmp/ntotal;
MPI_Allreduce(&min,&tmp,1,MPI_DOUBLE,MPI_MIN,world);
min = tmp;
MPI_Allreduce(&max,&tmp,1,MPI_DOUBLE,MPI_MAX,world);
max = tmp;
for (i = 0; i < nhisto; i++) histo[i] = 0;
double del = max - min;
for (i = 0; i < n; i++) {
if (del == 0.0) m = 0;
else m = static_cast<int> ((data[i]-min)/del * nhisto);
if (m > nhisto-1) m = nhisto-1;
histo[m]++;
}
memory->create(histotmp,nhisto,"finish:histotmp");
MPI_Allreduce(histo,histotmp,nhisto,MPI_INT,MPI_SUM,world);
for (i = 0; i < nhisto; i++) histo[i] = histotmp[i];
memory->destroy(histotmp);
*pave = ave;
*pmax = max;
*pmin = min;
}
diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp
index 0fd4672ec..18303b6cf 100644
--- a/src/fix_ave_spatial.cpp
+++ b/src/fix_ave_spatial.cpp
@@ -1,1277 +1,1284 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "stdlib.h"
#include "string.h"
#include "fix_ave_spatial.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "domain.h"
#include "region.h"
#include "lattice.h"
#include "modify.h"
#include "compute.h"
#include "input.h"
#include "variable.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{LOWER,CENTER,UPPER,COORD};
enum{V,F,DENSITY_NUMBER,DENSITY_MASS,COMPUTE,FIX,VARIABLE};
enum{SAMPLE,ALL};
enum{BOX,LATTICE,REDUCED};
enum{ONE,RUNNING,WINDOW};
#define INVOKED_PERATOM 8
#define BIG 1000000000
/* ---------------------------------------------------------------------- */
FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix ave/spatial command");
MPI_Comm_rank(world,&me);
nevery = atoi(arg[3]);
nrepeat = atoi(arg[4]);
nfreq = atoi(arg[5]);
global_freq = nfreq;
no_change_box = 1;
time_depend = 1;
ndim = 0;
int iarg = 6;
while (iarg < narg && ndim < 3) {
if (iarg+3 > narg) break;
if (strcmp(arg[iarg],"x") == 0) dim[ndim] = 0;
else if (strcmp(arg[iarg],"y") == 0) dim[ndim] = 1;
else if (strcmp(arg[iarg],"z") == 0) dim[ndim] = 2;
else break;
if (dim[ndim] == 2 && domain->dimension == 2)
error->all(FLERR,"Cannot use fix ave/spatial z for 2 dimensional model");
if (strcmp(arg[iarg+1],"lower") == 0) originflag[ndim] = LOWER;
if (strcmp(arg[iarg+1],"center") == 0) originflag[ndim] = CENTER;
if (strcmp(arg[iarg+1],"upper") == 0) originflag[ndim] = UPPER;
else originflag[ndim] = COORD;
if (originflag[ndim] == COORD) origin[ndim] = atof(arg[iarg+1]);
delta[ndim] = atof(arg[iarg+2]);
ndim++;
iarg += 3;
}
if (!ndim) error->all(FLERR,"Illegal fix ave/spatial command");
if (ndim == 2 && dim[0] == dim[1])
error->all(FLERR,"Same dimension twice in fix ave/spatial");
if (ndim == 3 && (dim[0] == dim[1] || dim[1] == dim[2] || dim[0] == dim[2]))
error->all(FLERR,"Same dimension twice in fix ave/spatial");
// parse values until one isn't recognized
which = new int[narg-9];
argindex = new int[narg-9];
ids = new char*[narg-9];
value2index = new int[narg-9];
nvalues = 0;
while (iarg < narg) {
ids[nvalues] = NULL;
if (strcmp(arg[iarg],"vx") == 0) {
which[nvalues] = V;
argindex[nvalues++] = 0;
} else if (strcmp(arg[iarg],"vy") == 0) {
which[nvalues] = V;
argindex[nvalues++] = 1;
} else if (strcmp(arg[iarg],"vz") == 0) {
which[nvalues] = V;
argindex[nvalues++] = 2;
} else if (strcmp(arg[iarg],"fx") == 0) {
which[nvalues] = F;
argindex[nvalues++] = 0;
} else if (strcmp(arg[iarg],"fy") == 0) {
which[nvalues] = F;
argindex[nvalues++] = 1;
} else if (strcmp(arg[iarg],"fz") == 0) {
which[nvalues] = F;
argindex[nvalues++] = 2;
} else if (strcmp(arg[iarg],"density/number") == 0) {
which[nvalues] = DENSITY_NUMBER;
argindex[nvalues++] = 0;
} else if (strcmp(arg[iarg],"density/mass") == 0) {
which[nvalues] = DENSITY_MASS;
argindex[nvalues++] = 0;
} else if (strncmp(arg[iarg],"c_",2) == 0 ||
strncmp(arg[iarg],"f_",2) == 0 ||
strncmp(arg[iarg],"v_",2) == 0) {
if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
int n = strlen(arg[iarg]);
char *suffix = new char[n];
strcpy(suffix,&arg[iarg][2]);
char *ptr = strchr(suffix,'[');
if (ptr) {
if (suffix[strlen(suffix)-1] != ']')
error->all(FLERR,"Illegal fix ave/spatial command");
argindex[nvalues] = atoi(ptr+1);
*ptr = '\0';
} else argindex[nvalues] = 0;
n = strlen(suffix) + 1;
ids[nvalues] = new char[n];
strcpy(ids[nvalues],suffix);
nvalues++;
delete [] suffix;
} else break;
iarg++;
}
// optional args
normflag = ALL;
scaleflag = LATTICE;
regionflag = 0;
idregion = NULL;
fp = NULL;
ave = ONE;
nwindow = 0;
char *title1 = NULL;
char *title2 = NULL;
char *title3 = NULL;
while (iarg < narg) {
if (strcmp(arg[iarg],"norm") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
if (strcmp(arg[iarg+1],"all") == 0) normflag = ALL;
else if (strcmp(arg[iarg+1],"sample") == 0) normflag = SAMPLE;
else error->all(FLERR,"Illegal fix ave/spatial command");
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = BOX;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = LATTICE;
else if (strcmp(arg[iarg+1],"reduced") == 0) scaleflag = REDUCED;
else error->all(FLERR,"Illegal fix ave/spatial command");
iarg += 2;
} else if (strcmp(arg[iarg],"region") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
iregion = domain->find_region(arg[iarg+1]);
if (iregion == -1)
error->all(FLERR,"Region ID for fix ave/spatial does not exist");
int n = strlen(arg[iarg+1]) + 1;
idregion = new char[n];
strcpy(idregion,arg[iarg+1]);
regionflag = 1;
iarg += 2;
} else if (strcmp(arg[iarg],"file") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
if (me == 0) {
fp = fopen(arg[iarg+1],"w");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open fix ave/spatial file %s",arg[iarg+1]);
error->one(FLERR,str);
}
}
iarg += 2;
} else if (strcmp(arg[iarg],"ave") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW;
else error->all(FLERR,"Illegal fix ave/spatial command");
if (ave == WINDOW) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
nwindow = atoi(arg[iarg+2]);
if (nwindow <= 0) error->all(FLERR,"Illegal fix ave/spatial command");
}
iarg += 2;
if (ave == WINDOW) iarg++;
} else if (strcmp(arg[iarg],"title1") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
delete [] title1;
int n = strlen(arg[iarg+1]) + 1;
title1 = new char[n];
strcpy(title1,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"title2") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
delete [] title2;
int n = strlen(arg[iarg+1]) + 1;
title2 = new char[n];
strcpy(title2,arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"title3") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/spatial command");
delete [] title3;
int n = strlen(arg[iarg+1]) + 1;
title3 = new char[n];
strcpy(title3,arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal fix ave/spatial command");
}
// setup and error check
if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0)
error->all(FLERR,"Illegal fix ave/spatial command");
if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq)
error->all(FLERR,"Illegal fix ave/spatial command");
if (delta[0] <= 0.0) error->all(FLERR,"Illegal fix ave/spatial command");
if (ndim >= 2 && delta[1] <= 0.0)
error->all(FLERR,"Illegal fix ave/spatial command");
if (ndim == 3 && delta[2] <= 0.0)
error->all(FLERR,"Illegal fix ave/spatial command");
for (int i = 0; i < nvalues; i++) {
if (which[i] == COMPUTE) {
int icompute = modify->find_compute(ids[i]);
if (icompute < 0)
error->all(FLERR,"Compute ID for fix ave/spatial does not exist");
if (modify->compute[icompute]->peratom_flag == 0)
error->all(FLERR,"Fix ave/spatial compute does not "
"calculate per-atom values");
if (argindex[i] == 0 &&
modify->compute[icompute]->size_peratom_cols != 0)
error->all(FLERR,"Fix ave/spatial compute does not "
"calculate a per-atom vector");
if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
error->all(FLERR,"Fix ave/spatial compute does not "
"calculate a per-atom array");
if (argindex[i] &&
argindex[i] > modify->compute[icompute]->size_peratom_cols)
- error->all(FLERR,"Fix ave/spatial compute vector is accessed out-of-range");
+ error->all(FLERR,
+ "Fix ave/spatial compute vector is accessed out-of-range");
} else if (which[i] == FIX) {
int ifix = modify->find_fix(ids[i]);
if (ifix < 0)
error->all(FLERR,"Fix ID for fix ave/spatial does not exist");
if (modify->fix[ifix]->peratom_flag == 0)
- error->all(FLERR,"Fix ave/spatial fix does not calculate per-atom values");
+ error->all(FLERR,
+ "Fix ave/spatial fix does not calculate per-atom values");
if (argindex[i] && modify->fix[ifix]->size_peratom_cols != 0)
- error->all(FLERR,"Fix ave/spatial fix does not calculate a per-atom vector");
+ error->all(FLERR,
+ "Fix ave/spatial fix does not calculate a per-atom vector");
if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
- error->all(FLERR,"Fix ave/spatial fix does not calculate a per-atom array");
+ error->all(FLERR,
+ "Fix ave/spatial fix does not calculate a per-atom array");
if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols)
error->all(FLERR,"Fix ave/spatial fix vector is accessed out-of-range");
} else if (which[i] == VARIABLE) {
int ivariable = input->variable->find(ids[i]);
if (ivariable < 0)
error->all(FLERR,"Variable name for fix ave/spatial does not exist");
if (input->variable->atomstyle(ivariable) == 0)
error->all(FLERR,"Fix ave/spatial variable is not atom-style variable");
}
}
// print file comment lines
if (fp && me == 0) {
if (title1) fprintf(fp,"%s\n",title1);
else fprintf(fp,"# Spatial-averaged data for fix %s and group %s\n",
id,arg[1]);
if (title2) fprintf(fp,"%s\n",title2);
else fprintf(fp,"# Timestep Number-of-bins\n");
if (title3) fprintf(fp,"%s\n",title3);
else {
if (ndim == 1) fprintf(fp,"# Bin Coord Ncount");
else if (ndim == 2) fprintf(fp,"# Bin Coord1 Coord2 Ncount");
else if (ndim == 3) fprintf(fp,"# Bin Coord1 Coord2 Coord3 Ncount");
for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[6+3*ndim+i]);
fprintf(fp,"\n");
}
}
delete [] title1;
delete [] title2;
delete [] title3;
// this fix produces a global array
array_flag = 1;
size_array_rows = BIG;
size_array_cols = 1 + ndim + nvalues;
extarray = 0;
// setup scaling
int triclinic = domain->triclinic;
if (triclinic == 1 && scaleflag != REDUCED)
- error->all(FLERR,"Fix ave/spatial for triclinic boxes requires units reduced");
+ error->all(FLERR,
+ "Fix ave/spatial for triclinic boxes requires units reduced");
if (scaleflag == LATTICE && domain->lattice == NULL)
error->all(FLERR,"Use of fix ave/spatial with undefined lattice");
if (scaleflag == LATTICE) {
xscale = domain->lattice->xlattice;
yscale = domain->lattice->ylattice;
zscale = domain->lattice->zlattice;
}
else xscale = yscale = zscale = 1.0;
// apply scaling factors
double scale;
for (int idim = 0; idim < ndim; idim++) {
if (dim[idim] == 0) scale = xscale;
else if (dim[idim] == 1) scale = yscale;
else if (dim[idim] == 2) scale = zscale;
delta[idim] *= scale;
if (originflag[idim] == COORD) origin[idim] *= scale;
invdelta[idim] = 1.0/delta[idim];
}
// initializations
irepeat = 0;
iwindow = window_limit = 0;
norm = 0;
maxvar = 0;
varatom = NULL;
maxatom = 0;
bin = NULL;
nbins = maxbin = 0;
count_one = count_many = count_sum = count_total = NULL;
coord = NULL;
count_list = NULL;
values_one = values_many = values_sum = values_total = NULL;
values_list = NULL;
// nvalid = next step on which end_of_step does something
// add nvalid to all computes that store invocation times
// since don't know a priori which are invoked by this fix
// once in end_of_step() can set timestep for ones actually invoked
nvalid = nextvalid();
modify->addstep_compute_all(nvalid);
}
/* ---------------------------------------------------------------------- */
FixAveSpatial::~FixAveSpatial()
{
delete [] which;
delete [] argindex;
for (int i = 0; i < nvalues; i++) delete [] ids[i];
delete [] ids;
delete [] value2index;
delete [] idregion;
if (fp && me == 0) fclose(fp);
memory->destroy(varatom);
memory->destroy(bin);
memory->destroy(count_one);
memory->destroy(count_many);
memory->destroy(count_sum);
memory->destroy(count_total);
memory->destroy(coord);
memory->destroy(count_list);
memory->destroy(values_one);
memory->destroy(values_many);
memory->destroy(values_sum);
memory->destroy(values_total);
memory->destroy(values_list);
}
/* ---------------------------------------------------------------------- */
int FixAveSpatial::setmask()
{
int mask = 0;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixAveSpatial::init()
{
// set and check validity of region
if (regionflag) {
iregion = domain->find_region(idregion);
if (iregion == -1)
error->all(FLERR,"Region ID for fix ave/spatial does not exist");
region = domain->regions[iregion];
}
// # of bins cannot vary for ave = RUNNING or WINDOW
if (ave == RUNNING || ave == WINDOW) {
if (scaleflag != REDUCED && domain->box_change)
error->all(FLERR,"Fix ave/spatial settings invalid with changing box");
}
// set indices and check validity of all computes,fixes,variables
// check that fix frequency is acceptable
for (int m = 0; m < nvalues; m++) {
if (which[m] == COMPUTE) {
int icompute = modify->find_compute(ids[m]);
if (icompute < 0)
error->all(FLERR,"Compute ID for fix ave/spatial does not exist");
value2index[m] = icompute;
} else if (which[m] == FIX) {
int ifix = modify->find_fix(ids[m]);
if (ifix < 0)
error->all(FLERR,"Fix ID for fix ave/spatial does not exist");
value2index[m] = ifix;
if (nevery % modify->fix[ifix]->peratom_freq)
- error->all(FLERR,"Fix for fix ave/spatial not computed at compatible time");
+ error->all(FLERR,
+ "Fix for fix ave/spatial not computed at compatible time");
} else if (which[m] == VARIABLE) {
int ivariable = input->variable->find(ids[m]);
if (ivariable < 0)
error->all(FLERR,"Variable name for fix ave/spatial does not exist");
value2index[m] = ivariable;
} else value2index[m] = -1;
}
// need to reset nvalid if nvalid < ntimestep b/c minimize was performed
if (nvalid < update->ntimestep) {
irepeat = 0;
nvalid = nextvalid();
modify->addstep_compute_all(nvalid);
}
}
/* ----------------------------------------------------------------------
setup initial bins
only does averaging if nvalid = current timestep
------------------------------------------------------------------------- */
void FixAveSpatial::setup(int vflag)
{
setup_bins();
end_of_step();
}
/* ---------------------------------------------------------------------- */
void FixAveSpatial::end_of_step()
{
int i,j,m,n;
// skip if not step which requires doing something
bigint ntimestep = update->ntimestep;
if (ntimestep != nvalid) return;
// zero out arrays that accumulate over many samples
// if box changes, first re-setup bins
if (irepeat == 0) {
if (domain->box_change) setup_bins();
for (m = 0; m < nbins; m++) {
count_many[m] = count_sum[m] = 0.0;
for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0;
}
}
// zero out arrays for one sample
for (m = 0; m < nbins; m++) {
count_one[m] = 0.0;
for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0;
}
// assign each atom to a bin
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (nlocal > maxatom) {
maxatom = atom->nmax;
memory->destroy(bin);
memory->create(bin,maxatom,"ave/spatial:bin");
}
if (ndim == 1) atom2bin1d();
else if (ndim == 2) atom2bin2d();
else atom2bin3d();
// perform the computation for one sample
// accumulate results of attributes,computes,fixes,variables to local copy
// sum within each bin, only include atoms in fix group
// compute/fix/variable may invoke computes so wrap with clear/add
modify->clearstep_compute();
for (m = 0; m < nvalues; m++) {
n = value2index[m];
j = argindex[m];
// V,F adds velocities,forces to values
if (which[m] == V || which[m] == F) {
double **attribute;
if (which[m] == V) attribute = atom->v;
else attribute = atom->f;
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
values_one[bin[i]][m] += attribute[i][j];
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
values_one[bin[i]][m] += attribute[i][j];
}
// DENSITY_NUMBER adds 1 to values
} else if (which[m] == DENSITY_NUMBER) {
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
values_one[bin[i]][m] += 1.0;
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
values_one[bin[i]][m] += 1.0;
}
// DENSITY_MASS adds mass to values
} else if (which[m] == DENSITY_MASS) {
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (rmass) values_one[bin[i]][m] += rmass[i];
else values_one[bin[i]][m] += mass[type[i]];
}
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (rmass) values_one[bin[i]][m] += rmass[i];
else values_one[bin[i]][m] += mass[type[i]];
}
}
// COMPUTE adds its scalar or vector component to values
// invoke compute if not previously invoked
} else if (which[m] == COMPUTE) {
Compute *compute = modify->compute[n];
if (!(compute->invoked_flag & INVOKED_PERATOM)) {
compute->compute_peratom();
compute->invoked_flag |= INVOKED_PERATOM;
}
double *vector = compute->vector_atom;
double **array = compute->array_atom;
int jm1 = j - 1;
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (j == 0) values_one[bin[i]][m] += vector[i];
else values_one[bin[i]][m] += array[i][jm1];
}
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (j == 0) values_one[bin[i]][m] += vector[i];
else values_one[bin[i]][m] += array[i][jm1];
}
}
// FIX adds its scalar or vector component to values
// access fix fields, guaranteed to be ready
} else if (which[m] == FIX) {
double *vector = modify->fix[n]->vector_atom;
double **array = modify->fix[n]->array_atom;
int jm1 = j - 1;
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (j == 0) values_one[bin[i]][m] += vector[i];
else values_one[bin[i]][m] += array[i][jm1];
}
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (j == 0) values_one[bin[i]][m] += vector[i];
else values_one[bin[i]][m] += array[i][jm1];
}
}
// VARIABLE adds its per-atom quantities to values
// evaluate atom-style variable
} else if (which[m] == VARIABLE) {
if (nlocal > maxvar) {
maxvar = atom->nmax;
memory->destroy(varatom);
memory->create(varatom,maxvar,"ave/spatial:varatom");
}
input->variable->compute_atom(n,igroup,varatom,1,0);
if (regionflag == 0) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
values_one[bin[i]][m] += varatom[i];
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
values_one[bin[i]][m] += varatom[i];
}
}
}
// process a single sample
// if normflag = ALL, accumulate values,count separately to many
// if normflag = SAMPLE, one = value/count, accumulate one to many
// exception is SAMPLE density: no normalization by atom count
if (normflag == ALL) {
for (m = 0; m < nbins; m++) {
count_many[m] += count_one[m];
for (j = 0; j < nvalues; j++)
values_many[m][j] += values_one[m][j];
}
} else {
MPI_Allreduce(count_one,count_many,nbins,MPI_DOUBLE,MPI_SUM,world);
for (m = 0; m < nbins; m++) {
if (count_many[m] > 0.0)
for (j = 0; j < nvalues; j++) {
if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
values_many[m][j] += values_one[m][j];
else values_many[m][j] += values_one[m][j]/count_many[m];
}
count_sum[m] += count_many[m];
}
}
// done if irepeat < nrepeat
// else reset irepeat and nvalid
irepeat++;
if (irepeat < nrepeat) {
nvalid += nevery;
modify->addstep_compute(nvalid);
return;
}
irepeat = 0;
nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
modify->addstep_compute(nvalid);
// time average across samples
// if normflag = ALL, final is total value / total count
// if normflag = SAMPLE, final is sum of ave / repeat
// exception is densities: normalized by repeat, not total count
double repeat = nrepeat;
double mv2d = force->mv2d;
if (normflag == ALL) {
MPI_Allreduce(count_many,count_sum,nbins,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
MPI_DOUBLE,MPI_SUM,world);
for (m = 0; m < nbins; m++) {
if (count_sum[m] > 0.0)
for (j = 0; j < nvalues; j++)
if (which[j] == DENSITY_NUMBER) values_sum[m][j] /= repeat;
else if (which[j] == DENSITY_MASS) values_sum[m][j] *= mv2d/repeat;
else values_sum[m][j] /= count_sum[m];
count_sum[m] /= repeat;
}
} else {
MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
MPI_DOUBLE,MPI_SUM,world);
for (m = 0; m < nbins; m++) {
for (j = 0; j < nvalues; j++)
values_sum[m][j] /= repeat;
count_sum[m] /= repeat;
}
}
// density is additionally normalized by bin volume
for (j = 0; j < nvalues; j++)
if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
for (m = 0; m < nbins; m++)
values_sum[m][j] /= bin_volume;
// if ave = ONE, only single Nfreq timestep value is needed
// if ave = RUNNING, combine with all previous Nfreq timestep values
// if ave = WINDOW, comine with nwindow most recent Nfreq timestep values
if (ave == ONE) {
for (m = 0; m < nbins; m++) {
for (i = 0; i < nvalues; i++)
values_total[m][i] = values_sum[m][i];
count_total[m] = count_sum[m];
}
norm = 1;
} else if (ave == RUNNING) {
for (m = 0; m < nbins; m++) {
for (i = 0; i < nvalues; i++)
values_total[m][i] += values_sum[m][i];
count_total[m] += count_sum[m];
}
norm++;
} else if (ave == WINDOW) {
for (m = 0; m < nbins; m++) {
for (i = 0; i < nvalues; i++) {
values_total[m][i] += values_sum[m][i];
if (window_limit) values_total[m][i] -= values_list[iwindow][m][i];
values_list[iwindow][m][i] = values_sum[m][i];
}
count_total[m] += count_sum[m];
if (window_limit) count_total[m] -= count_list[iwindow][m];
count_list[iwindow][m] = count_sum[m];
}
iwindow++;
if (iwindow == nwindow) {
iwindow = 0;
window_limit = 1;
}
if (window_limit) norm = nwindow;
else norm = iwindow;
}
// output result to file
if (fp && me == 0) {
fprintf(fp,BIGINT_FORMAT " %d\n",ntimestep,nbins);
if (ndim == 1)
for (m = 0; m < nbins; m++) {
fprintf(fp," %d %g %g",m+1,coord[m][0],
count_total[m]/norm);
for (i = 0; i < nvalues; i++)
fprintf(fp," %g",values_total[m][i]/norm);
fprintf(fp,"\n");
}
else if (ndim == 2)
for (m = 0; m < nbins; m++) {
fprintf(fp," %d %g %g %g",m+1,coord[m][0],coord[m][1],
count_total[m]/norm);
for (i = 0; i < nvalues; i++)
fprintf(fp," %g",values_total[m][i]/norm);
fprintf(fp,"\n");
}
else
for (m = 0; m < nbins; m++) {
fprintf(fp," %d %g %g %g %g",m+1,coord[m][0],coord[m][1],coord[m][2],
count_total[m]/norm);
for (i = 0; i < nvalues; i++)
fprintf(fp," %g",values_total[m][i]/norm);
fprintf(fp,"\n");
}
fflush(fp);
}
}
/* ----------------------------------------------------------------------
setup 1d, 2d, or 3d bins and their extent and coordinates
called at setup() and when averaging occurs if box size changes
------------------------------------------------------------------------- */
void FixAveSpatial::setup_bins()
{
int i,j,k,m,n;
double lo,hi,coord1,coord2;
// lo = bin boundary immediately below boxlo
// hi = bin boundary immediately above boxhi
// allocate and initialize arrays based on new bin count
double *boxlo,*boxhi,*prd;
if (scaleflag == REDUCED) {
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
prd = domain->prd_lamda;
} else {
boxlo = domain->boxlo;
boxhi = domain->boxhi;
prd = domain->prd;
}
if (domain->dimension == 3)
bin_volume = domain->xprd * domain->yprd * domain->zprd;
else bin_volume = domain->xprd * domain->yprd;
nbins = 1;
for (m = 0; m < ndim; m++) {
if (originflag[m] == LOWER) origin[m] = boxlo[dim[m]];
else if (originflag[m] == UPPER) origin[m] = boxhi[dim[m]];
else if (originflag[m] == CENTER)
origin[m] = 0.5 * (boxlo[dim[m]] + boxhi[dim[m]]);
if (origin[m] < boxlo[dim[m]]) {
n = static_cast<int> ((boxlo[dim[m]] - origin[m]) * invdelta[m]);
lo = origin[m] + n*delta[m];
} else {
n = static_cast<int> ((origin[m] - boxlo[dim[m]]) * invdelta[m]);
lo = origin[m] - n*delta[m];
if (lo > boxlo[dim[m]]) lo -= delta[m];
}
if (origin[m] < boxhi[dim[m]]) {
n = static_cast<int> ((boxhi[dim[m]] - origin[m]) * invdelta[m]);
hi = origin[m] + n*delta[m];
if (hi < boxhi[dim[m]]) hi += delta[m];
} else {
n = static_cast<int> ((origin[m] - boxhi[dim[m]]) * invdelta[m]);
hi = origin[m] - n*delta[m];
}
offset[m] = lo;
nlayers[m] = static_cast<int> ((hi-lo) * invdelta[m] + 0.5);
nbins *= nlayers[m];
bin_volume *= delta[m]/prd[dim[m]];
}
// reallocate bin arrays if needed
if (nbins > maxbin) {
maxbin = nbins;
memory->grow(count_one,nbins,"ave/spatial:count_one");
memory->grow(count_many,nbins,"ave/spatial:count_many");
memory->grow(count_sum,nbins,"ave/spatial:count_sum");
memory->grow(count_total,nbins,"ave/spatial:count_total");
memory->grow(coord,nbins,ndim,"ave/spatial:coord");
memory->grow(values_one,nbins,nvalues,"ave/spatial:values_one");
memory->grow(values_many,nbins,nvalues,"ave/spatial:values_many");
memory->grow(values_sum,nbins,nvalues,"ave/spatial:values_sum");
memory->grow(values_total,nbins,nvalues,"ave/spatial:values_total");
// only allocate count and values list for ave = WINDOW
if (ave == WINDOW) {
memory->create(count_list,nwindow,nbins,"ave/spatial:count_list");
memory->create(values_list,nwindow,nbins,nvalues,
"ave/spatial:values_list");
}
// reinitialize regrown count/values total since they accumulate
for (m = 0; m < nbins; m++) {
for (i = 0; i < nvalues; i++) values_total[m][i] = 0.0;
count_total[m] = 0.0;
}
}
// set bin coordinates
if (ndim == 1) {
for (i = 0; i < nlayers[0]; i++)
coord[i][0] = offset[0] + (i+0.5)*delta[0];
} else if (ndim == 2) {
m = 0;
for (i = 0; i < nlayers[0]; i++) {
coord1 = offset[0] + (i+0.5)*delta[0];
for (j = 0; j < nlayers[1]; j++) {
coord[m][0] = coord1;
coord[m][1] = offset[1] + (j+0.5)*delta[1];
m++;
}
}
} else if (ndim == 3) {
m = 0;
for (i = 0; i < nlayers[0]; i++) {
coord1 = offset[0] + (i+0.5)*delta[0];
for (j = 0; j < nlayers[1]; j++) {
coord2 = offset[1] + (j+0.5)*delta[1];
for (k = 0; k < nlayers[2]; k++) {
coord[m][0] = coord1;
coord[m][1] = coord2;
coord[m][2] = offset[2] + (k+0.5)*delta[2];
m++;
}
}
}
}
}
/* ----------------------------------------------------------------------
assign each atom to a 1d bin
------------------------------------------------------------------------- */
void FixAveSpatial::atom2bin1d()
{
int i,ibin;
double *boxlo,*boxhi,*prd;
double xremap;
double lamda[3];
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int idim = dim[0];
int nlayerm1 = nlayers[0] - 1;
int periodicity = domain->periodicity[idim];
if (periodicity) {
if (scaleflag == REDUCED) {
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
prd = domain->prd_lamda;
} else {
boxlo = domain->boxlo;
boxhi = domain->boxhi;
prd = domain->prd;
}
}
// remap each atom's relevant coord back into box via PBC if necessary
// if scaleflag = REDUCED, box coords -> lamda coords
if (regionflag == 0) {
if (scaleflag == REDUCED) domain->x2lamda(nlocal);
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
xremap = x[i][idim];
if (periodicity) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
ibin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
ibin = MAX(ibin,0);
ibin = MIN(ibin,nlayerm1);
bin[i] = ibin;
count_one[ibin] += 1.0;
}
if (scaleflag == REDUCED) domain->lamda2x(nlocal);
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (scaleflag == REDUCED) {
domain->x2lamda(x[i],lamda);
xremap = lamda[idim];
} else xremap = x[i][idim];
if (periodicity) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
ibin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
ibin = MAX(ibin,0);
ibin = MIN(ibin,nlayerm1);
bin[i] = ibin;
count_one[ibin] += 1.0;
}
}
}
/* ----------------------------------------------------------------------
assign each atom to a 2d bin
------------------------------------------------------------------------- */
void FixAveSpatial::atom2bin2d()
{
int i,ibin,i1bin,i2bin;
double *boxlo,*boxhi,*prd;
double xremap,yremap;
double lamda[3];
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int idim = dim[0];
int jdim = dim[1];
int nlayer1m1 = nlayers[0] - 1;
int nlayer2m1 = nlayers[1] - 1;
int* periodicity = domain->periodicity;
if (periodicity[idim] || periodicity[jdim]) {
if (scaleflag == REDUCED) {
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
prd = domain->prd_lamda;
} else {
boxlo = domain->boxlo;
boxhi = domain->boxhi;
prd = domain->prd;
}
}
// remap each atom's relevant coord back into box via PBC if necessary
// if scaleflag = REDUCED, box coords -> lamda coords
if (regionflag == 0) {
if (scaleflag == REDUCED) domain->x2lamda(nlocal);
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
xremap = x[i][idim];
if (periodicity[idim]) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
i1bin = MAX(i1bin,0);
i1bin = MIN(i1bin,nlayer1m1);
yremap = x[i][jdim];
if (periodicity[jdim]) {
if (yremap < boxlo[jdim]) yremap += prd[jdim];
if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
}
i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
i2bin = MAX(i2bin,0);
i2bin = MIN(i2bin,nlayer2m1);
ibin = i1bin*nlayers[1] + i2bin;
bin[i] = ibin;
count_one[ibin] += 1.0;
}
if (scaleflag == REDUCED) domain->lamda2x(nlocal);
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (scaleflag == REDUCED) {
domain->x2lamda(x[i],lamda);
xremap = lamda[idim];
yremap = lamda[jdim];
} else {
xremap = x[i][idim];
yremap = x[i][jdim];
}
if (periodicity[idim]) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
i1bin = MAX(i1bin,0);
i1bin = MIN(i1bin,nlayer1m1-1);
if (periodicity[jdim]) {
if (yremap < boxlo[jdim]) yremap += prd[jdim];
if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
}
i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
i2bin = MAX(i2bin,0);
i2bin = MIN(i2bin,nlayer2m1-1);
ibin = i1bin*nlayers[1] + i2bin;
bin[i] = ibin;
count_one[ibin] += 1.0;
}
}
}
/* ----------------------------------------------------------------------
assign each atom to a 3d bin
------------------------------------------------------------------------- */
void FixAveSpatial::atom2bin3d()
{
int i,ibin,i1bin,i2bin,i3bin;
double *boxlo,*boxhi,*prd;
double xremap,yremap,zremap;
double lamda[3];
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int idim = dim[0];
int jdim = dim[1];
int kdim = dim[2];
int nlayer1m1 = nlayers[0] - 1;
int nlayer2m1 = nlayers[1] - 1;
int nlayer3m1 = nlayers[2] - 1;
int* periodicity = domain->periodicity;
if (periodicity[idim] || periodicity[jdim] || periodicity[kdim]) {
if (scaleflag == REDUCED) {
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
prd = domain->prd_lamda;
} else {
boxlo = domain->boxlo;
boxhi = domain->boxhi;
prd = domain->prd;
}
}
// remap each atom's relevant coord back into box via PBC if necessary
// if scaleflag = REDUCED, box coords -> lamda coords
if (regionflag == 0) {
if (scaleflag == REDUCED) domain->x2lamda(nlocal);
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
xremap = x[i][idim];
if (periodicity[idim]) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
i1bin = MAX(i1bin,0);
i1bin = MIN(i1bin,nlayer1m1);
yremap = x[i][jdim];
if (periodicity[jdim]) {
if (yremap < boxlo[jdim]) yremap += prd[jdim];
if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
}
i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
i2bin = MAX(i2bin,0);
i2bin = MIN(i2bin,nlayer2m1);
zremap = x[i][kdim];
if (periodicity[kdim]) {
if (zremap < boxlo[kdim]) yremap += prd[kdim];
if (zremap >= boxhi[kdim]) yremap -= prd[kdim];
}
i3bin = static_cast<int> ((zremap - offset[2]) * invdelta[2]);
i3bin = MAX(i3bin,0);
i3bin = MIN(i3bin,nlayer3m1);
ibin = i1bin*nlayers[1]*nlayers[2] + i2bin*nlayers[2] + i3bin;
bin[i] = ibin;
count_one[ibin] += 1.0;
}
if (scaleflag == REDUCED) domain->lamda2x(nlocal);
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
if (scaleflag == REDUCED) {
domain->x2lamda(x[i],lamda);
xremap = lamda[idim];
yremap = lamda[jdim];
zremap = lamda[kdim];
} else {
xremap = x[i][idim];
yremap = x[i][jdim];
zremap = x[i][kdim];
}
if (periodicity[idim]) {
if (xremap < boxlo[idim]) xremap += prd[idim];
if (xremap >= boxhi[idim]) xremap -= prd[idim];
}
i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
i1bin = MAX(i1bin,0);
i1bin = MIN(i1bin,nlayer1m1);
if (periodicity[jdim]) {
if (yremap < boxlo[jdim]) yremap += prd[jdim];
if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
}
i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
i2bin = MAX(i2bin,0);
i2bin = MIN(i2bin,nlayer2m1);
if (periodicity[kdim]) {
if (zremap < boxlo[kdim]) yremap += prd[kdim];
if (zremap >= boxhi[kdim]) yremap -= prd[kdim];
}
i3bin = static_cast<int> ((zremap - offset[2]) * invdelta[2]);
i3bin = MAX(i3bin,0);
i3bin = MIN(i3bin,nlayer3m1);
ibin = i1bin*nlayers[1]*nlayers[2] + i2bin*nlayers[2] + i3bin;
bin[i] = ibin;
count_one[ibin] += 1.0;
}
}
}
/* ----------------------------------------------------------------------
return I,J array value
if I exceeds current bins, return 0.0 instead of generating an error
column 1,2,3 = bin coords, next column = count, remaining columns = Nvalues
------------------------------------------------------------------------- */
double FixAveSpatial::compute_array(int i, int j)
{
if (values_total == NULL) return 0.0;
if (i >= nbins) return 0.0;
if (j < ndim) return coord[i][j];
j -= ndim+1;
+ if (!norm) return 0.0;
if (j < 0) return count_total[i]/norm;
return values_total[i][j]/norm;
}
/* ----------------------------------------------------------------------
calculate nvalid = next step on which end_of_step does something
can be this timestep if multiple of nfreq and nrepeat = 1
else backup from next multiple of nfreq
------------------------------------------------------------------------- */
bigint FixAveSpatial::nextvalid()
{
bigint nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
if (nvalid-nfreq == update->ntimestep && nrepeat == 1)
nvalid = update->ntimestep;
else
nvalid -= (nrepeat-1)*nevery;
if (nvalid < update->ntimestep) nvalid += nfreq;
return nvalid;
}
/* ----------------------------------------------------------------------
memory usage of varatom and bins
------------------------------------------------------------------------- */
double FixAveSpatial::memory_usage()
{
double bytes = maxvar * sizeof(double); // varatom
bytes += maxatom * sizeof(int); // bin
bytes += 4*nbins * sizeof(double); // count one,many,sum,total
bytes += ndim*nbins * sizeof(double); // coord
bytes += nvalues*nbins * sizeof(double); // values one,many,sum,total
bytes += nwindow*nbins * sizeof(double); // count_list
bytes += nwindow*nbins*nvalues * sizeof(double); // values_list
return bytes;
}
diff --git a/src/fix_dt_reset.cpp b/src/fix_dt_reset.cpp
index 758c8b32a..c35903a69 100644
--- a/src/fix_dt_reset.cpp
+++ b/src/fix_dt_reset.cpp
@@ -1,200 +1,212 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_dt_reset.h"
#include "atom.h"
#include "update.h"
#include "integrate.h"
#include "domain.h"
#include "lattice.h"
#include "force.h"
#include "pair.h"
#include "modify.h"
#include "fix.h"
#include "output.h"
#include "dump.h"
#include "comm.h"
#include "error.h"
using namespace LAMMPS_NS;
#define BIG 1.0e20
/* ---------------------------------------------------------------------- */
FixDtReset::FixDtReset(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 7) error->all(FLERR,"Illegal fix dt/reset command");
time_depend = 1;
scalar_flag = 1;
vector_flag = 1;
- size_vector = 1;
+ size_vector = 2;
global_freq = 1;
extscalar = 0;
extvector = 0;
nevery = atoi(arg[3]);
if (nevery <= 0) error->all(FLERR,"Illegal fix dt/reset command");
minbound = maxbound = 1;
tmin = tmax = 0.0;
if (strcmp(arg[4],"NULL") == 0) minbound = 0;
else tmin = atof(arg[4]);
if (strcmp(arg[5],"NULL") == 0) maxbound = 0;
else tmax = atof(arg[5]);
xmax = atof(arg[6]);
if (minbound && tmin < 0.0) error->all(FLERR,"Illegal fix dt/reset command");
if (maxbound && tmax < 0.0) error->all(FLERR,"Illegal fix dt/reset command");
if (minbound && maxbound && tmin >= tmax)
error->all(FLERR,"Illegal fix dt/reset command");
if (xmax <= 0.0) error->all(FLERR,"Illegal fix dt/reset command");
int scaleflag = 1;
int iarg = 7;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix dt/reset command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal fix dt/reset command");
iarg += 2;
} else error->all(FLERR,"Illegal fix dt/reset command");
}
// setup scaling, based on xlattice parameter
if (scaleflag && domain->lattice == NULL)
error->all(FLERR,"Use of fix dt/reset with undefined lattice");
if (scaleflag) xmax *= domain->lattice->xlattice;
// initializations
- t_elapsed = 0.0;
+ t_elapsed = t_laststep = 0.0;
laststep = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
int FixDtReset::setmask()
{
int mask = 0;
+ mask |= INITIAL_INTEGRATE;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixDtReset::init()
{
// set rRESPA flag
respaflag = 0;
if (strstr(update->integrate_style,"respa")) respaflag = 1;
// check for DCD or XTC dumps
for (int i = 0; i < output->ndump; i++)
if ((strcmp(output->dump[i]->style,"dcd") == 0 ||
strcmp(output->dump[i]->style,"xtc") == 0) && comm->me == 0)
- error->warning(FLERR,"Dump dcd/xtc timestamp may be wrong with fix dt/reset");
+ error->warning(FLERR,
+ "Dump dcd/xtc timestamp may be wrong with fix dt/reset");
ftm2v = force->ftm2v;
+ dt = update->dt;
}
/* ---------------------------------------------------------------------- */
void FixDtReset::setup(int vflag)
{
end_of_step();
}
/* ---------------------------------------------------------------------- */
+void FixDtReset::initial_integrate(int vflag)
+{
+ // calculate elapsed time based on previous reset timestep
+
+ t_elapsed = t_laststep + (update->ntimestep-laststep)*dt;
+}
+
+/* ---------------------------------------------------------------------- */
+
void FixDtReset::end_of_step()
{
- double dt,dtv,dtf,dtsq;
+ double dtv,dtf,dtsq;
double vsq,fsq,massinv;
double delx,dely,delz,delr;
- // accumulate total time based on previous timestep
-
- t_elapsed += (update->ntimestep - laststep) * update->dt;
-
// compute vmax and amax of any atom in group
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double dtmin = BIG;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (rmass) massinv = 1.0/rmass[i];
else massinv = 1.0/mass[type[i]];
vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
fsq = f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
dtv = dtf = BIG;
if (vsq > 0.0) dtv = xmax/sqrt(vsq);
if (fsq > 0.0) dtf = sqrt(2.0*xmax/(ftm2v*sqrt(fsq)*massinv));
dt = MIN(dtv,dtf);
dtsq = dt*dt;
delx = dt*v[i][0] + 0.5*dtsq*massinv*f[i][0] * ftm2v;
dely = dt*v[i][1] + 0.5*dtsq*massinv*f[i][1] * ftm2v;
delz = dt*v[i][2] + 0.5*dtsq*massinv*f[i][2] * ftm2v;
delr = sqrt(delx*delx + dely*dely + delz*delz);
if (delr > xmax) dt *= xmax/delr;
dtmin = MIN(dtmin,dt);
}
MPI_Allreduce(&dtmin,&dt,1,MPI_DOUBLE,MPI_MIN,world);
if (minbound) dt = MAX(dt,tmin);
if (maxbound) dt = MIN(dt,tmax);
- // reset update->dt and other classes that depend on it
+ // if timestep didn't change, just return
+ // else reset update->dt and other classes that depend on it
// rRESPA, pair style, fixes
- laststep = update->ntimestep;
if (dt == update->dt) return;
+ t_elapsed = t_laststep += (update->ntimestep-laststep)*update->dt;
+ laststep = update->ntimestep;
+
update->dt = dt;
if (respaflag) update->integrate->reset_dt();
if (force->pair) force->pair->reset_dt();
for (int i = 0; i < modify->nfix; i++) modify->fix[i]->reset_dt();
}
/* ---------------------------------------------------------------------- */
double FixDtReset::compute_scalar()
{
return update->dt;
}
/* ---------------------------------------------------------------------- */
double FixDtReset::compute_vector(int n)
{
- return t_elapsed;
+ if (n == 0) return t_elapsed;
+ return (double) laststep;
}
diff --git a/src/fix_dt_reset.h b/src/fix_dt_reset.h
index 956d35d1b..3a0146c91 100644
--- a/src/fix_dt_reset.h
+++ b/src/fix_dt_reset.h
@@ -1,50 +1,51 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
FixStyle(dt/reset,FixDtReset)
#else
#ifndef LMP_FIX_DT_RESET_H
#define LMP_FIX_DT_RESET_H
#include "fix.h"
namespace LAMMPS_NS {
class FixDtReset : public Fix {
public:
FixDtReset(class LAMMPS *, int, char **);
~FixDtReset() {}
int setmask();
void init();
void setup(int);
+ void initial_integrate(int);
void end_of_step();
double compute_scalar();
double compute_vector(int);
private:
bigint laststep;
int minbound,maxbound;
double tmin,tmax,xmax;
double ftm2v;
- double t_elapsed;
+ double dt,t_elapsed,t_laststep;
int respaflag;
};
}
#endif
#endif
diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp
index d7683d7de..4ee547dd8 100644
--- a/src/fix_langevin.cpp
+++ b/src/fix_langevin.cpp
@@ -1,715 +1,810 @@
/* ----------------------------------------------------------------------
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: Carolyn Phillips (U Mich), reservoir energy tally
------------------------------------------------------------------------- */
#include "mpi.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
#include "fix_langevin.h"
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
#include "force.h"
#include "update.h"
#include "modify.h"
#include "compute.h"
#include "domain.h"
#include "region.h"
#include "respa.h"
#include "comm.h"
+#include "input.h"
+#include "variable.h"
#include "random_mars.h"
#include "memory.h"
#include "error.h"
#include "group.h"
using namespace LAMMPS_NS;
enum{NOBIAS,BIAS};
+enum{CONSTANT,EQUAL,ATOM};
#define SINERTIA 0.4 // moment of inertia prefactor for sphere
#define EINERTIA 0.2 // moment of inertia prefactor for ellipsoid
/* ---------------------------------------------------------------------- */
FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 7) error->all(FLERR,"Illegal fix langevin command");
scalar_flag = 1;
global_freq = 1;
extscalar = 1;
nevery = 1;
- t_start = atof(arg[3]);
+ tstr = NULL;
+ if (strstr(arg[3],"v_") == arg[3]) {
+ int n = strlen(&arg[3][2]) + 1;
+ tstr = new char[n];
+ strcpy(tstr,&arg[3][2]);
+ } else {
+ t_start = atof(arg[3]);
+ tstyle = CONSTANT;
+ }
+
t_stop = atof(arg[4]);
t_period = atof(arg[5]);
int seed = atoi(arg[6]);
if (t_period <= 0.0) error->all(FLERR,"Fix langevin period must be > 0.0");
if (seed <= 0) error->all(FLERR,"Illegal fix langevin command");
// initialize Marsaglia RNG with processor-unique seed
random = new RanMars(lmp,seed + comm->me);
// allocate per-type arrays for force prefactors
gfactor1 = new double[atom->ntypes+1];
gfactor2 = new double[atom->ntypes+1];
ratio = new double[atom->ntypes+1];
// optional args
for (int i = 1; i <= atom->ntypes; i++) ratio[i] = 1.0;
oflag = aflag = 0;
tally = 0;
zeroflag = 0;
int iarg = 7;
while (iarg < narg) {
if (strcmp(arg[iarg],"angmom") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command");
if (strcmp(arg[iarg+1],"no") == 0) aflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) aflag = 1;
else error->all(FLERR,"Illegal fix langevin command");
iarg += 2;
} else if (strcmp(arg[iarg],"omega") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command");
if (strcmp(arg[iarg+1],"no") == 0) oflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) oflag = 1;
else error->all(FLERR,"Illegal fix langevin command");
iarg += 2;
} else if (strcmp(arg[iarg],"scale") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix langevin command");
int itype = atoi(arg[iarg+1]);
double scale = atof(arg[iarg+2]);
if (itype <= 0 || itype > atom->ntypes)
error->all(FLERR,"Illegal fix langevin command");
ratio[itype] = scale;
iarg += 3;
} else if (strcmp(arg[iarg],"tally") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command");
if (strcmp(arg[iarg+1],"no") == 0) tally = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) tally = 1;
else error->all(FLERR,"Illegal fix langevin command");
iarg += 2;
} else if (strcmp(arg[iarg],"zero") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix langevin command");
if (strcmp(arg[iarg+1],"no") == 0) zeroflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) zeroflag = 1;
else error->all(FLERR,"Illegal fix langevin command");
iarg += 2;
} else error->all(FLERR,"Illegal fix langevin command");
}
// error check
if (aflag) {
avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec)
error->all(FLERR,"Fix langevin angmom requires atom style ellipsoid");
}
// set temperature = NULL, user can override via fix_modify if wants bias
id_temp = NULL;
temperature = NULL;
// flangevin is unallocated until first call to setup()
// compute_scalar checks for this and returns 0.0 if flangevin is NULL
- flangevin = NULL;
- nmax = 0;
energy = 0.0;
+ flangevin = NULL;
+ tforce = NULL;
+ maxatom1 = maxatom2 = 0;
}
/* ---------------------------------------------------------------------- */
FixLangevin::~FixLangevin()
{
delete random;
+ delete [] tstr;
delete [] gfactor1;
delete [] gfactor2;
delete [] ratio;
delete [] id_temp;
memory->destroy(flangevin);
+ memory->destroy(tforce);
}
/* ---------------------------------------------------------------------- */
int FixLangevin::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
mask |= END_OF_STEP;
mask |= THERMO_ENERGY;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixLangevin::init()
{
if (oflag && !atom->sphere_flag)
error->all(FLERR,"Fix langevin omega require atom style sphere");
if (aflag && !atom->ellipsoid_flag)
error->all(FLERR,"Fix langevin angmom require atom style ellipsoid");
+ // check variable
+
+ if (tstr) {
+ tvar = input->variable->find(tstr);
+ if (tvar < 0)
+ error->all(FLERR,"Variable name for fix langevin does not exist");
+ if (input->variable->equalstyle(tvar)) tstyle = EQUAL;
+ else if (input->variable->atomstyle(tvar)) tstyle = ATOM;
+ else error->all(FLERR,"Variable for fix langevin is invalid style");
+ }
+
// if oflag or aflag set, check that all group particles are finite-size
if (oflag) {
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
if (radius[i] == 0.0)
error->one(FLERR,"Fix langevin omega requires extended particles");
}
if (aflag) {
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
if (ellipsoid[i] < 0)
error->one(FLERR,"Fix langevin angmom requires extended particles");
}
// set force prefactors
if (!atom->rmass) {
for (int i = 1; i <= atom->ntypes; i++) {
gfactor1[i] = -atom->mass[i] / t_period / force->ftm2v;
gfactor2[i] = sqrt(atom->mass[i]) *
sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) /
force->ftm2v;
gfactor1[i] *= 1.0/ratio[i];
gfactor2[i] *= 1.0/sqrt(ratio[i]);
}
}
if (temperature && temperature->tempbias) which = BIAS;
else which = NOBIAS;
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixLangevin::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
post_force(vflag);
else {
((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
post_force_respa(vflag,nlevels_respa-1,0);
((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
}
}
/* ---------------------------------------------------------------------- */
void FixLangevin::post_force(int vflag)
{
if (tally) post_force_tally();
else post_force_no_tally();
}
/* ---------------------------------------------------------------------- */
void FixLangevin::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixLangevin::post_force_no_tally()
{
- double gamma1,gamma2;
+ double gamma1,gamma2,t_target;
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
- double t_target = t_start + delta * (t_stop-t_start);
- double tsqrt = sqrt(t_target);
+
+ // set current t_target and t_sqrt
+ // if variable temp, evaluate variable, wrap with clear/add
+ // reallocate tforce array if necessary
+
+ if (tstyle == CONSTANT) {
+ t_target = t_start + delta * (t_stop-t_start);
+ tsqrt = sqrt(t_target);
+ } else {
+ modify->clearstep_compute();
+ if (tstyle == EQUAL) {
+ t_target = input->variable->compute_equal(tvar);
+ if (t_target < 0.0)
+ error->one(FLERR,"Fix langevin variable returned negative temperature");
+ tsqrt = sqrt(t_target);
+ } else {
+ if (nlocal > maxatom2) {
+ maxatom2 = atom->nmax;
+ memory->destroy(tforce);
+ memory->create(tforce,maxatom2,"langevin:tforce");
+ }
+ input->variable->compute_atom(tvar,igroup,tforce,1,0);
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit)
+ if (tforce[i] < 0.0)
+ error->one(FLERR,
+ "Fix langevin variable returned negative temperature");
+ }
+ modify->addstep_compute(update->ntimestep + 1);
+ }
// apply damping and thermostat to atoms in group
// for BIAS:
// calculate temperature since some computes require temp
// computed on current nlocal atoms to remove bias
// test v = 0 since some computes mask non-participating atoms via v = 0
// and added force has extra term not multiplied by v = 0
// for ZEROFLAG:
// sum random force over all atoms in group
// subtract sum/count from each atom in group
double fran[3],fsum[3],fsumall[3];
fsum[0] = fsum[1] = fsum[2] = 0.0;
bigint count;
double boltz = force->boltz;
double dt = update->dt;
double mvv2e = force->mvv2e;
double ftm2v = force->ftm2v;
if (zeroflag) {
count = group->count(igroup);
if (count == 0)
error->all(FLERR,"Cannot zero Langevin force of 0 atoms");
}
if (rmass) {
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -rmass[i] / t_period / ftm2v;
gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
fran[0] = gamma2*(random->uniform()-0.5);
fran[1] = gamma2*(random->uniform()-0.5);
fran[2] = gamma2*(random->uniform()-0.5);
f[i][0] += gamma1*v[i][0] + fran[0];
f[i][1] += gamma1*v[i][1] + fran[1];
f[i][2] += gamma1*v[i][2] + fran[2];
fsum[0] += fran[0];
fsum[1] += fran[1];
fsum[2] += fran[2];
}
}
} else if (which == BIAS) {
temperature->compute_scalar();
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -rmass[i] / t_period / ftm2v;
gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
temperature->remove_bias(i,v[i]);
fran[0] = gamma2*(random->uniform()-0.5);
fran[1] = gamma2*(random->uniform()-0.5);
fran[2] = gamma2*(random->uniform()-0.5);
if (v[i][0] != 0.0)
f[i][0] += gamma1*v[i][0] + fran[0];
if (v[i][1] != 0.0)
f[i][1] += gamma1*v[i][1] + fran[1];
if (v[i][2] != 0.0)
f[i][2] += gamma1*v[i][2] + fran[2];
fsum[0] += fran[0];
fsum[1] += fran[1];
fsum[2] += fran[2];
temperature->restore_bias(i,v[i]);
}
}
}
} else {
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = gfactor1[type[i]];
gamma2 = gfactor2[type[i]] * tsqrt;
fran[0] = gamma2*(random->uniform()-0.5);
fran[1] = gamma2*(random->uniform()-0.5);
fran[2] = gamma2*(random->uniform()-0.5);
f[i][0] += gamma1*v[i][0] + fran[0];
f[i][1] += gamma1*v[i][1] + fran[1];
f[i][2] += gamma1*v[i][2] + fran[2];
fsum[0] += fran[0];
fsum[1] += fran[1];
fsum[2] += fran[2];
}
}
} else if (which == BIAS) {
temperature->compute_scalar();
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = gfactor1[type[i]];
gamma2 = gfactor2[type[i]] * tsqrt;
temperature->remove_bias(i,v[i]);
fran[0] = gamma2*(random->uniform()-0.5);
fran[1] = gamma2*(random->uniform()-0.5);
fran[2] = gamma2*(random->uniform()-0.5);
if (v[i][0] != 0.0)
f[i][0] += gamma1*v[i][0] + fran[0];
if (v[i][1] != 0.0)
f[i][1] += gamma1*v[i][1] + fran[1];
if (v[i][2] != 0.0)
f[i][2] += gamma1*v[i][2] + fran[2];
fsum[0] += fran[0];
fsum[1] += fran[1];
fsum[2] += fran[2];
temperature->restore_bias(i,v[i]);
}
}
}
}
// set total force to zero
if (zeroflag) {
MPI_Allreduce(fsum,fsumall,3,MPI_DOUBLE,MPI_SUM,world);
fsumall[0] /= count;
fsumall[1] /= count;
fsumall[2] /= count;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
f[i][0] -= fsumall[0];
f[i][1] -= fsumall[1];
f[i][2] -= fsumall[2];
}
}
}
// thermostat omega and angmom
- if (oflag) omega_thermostat(tsqrt);
- if (aflag) angmom_thermostat(tsqrt);
+ if (oflag) omega_thermostat();
+ if (aflag) angmom_thermostat();
}
/* ---------------------------------------------------------------------- */
void FixLangevin::post_force_tally()
{
- double gamma1,gamma2;
+ double gamma1,gamma2,t_target;
// reallocate flangevin if necessary
- if (atom->nmax > nmax) {
+ if (atom->nlocal > maxatom1) {
memory->destroy(flangevin);
- nmax = atom->nmax;
- memory->create(flangevin,nmax,3,"langevin:flangevin");
+ maxatom1 = atom->nmax;
+ memory->create(flangevin,maxatom1,3,"langevin:flangevin");
}
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
- double t_target = t_start + delta * (t_stop-t_start);
- double tsqrt = sqrt(t_target);
+
+ // set current t_target and t_sqrt
+ // if variable temp, evaluate variable, wrap with clear/add
+ // reallocate tforce array if necessary
+
+ if (tstyle == CONSTANT) {
+ t_target = t_start + delta * (t_stop-t_start);
+ tsqrt = sqrt(t_target);
+ } else {
+ modify->clearstep_compute();
+ if (tstyle == EQUAL) {
+ t_target = input->variable->compute_equal(tvar);
+ if (t_target < 0.0)
+ error->one(FLERR,"Fix langevin variable returned negative temperature");
+ tsqrt = sqrt(t_target);
+ } else {
+ if (nlocal > maxatom2) {
+ maxatom2 = atom->nmax;
+ memory->destroy(tforce);
+ memory->create(tforce,maxatom2,"langevin:tforce");
+ }
+ input->variable->compute_atom(tvar,igroup,tforce,1,0);
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit)
+ if (tforce[i] < 0.0)
+ error->one(FLERR,
+ "Fix langevin variable returned negative temperature");
+ }
+ modify->addstep_compute(update->ntimestep + 1);
+ }
// apply damping and thermostat to appropriate atoms
// for BIAS:
// calculate temperature since some computes require temp
// computed on current nlocal atoms to remove bias
// test v = 0 since some computes mask non-participating atoms via v = 0
// and added force has extra term not multiplied by v = 0
double boltz = force->boltz;
double dt = update->dt;
double mvv2e = force->mvv2e;
double ftm2v = force->ftm2v;
if (rmass) {
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -rmass[i] / t_period / ftm2v;
gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
f[i][0] += flangevin[i][0];
f[i][1] += flangevin[i][1];
f[i][2] += flangevin[i][2];
}
}
} else if (which == BIAS) {
temperature->compute_scalar();
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -rmass[i] / t_period / ftm2v;
gamma2 = sqrt(rmass[i]) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
temperature->remove_bias(i,v[i]);
flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
if (v[i][0] != 0.0) f[i][0] += flangevin[i][0];
else flangevin[i][0] = 0;
if (v[i][1] != 0.0) f[i][1] += flangevin[i][1];
else flangevin[i][1] = 0;
if (v[i][2] != 0.0) f[i][2] += flangevin[i][2];
else flangevin[i][2] = 0;
temperature->restore_bias(i,v[i]);
}
}
}
} else {
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = gfactor1[type[i]];
gamma2 = gfactor2[type[i]] * tsqrt;
flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
f[i][0] += flangevin[i][0];
f[i][1] += flangevin[i][1];
f[i][2] += flangevin[i][2];
}
}
} else if (which == BIAS) {
temperature->compute_scalar();
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = gfactor1[type[i]];
gamma2 = gfactor2[type[i]] * tsqrt;
temperature->remove_bias(i,v[i]);
flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
if (v[i][0] != 0.0) f[i][0] += flangevin[i][0];
else flangevin[i][0] = 0.0;
if (v[i][1] != 0.0) f[i][1] += flangevin[i][1];
else flangevin[i][1] = 0.0;
if (v[i][2] != 0.0) f[i][2] += flangevin[i][2];
else flangevin[i][2] = 0.0;
temperature->restore_bias(i,v[i]);
}
}
}
}
// thermostat omega and angmom
- if (oflag) omega_thermostat(tsqrt);
- if (aflag) angmom_thermostat(tsqrt);
+ if (oflag) omega_thermostat();
+ if (aflag) angmom_thermostat();
}
/* ----------------------------------------------------------------------
thermostat rotational dof via omega
------------------------------------------------------------------------- */
-void FixLangevin::omega_thermostat(double tsqrt)
+void FixLangevin::omega_thermostat()
{
double gamma1,gamma2;
double boltz = force->boltz;
double dt = update->dt;
double mvv2e = force->mvv2e;
double ftm2v = force->ftm2v;
double **torque = atom->torque;
double **omega = atom->omega;
double *radius = atom->radius;
double *rmass = atom->rmass;
int *mask = atom->mask;
int *type = atom->type;
int nlocal = atom->nlocal;
double tran[3];
double inertiaone;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
inertiaone = SINERTIA*radius[i]*radius[i]*rmass[i];
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -inertiaone / t_period / ftm2v;
gamma2 = sqrt(inertiaone) * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
tran[0] = gamma2*(random->uniform()-0.5);
tran[1] = gamma2*(random->uniform()-0.5);
tran[2] = gamma2*(random->uniform()-0.5);
torque[i][0] += gamma1*omega[i][0] + tran[0];
torque[i][1] += gamma1*omega[i][1] + tran[1];
torque[i][2] += gamma1*omega[i][2] + tran[2];
}
}
}
/* ----------------------------------------------------------------------
thermostat rotational dof via angmom
------------------------------------------------------------------------- */
-void FixLangevin::angmom_thermostat(double tsqrt)
+void FixLangevin::angmom_thermostat()
{
double gamma1,gamma2;
double boltz = force->boltz;
double dt = update->dt;
double mvv2e = force->mvv2e;
double ftm2v = force->ftm2v;
AtomVecEllipsoid::Bonus *bonus = avec->bonus;
double **torque = atom->torque;
double **angmom = atom->angmom;
double *rmass = atom->rmass;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int *type = atom->type;
int nlocal = atom->nlocal;
double inertia[3],omega[3],tran[3];
double *shape,*quat;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
shape = bonus[ellipsoid[i]].shape;
inertia[0] = EINERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]);
inertia[1] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]);
inertia[2] = EINERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]);
quat = bonus[ellipsoid[i]].quat;
MathExtra::mq_to_omega(angmom[i],quat,inertia,omega);
+ if (tstyle == ATOM) tsqrt = sqrt(tforce[i]);
gamma1 = -1.0 / t_period / ftm2v;
gamma2 = sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
gamma1 *= 1.0/ratio[type[i]];
gamma2 *= 1.0/sqrt(ratio[type[i]]) * tsqrt;
tran[0] = sqrt(inertia[0])*gamma2*(random->uniform()-0.5);
tran[1] = sqrt(inertia[1])*gamma2*(random->uniform()-0.5);
tran[2] = sqrt(inertia[2])*gamma2*(random->uniform()-0.5);
torque[i][0] += inertia[0]*gamma1*omega[0] + tran[0];
torque[i][1] += inertia[1]*gamma1*omega[1] + tran[1];
torque[i][2] += inertia[2]*gamma1*omega[2] + tran[2];
}
}
}
/* ----------------------------------------------------------------------
tally energy transfer to thermal reservoir
------------------------------------------------------------------------- */
void FixLangevin::end_of_step()
{
if (!tally) return;
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
energy_onestep = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
energy_onestep += flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] +
flangevin[i][2]*v[i][2];
energy += energy_onestep*update->dt;
}
/* ---------------------------------------------------------------------- */
void FixLangevin::reset_target(double t_new)
{
t_start = t_stop = t_new;
}
/* ---------------------------------------------------------------------- */
void FixLangevin::reset_dt()
{
if (atom->mass) {
for (int i = 1; i <= atom->ntypes; i++) {
gfactor2[i] = sqrt(atom->mass[i]) *
sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) /
force->ftm2v;
gfactor2[i] *= 1.0/sqrt(ratio[i]);
}
}
}
/* ---------------------------------------------------------------------- */
int FixLangevin::modify_param(int narg, char **arg)
{
if (strcmp(arg[0],"temp") == 0) {
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
delete [] id_temp;
int n = strlen(arg[1]) + 1;
id_temp = new char[n];
strcpy(id_temp,arg[1]);
int icompute = modify->find_compute(id_temp);
- if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID");
+ if (icompute < 0)
+ error->all(FLERR,"Could not find fix_modify temperature ID");
temperature = modify->compute[icompute];
if (temperature->tempflag == 0)
- error->all(FLERR,"Fix_modify temperature ID does not compute temperature");
+ error->all(FLERR,
+ "Fix_modify temperature ID does not compute temperature");
if (temperature->igroup != igroup && comm->me == 0)
error->warning(FLERR,"Group for fix_modify temp != fix group");
return 2;
}
return 0;
}
/* ---------------------------------------------------------------------- */
double FixLangevin::compute_scalar()
{
if (!tally || flangevin == NULL) return 0.0;
// capture the very first energy transfer to thermal reservoir
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (update->ntimestep == update->beginstep) {
energy_onestep = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
energy_onestep += flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] +
flangevin[i][2]*v[i][2];
energy = 0.5*energy_onestep*update->dt;
}
double energy_me = energy - 0.5*energy_onestep*update->dt;
double energy_all;
MPI_Allreduce(&energy_me,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
return -energy_all;
}
/* ----------------------------------------------------------------------
memory usage of tally array
------------------------------------------------------------------------- */
double FixLangevin::memory_usage()
{
- if (!tally) return 0.0;
- double bytes = atom->nmax*3 * sizeof(double);
+ double bytes = 0.0;
+ if (tally) double bytes = atom->nmax*3 * sizeof(double);
+ if (tforce) bytes = atom->nmax * sizeof(double);
return bytes;
}
diff --git a/src/fix_langevin.h b/src/fix_langevin.h
index 735f6cdcf..80f4335b3 100644
--- a/src/fix_langevin.h
+++ b/src/fix_langevin.h
@@ -1,69 +1,73 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef FIX_CLASS
FixStyle(langevin,FixLangevin)
#else
#ifndef LMP_FIX_LANGEVIN_H
#define LMP_FIX_LANGEVIN_H
#include "fix.h"
namespace LAMMPS_NS {
class FixLangevin : public Fix {
public:
FixLangevin(class LAMMPS *, int, char **);
virtual ~FixLangevin();
int setmask();
void init();
void setup(int);
void post_force(int);
void post_force_respa(int, int, int);
virtual void end_of_step();
void reset_target(double);
void reset_dt();
int modify_param(int, char **);
virtual double compute_scalar();
double memory_usage();
protected:
int which,tally,zeroflag,oflag,aflag;
double t_start,t_stop,t_period;
double *gfactor1,*gfactor2,*ratio;
double energy,energy_onestep;
+ double tsqrt;
+ int tstyle,tvar;
+ char *tstr;
class AtomVecEllipsoid *avec;
- int nmax;
+ int maxatom1,maxatom2;
double **flangevin;
+ double *tforce;
char *id_temp;
class Compute *temperature;
int nlevels_respa;
class RanMars *random;
virtual void post_force_no_tally();
virtual void post_force_tally();
- void omega_thermostat(double);
- void angmom_thermostat(double);
+ void omega_thermostat();
+ void angmom_thermostat();
};
}
#endif
#endif
diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp
index b73b04c5b..1ef84c326 100644
--- a/src/fix_tmd.cpp
+++ b/src/fix_tmd.cpp
@@ -1,561 +1,562 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Paul Crozier (SNL)
Christian Burisch (Bochum Univeristy, Germany)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_tmd.h"
#include "atom.h"
#include "update.h"
#include "modify.h"
#include "domain.h"
#include "group.h"
#include "respa.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define CHUNK 1000
#define MAXLINE 256
/* ---------------------------------------------------------------------- */
FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix tmd command");
rho_stop = atof(arg[3]);
nfileevery = atoi(arg[5]);
- if (rho_stop < 0 || nfileevery < 0) error->all(FLERR,"Illegal fix tmd command");
+ if (rho_stop < 0 || nfileevery < 0)
+ error->all(FLERR,"Illegal fix tmd command");
if (nfileevery && narg != 7) error->all(FLERR,"Illegal fix tmd command");
MPI_Comm_rank(world,&me);
// perform initial allocation of atom-based arrays
// register with Atom class
xf = NULL;
xold = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
// make sure an atom map exists before reading in target coordinates
if (atom->map_style == 0)
error->all(FLERR,"Cannot use fix TMD unless atom map exists");
// read from arg[4] and store coordinates of final target in xf
readfile(arg[4]);
// open arg[6] statistics file and write header
if (nfileevery) {
if (narg != 7) error->all(FLERR,"Illegal fix tmd command");
if (me == 0) {
fp = fopen(arg[6],"w");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open fix tmd file %s",arg[6]);
error->one(FLERR,str);
}
fprintf(fp,"%s %s\n","# Step rho_target rho_old gamma_back",
"gamma_forward lambda work_lambda work_analytical");
}
}
masstotal = group->mass(igroup);
// rho_start = initial rho
// xold = initial x or 0.0 if not in group
int *mask = atom->mask;
int *type = atom->type;
int *image = atom->image;
double **x = atom->x;
double *mass = atom->mass;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double dx,dy,dz;
int xbox,ybox,zbox;
rho_start = 0.0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
xbox = (image[i] & 1023) - 512;
ybox = (image[i] >> 10 & 1023) - 512;
zbox = (image[i] >> 20) - 512;
dx = x[i][0] + xbox*xprd - xf[i][0];
dy = x[i][1] + ybox*yprd - xf[i][1];
dz = x[i][2] + zbox*zprd - xf[i][2];
rho_start += mass[type[i]]*(dx*dx + dy*dy + dz*dz);
xold[i][0] = x[i][0] + xbox*xprd;
xold[i][1] = x[i][1] + ybox*yprd;
xold[i][2] = x[i][2] + zbox*zprd;
} else xold[i][0] = xold[i][1] = xold[i][2] = 0.0;
}
double rho_start_total;
MPI_Allreduce(&rho_start,&rho_start_total,1,MPI_DOUBLE,MPI_SUM,world);
rho_start = sqrt(rho_start_total/masstotal);
rho_old = rho_start;
work_lambda = 0.0;
work_analytical = 0.0;
previous_stat = 0;
}
/* ---------------------------------------------------------------------- */
FixTMD::~FixTMD()
{
if (nfileevery && me == 0) fclose(fp);
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
// delete locally stored arrays
memory->destroy(xf);
memory->destroy(xold);
}
/* ---------------------------------------------------------------------- */
int FixTMD::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= INITIAL_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixTMD::init()
{
// check that no integrator fix comes after a TMD fix
int flag = 0;
for (int i = 0; i < modify->nfix; i++) {
if (strcmp(modify->fix[i]->style,"tmd") == 0) flag = 1;
if (flag && strcmp(modify->fix[i]->style,"nve") == 0) flag = 2;
if (flag && strcmp(modify->fix[i]->style,"nvt") == 0) flag = 2;
if (flag && strcmp(modify->fix[i]->style,"npt") == 0) flag = 2;
if (flag && strcmp(modify->fix[i]->style,"nph") == 0) flag = 2;
}
if (flag == 2) error->all(FLERR,"Fix tmd must come after integration fixes");
// timesteps
dtv = update->dt;
dtf = update->dt * force->ftm2v;
if (strstr(update->integrate_style,"respa"))
step_respa = ((Respa *) update->integrate)->step;
}
/* ---------------------------------------------------------------------- */
void FixTMD::initial_integrate(int vflag)
{
double a,b,c,d,e;
double dx,dy,dz,dxkt,dykt,dzkt;
double dxold,dyold,dzold,xback,yback,zback;
double gamma_forward,gamma_back,gamma_max,lambda;
double kt,fr,kttotal,frtotal,dtfm;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
int *image = atom->image;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int xbox,ybox,zbox;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
double rho_target = rho_start + delta * (rho_stop - rho_start);
// compute the Lagrange multiplier
a = b = e = 0.0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dxold = xold[i][0] - xf[i][0];
dyold = xold[i][1] - xf[i][1];
dzold = xold[i][2] - xf[i][2];
xbox = (image[i] & 1023) - 512;
ybox = (image[i] >> 10 & 1023) - 512;
zbox = (image[i] >> 20) - 512;
dx = x[i][0] + xbox*xprd - xf[i][0];
dy = x[i][1] + ybox*yprd - xf[i][1];
dz = x[i][2] + zbox*zprd - xf[i][2];
a += mass[type[i]]*(dxold*dxold + dyold*dyold + dzold*dzold);
b += mass[type[i]]*(dx *dxold + dy *dyold + dz *dzold);
e += mass[type[i]]*(dx *dx + dy *dy + dz *dz);
}
}
double abe[3],abetotal[3];
abe[0] = a; abe[1] = b; abe[2] = e;
MPI_Allreduce(abe,abetotal,3,MPI_DOUBLE,MPI_SUM,world);
a = abetotal[0]/masstotal;
b = 2.0*abetotal[1]/masstotal;
e = abetotal[2]/masstotal;
c = e - rho_old*rho_old;
d = b*b - 4*a*c;
if (d < 0) d = 0;
if (b >= 0) gamma_max = (-b - sqrt(d))/(2*a);
else gamma_max = (-b + sqrt(d))/(2*a);
gamma_back = c/(a*gamma_max);
if (a == 0.0) gamma_back = 0;
c = e - rho_target*rho_target;
d = b*b - 4*a*c;
if (d < 0) d = 0;
if (b >= 0) gamma_max = (-b - sqrt(d))/(2*a);
else gamma_max = (-b + sqrt(d))/(2*a);
gamma_forward = c/(a*gamma_max);
if (a == 0.0) gamma_forward = 0;
fr = kt = 0.0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dxold = xold[i][0] - xf[i][0];
dyold = xold[i][1] - xf[i][1];
dzold = xold[i][2] - xf[i][2];
xbox = (image[i] & 1023) - 512;
ybox = (image[i] >> 10 & 1023) - 512;
zbox = (image[i] >> 20) - 512;
xback = x[i][0] + xbox*xprd + gamma_back*dxold;
yback = x[i][1] + ybox*yprd + gamma_back*dyold;
zback = x[i][2] + zbox*zprd + gamma_back*dzold;
dxkt = xback - xold[i][0];
dykt = yback - xold[i][1];
dzkt = zback - xold[i][2];
kt += mass[type[i]]*(dxkt*dxkt + dykt*dykt + dzkt*dzkt);
fr += f[i][0]*dxold + f[i][1]*dyold + f[i][2]*dzold;
}
}
double r[2],rtotal[2];
r[0] = fr; r[1] = kt;
MPI_Allreduce(r,rtotal,2,MPI_DOUBLE,MPI_SUM,world);
frtotal = rtotal[0];
kttotal = rtotal[1];
// stat write of mean constraint force based on previous time step constraint
if (nfileevery && me == 0) {
work_analytical +=
(-frtotal - kttotal/dtv/dtf)*(rho_target - rho_old)/rho_old;
lambda = gamma_back*rho_old*masstotal/dtv/dtf;
work_lambda += lambda*(rho_target - rho_old);
if (!(update->ntimestep % nfileevery) &&
(previous_stat != update->ntimestep)) {
fprintf(fp,
BIGINT_FORMAT " %g %g %g %g %g %g %g\n",
update->ntimestep,rho_target,rho_old,
gamma_back,gamma_forward,lambda,work_lambda,work_analytical);
fflush(fp);
previous_stat = update->ntimestep;
}
}
rho_old = rho_target;
// apply the constraint and save constrained positions for next step
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
dxold = xold[i][0] - xf[i][0];
x[i][0] += gamma_forward*dxold;
v[i][0] += gamma_forward*dxold/dtv;
f[i][0] += gamma_forward*dxold/dtv/dtfm;
dyold = xold[i][1] - xf[i][1];
x[i][1] += gamma_forward*dyold;
v[i][1] += gamma_forward*dyold/dtv;
f[i][1] += gamma_forward*dyold/dtv/dtfm;
dzold = xold[i][2] - xf[i][2];
x[i][2] += gamma_forward*dzold;
v[i][2] += gamma_forward*dzold/dtv;
f[i][2] += gamma_forward*dzold/dtv/dtfm;
xbox = (image[i] & 1023) - 512;
ybox = (image[i] >> 10 & 1023) - 512;
zbox = (image[i] >> 20) - 512;
xold[i][0] = x[i][0] + xbox*xprd;
xold[i][1] = x[i][1] + ybox*yprd;
xold[i][2] = x[i][2] + zbox*zprd;
}
}
}
/* ---------------------------------------------------------------------- */
void FixTMD::initial_integrate_respa(int vflag, int ilevel, int flag)
{
if (flag) return; // only used by NPT,NPH
dtv = step_respa[ilevel];
dtf = step_respa[ilevel] * force->ftm2v;
if (ilevel == 0) initial_integrate(vflag);
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double FixTMD::memory_usage()
{
double bytes = 2*atom->nmax*3 * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
allocate atom-based arrays
------------------------------------------------------------------------- */
void FixTMD::grow_arrays(int nmax)
{
memory->grow(xf,nmax,3,"fix_tmd:xf");
memory->grow(xold,nmax,3,"fix_tmd:xold");
}
/* ----------------------------------------------------------------------
copy values within local atom-based arrays
------------------------------------------------------------------------- */
void FixTMD::copy_arrays(int i, int j)
{
xf[j][0] = xf[i][0];
xf[j][1] = xf[i][1];
xf[j][2] = xf[i][2];
xold[j][0] = xold[i][0];
xold[j][1] = xold[i][1];
xold[j][2] = xold[i][2];
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for exchange with another proc
------------------------------------------------------------------------- */
int FixTMD::pack_exchange(int i, double *buf)
{
buf[0] = xf[i][0];
buf[1] = xf[i][1];
buf[2] = xf[i][2];
buf[3] = xold[i][0];
buf[4] = xold[i][1];
buf[5] = xold[i][2];
return 6;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based arrays from exchange with another proc
------------------------------------------------------------------------- */
int FixTMD::unpack_exchange(int nlocal, double *buf)
{
xf[nlocal][0] = buf[0];
xf[nlocal][1] = buf[1];
xf[nlocal][2] = buf[2];
xold[nlocal][0] = buf[3];
xold[nlocal][1] = buf[4];
xold[nlocal][2] = buf[5];
return 6;
}
/* ----------------------------------------------------------------------
read target coordinates from file, store with appropriate atom
------------------------------------------------------------------------- */
void FixTMD::readfile(char *file)
{
if (me == 0) {
if (screen) fprintf(screen,"Reading TMD target file %s ...\n",file);
open(file);
}
int *mask = atom->mask;
int nlocal = atom->nlocal;
char *buffer = new char[CHUNK*MAXLINE];
char *ptr,*next,*bufptr;
int i,m,nlines,tag,imageflag,ix,iy,iz;
double x,y,z,xprd,yprd,zprd;
int firstline = 1;
int ncount = 0;
int eof = 0;
xprd = yprd = zprd = -1.0;
while (!eof) {
if (me == 0) {
m = 0;
for (nlines = 0; nlines < CHUNK; nlines++) {
ptr = fgets(&buffer[m],MAXLINE,fp);
if (ptr == NULL) break;
m += strlen(&buffer[m]);
}
if (ptr == NULL) eof = 1;
buffer[m++] = '\n';
}
MPI_Bcast(&eof,1,MPI_INT,0,world);
MPI_Bcast(&nlines,1,MPI_INT,0,world);
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
bufptr = buffer;
for (i = 0; i < nlines; i++) {
next = strchr(bufptr,'\n');
*next = '\0';
if (firstline) {
if (strstr(bufptr,"xlo xhi")) {
double lo,hi;
sscanf(bufptr,"%lg %lg",&lo,&hi);
xprd = hi - lo;
bufptr = next + 1;
continue;
} else if (strstr(bufptr,"ylo yhi")) {
double lo,hi;
sscanf(bufptr,"%lg %lg",&lo,&hi);
yprd = hi - lo;
bufptr = next + 1;
continue;
} else if (strstr(bufptr,"zlo zhi")) {
double lo,hi;
sscanf(bufptr,"%lg %lg",&lo,&hi);
zprd = hi - lo;
bufptr = next + 1;
continue;
} else if (atom->count_words(bufptr) == 4) {
if (xprd >= 0.0 || yprd >= 0.0 || zprd >= 0.0)
error->all(FLERR,"Incorrect format in TMD target file");
imageflag = 0;
firstline = 0;
} else if (atom->count_words(bufptr) == 7) {
if (xprd < 0.0 || yprd < 0.0 || zprd < 0.0)
error->all(FLERR,"Incorrect format in TMD target file");
imageflag = 1;
firstline = 0;
} else error->all(FLERR,"Incorrect format in TMD target file");
}
if (imageflag)
sscanf(bufptr,"%d %lg %lg %lg %d %d %d",&tag,&x,&y,&z,&ix,&iy,&iz);
else
sscanf(bufptr,"%d %lg %lg %lg",&tag,&x,&y,&z);
m = atom->map(tag);
if (m >= 0 && m < nlocal && mask[m] & groupbit) {
if (imageflag) {
xf[m][0] = x + ix*xprd;
xf[m][1] = y + iy*yprd;
xf[m][2] = z + iz*zprd;
} else {
xf[m][0] = x;
xf[m][1] = y;
xf[m][2] = z;
}
ncount++;
}
bufptr = next + 1;
}
}
// clean up
delete [] buffer;
if (me == 0) {
if (compressed) pclose(fp);
else fclose(fp);
}
// check that all atoms in group were listed in target file
// set xf = 0.0 for atoms not in group
int gcount = 0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) gcount++;
else xf[i][0] = xf[i][1] = xf[i][2] = 0.0;
int flag = 0;
if (gcount != ncount) flag = 1;
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall) error->all(FLERR,"TMD target file did not list all group atoms");
}
/* ----------------------------------------------------------------------
proc 0 opens TMD data file
test if gzipped
------------------------------------------------------------------------- */
void FixTMD::open(char *file)
{
compressed = 0;
char *suffix = file + strlen(file) - 3;
if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
if (!compressed) fp = fopen(file,"r");
else {
#ifdef LAMMPS_GZIP
char gunzip[128];
sprintf(gunzip,"gunzip -c %s",file);
fp = popen(gunzip,"r");
#else
error->one(FLERR,"Cannot open gzipped file");
#endif
}
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
}
/* ---------------------------------------------------------------------- */
void FixTMD::reset_dt()
{
dtv = update->dt;
dtf = update->dt * force->ftm2v;
}
diff --git a/src/force.cpp b/src/force.cpp
index 2600b7dbf..c195b39d7 100644
--- a/src/force.cpp
+++ b/src/force.cpp
@@ -1,710 +1,725 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#include "force.h"
#include "style_bond.h"
#include "style_angle.h"
#include "style_dihedral.h"
#include "style_improper.h"
#include "style_pair.h"
#include "style_kspace.h"
#include "atom.h"
#include "comm.h"
#include "pair.h"
#include "pair_hybrid.h"
#include "bond.h"
#include "bond_hybrid.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "kspace.h"
#include "group.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Force::Force(LAMMPS *lmp) : Pointers(lmp)
{
newton = newton_pair = newton_bond = 1;
special_lj[0] = special_coul[0] = 1.0;
special_lj[1] = special_lj[2] = special_lj[3] = 0.0;
special_coul[1] = special_coul[2] = special_coul[3] = 0.0;
special_angle = special_dihedral = 0;
special_extra = 0;
dielectric = 1.0;
pair = NULL;
bond = NULL;
angle = NULL;
dihedral = NULL;
improper = NULL;
kspace = NULL;
char *str = (char *) "none";
int n = strlen(str) + 1;
pair_style = new char[n];
strcpy(pair_style,str);
bond_style = new char[n];
strcpy(bond_style,str);
angle_style = new char[n];
strcpy(angle_style,str);
dihedral_style = new char[n];
strcpy(dihedral_style,str);
improper_style = new char[n];
strcpy(improper_style,str);
kspace_style = new char[n];
strcpy(kspace_style,str);
}
/* ---------------------------------------------------------------------- */
Force::~Force()
{
delete [] pair_style;
delete [] bond_style;
delete [] angle_style;
delete [] dihedral_style;
delete [] improper_style;
delete [] kspace_style;
if (pair) delete pair;
if (bond) delete bond;
if (angle) delete angle;
if (dihedral) delete dihedral;
if (improper) delete improper;
if (kspace) delete kspace;
}
/* ---------------------------------------------------------------------- */
void Force::init()
{
qqrd2e = qqr2e/dielectric;
if (kspace) kspace->init(); // kspace must come before pair
if (pair) pair->init(); // so g_ewald is defined
if (bond) bond->init();
if (angle) angle->init();
if (dihedral) dihedral->init();
if (improper) improper->init();
}
/* ----------------------------------------------------------------------
create a pair style, called from input script or restart file
------------------------------------------------------------------------- */
void Force::create_pair(const char *style, const char *suffix)
{
delete [] pair_style;
if (pair) delete pair;
int sflag;
pair = new_pair(style,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
pair_style = new char[n];
strcpy(pair_style,estyle);
} else {
int n = strlen(style) + 1;
pair_style = new char[n];
strcpy(pair_style,style);
}
}
/* ----------------------------------------------------------------------
generate a pair class, first with suffix appended
------------------------------------------------------------------------- */
Pair *Force::new_pair(const char *style, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define PAIR_CLASS
#define PairStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp);
#include "style_pair.h"
#undef PairStyle
#undef PAIR_CLASS
}
sflag = 0;
if (strcmp(style,"none") == 0) return NULL;
#define PAIR_CLASS
#define PairStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp);
#include "style_pair.h"
#undef PAIR_CLASS
else error->all(FLERR,"Invalid pair style");
return NULL;
}
/* ----------------------------------------------------------------------
return ptr to Pair class if matches word or to matching hybrid sub-class
if exact, then style name must be exact match to word
if not exact, style name must contain word
return NULL if no match
return NULL if not exact and multiple hybrid sub-styles match
------------------------------------------------------------------------- */
Pair *Force::pair_match(const char *word, int exact)
{
int iwhich,count;
if (exact && strcmp(pair_style,word) == 0) return pair;
else if (!exact && strstr(pair_style,word)) return pair;
else if (strstr(pair_style,"hybrid/overlay")) {
PairHybridOverlay *hybrid = (PairHybridOverlay *) pair;
count = 0;
for (int i = 0; i < hybrid->nstyles; i++) {
if (exact && strcmp(hybrid->keywords[i],word) == 0)
return hybrid->styles[i];
else if (!exact && strstr(hybrid->keywords[i],word)) {
iwhich = i;
count++;
}
}
if (!exact && count == 1) return hybrid->styles[iwhich];
} else if (strstr(pair_style,"hybrid")) {
PairHybrid *hybrid = (PairHybrid *) pair;
count = 0;
for (int i = 0; i < hybrid->nstyles; i++) {
if (exact && strcmp(hybrid->keywords[i],word) == 0)
return hybrid->styles[i];
if (!exact && strstr(hybrid->keywords[i],word)) {
iwhich = i;
count++;
}
}
if (!exact && count == 1) return hybrid->styles[iwhich];
}
return NULL;
}
/* ----------------------------------------------------------------------
create a bond style, called from input script or restart file
------------------------------------------------------------------------- */
void Force::create_bond(const char *style, const char *suffix)
{
delete [] bond_style;
if (bond) delete bond;
int sflag;
bond = new_bond(style,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
bond_style = new char[n];
strcpy(bond_style,estyle);
} else {
int n = strlen(style) + 1;
bond_style = new char[n];
strcpy(bond_style,style);
}
}
/* ----------------------------------------------------------------------
generate a bond class, fist with suffix appended
------------------------------------------------------------------------- */
Bond *Force::new_bond(const char *style, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define BOND_CLASS
#define BondStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp);
#include "style_bond.h"
#undef BondStyle
#undef BOND_CLASS
}
sflag = 0;
if (strcmp(style,"none") == 0) return NULL;
#define BOND_CLASS
#define BondStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp);
#include "style_bond.h"
#undef BOND_CLASS
else error->all(FLERR,"Invalid bond style");
return NULL;
}
/* ----------------------------------------------------------------------
return ptr to current bond class or hybrid sub-class if matches style
------------------------------------------------------------------------- */
Bond *Force::bond_match(const char *style)
{
if (strcmp(bond_style,style) == 0) return bond;
else if (strcmp(bond_style,"hybrid") == 0) {
BondHybrid *hybrid = (BondHybrid *) bond;
for (int i = 0; i < hybrid->nstyles; i++)
if (strcmp(hybrid->keywords[i],style) == 0) return hybrid->styles[i];
}
return NULL;
}
/* ----------------------------------------------------------------------
create an angle style, called from input script or restart file
------------------------------------------------------------------------- */
void Force::create_angle(const char *style, const char *suffix)
{
delete [] angle_style;
if (angle) delete angle;
int sflag;
angle = new_angle(style,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
angle_style = new char[n];
strcpy(angle_style,estyle);
} else {
int n = strlen(style) + 1;
angle_style = new char[n];
strcpy(angle_style,style);
}
}
/* ----------------------------------------------------------------------
generate an angle class
------------------------------------------------------------------------- */
Angle *Force::new_angle(const char *style, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define ANGLE_CLASS
#define AngleStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp);
#include "style_angle.h"
#undef AngleStyle
#undef ANGLE_CLASS
}
sflag = 0;
if (strcmp(style,"none") == 0) return NULL;
#define ANGLE_CLASS
#define AngleStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp);
#include "style_angle.h"
#undef ANGLE_CLASS
else error->all(FLERR,"Invalid angle style");
return NULL;
}
/* ----------------------------------------------------------------------
create a dihedral style, called from input script or restart file
------------------------------------------------------------------------- */
void Force::create_dihedral(const char *style, const char *suffix)
{
delete [] dihedral_style;
if (dihedral) delete dihedral;
int sflag;
dihedral = new_dihedral(style,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
dihedral_style = new char[n];
strcpy(dihedral_style,estyle);
} else {
int n = strlen(style) + 1;
dihedral_style = new char[n];
strcpy(dihedral_style,style);
}
}
/* ----------------------------------------------------------------------
generate a dihedral class
------------------------------------------------------------------------- */
Dihedral *Force::new_dihedral(const char *style, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define DIHEDRAL_CLASS
#define DihedralStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp);
#include "style_dihedral.h"
#undef DihedralStyle
#undef DIHEDRAL_CLASS
}
sflag = 0;
if (strcmp(style,"none") == 0) return NULL;
#define DIHEDRAL_CLASS
#define DihedralStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp);
#include "style_dihedral.h"
#undef DihedralStyle
#undef DIHEDRAL_CLASS
else error->all(FLERR,"Invalid dihedral style");
return NULL;
}
/* ----------------------------------------------------------------------
create an improper style, called from input script or restart file
------------------------------------------------------------------------- */
void Force::create_improper(const char *style, const char *suffix)
{
delete [] improper_style;
if (improper) delete improper;
int sflag;
improper = new_improper(style,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
improper_style = new char[n];
strcpy(improper_style,estyle);
} else {
int n = strlen(style) + 1;
improper_style = new char[n];
strcpy(improper_style,style);
}
}
/* ----------------------------------------------------------------------
generate a improper class
------------------------------------------------------------------------- */
Improper *Force::new_improper(const char *style, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define IMPROPER_CLASS
#define ImproperStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp);
#include "style_improper.h"
#undef ImproperStyle
#undef IMPROPER_CLASS
}
sflag = 0;
if (strcmp(style,"none") == 0) return NULL;
#define IMPROPER_CLASS
#define ImproperStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp);
#include "style_improper.h"
#undef IMPROPER_CLASS
else error->all(FLERR,"Invalid improper style");
return NULL;
}
/* ----------------------------------------------------------------------
new kspace style
------------------------------------------------------------------------- */
void Force::create_kspace(int narg, char **arg, const char *suffix)
{
delete [] kspace_style;
if (kspace) delete kspace;
int sflag;
kspace = new_kspace(narg,arg,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",arg[0],suffix);
int n = strlen(estyle) + 1;
kspace_style = new char[n];
strcpy(kspace_style,estyle);
} else {
int n = strlen(arg[0]) + 1;
kspace_style = new char[n];
strcpy(kspace_style,arg[0]);
}
}
/* ----------------------------------------------------------------------
generate a kspace class
------------------------------------------------------------------------- */
KSpace *Force::new_kspace(int narg, char **arg, const char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",arg[0],suffix);
if (0) return NULL;
#define KSPACE_CLASS
#define KSpaceStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp,narg-1,&arg[1]);
#include "style_kspace.h"
#undef KSpaceStyle
#undef KSPACE_CLASS
}
sflag = 0;
if (strcmp(arg[0],"none") == 0) return NULL;
#define KSPACE_CLASS
#define KSpaceStyle(key,Class) \
else if (strcmp(arg[0],#key) == 0) return new Class(lmp,narg-1,&arg[1]);
#include "style_kspace.h"
#undef KSPACE_CLASS
else error->all(FLERR,"Invalid kspace style");
return NULL;
}
+/* ----------------------------------------------------------------------
+ return ptr to Kspace class if matches word
+ if exact, then style name must be exact match to word
+ if not exact, style name must contain word
+ return NULL if no match
+------------------------------------------------------------------------- */
+
+KSpace *Force::kspace_match(const char *word, int exact)
+{
+ if (exact && strcmp(kspace_style,word) == 0) return kspace;
+ else if (!exact && strstr(kspace_style,word)) return kspace;
+ return NULL;
+}
+
/* ----------------------------------------------------------------------
set special bond values
------------------------------------------------------------------------- */
void Force::set_special(int narg, char **arg)
{
if (narg == 0) error->all(FLERR,"Illegal special_bonds command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"amber") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = 0.0;
special_lj[2] = 0.0;
special_lj[3] = 0.5;
special_coul[1] = 0.0;
special_coul[2] = 0.0;
special_coul[3] = 5.0/6.0;
iarg += 1;
} else if (strcmp(arg[iarg],"charmm") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = 0.0;
special_lj[2] = 0.0;
special_lj[3] = 0.0;
special_coul[1] = 0.0;
special_coul[2] = 0.0;
special_coul[3] = 0.0;
iarg += 1;
} else if (strcmp(arg[iarg],"dreiding") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = 0.0;
special_lj[2] = 0.0;
special_lj[3] = 1.0;
special_coul[1] = 0.0;
special_coul[2] = 0.0;
special_coul[3] = 1.0;
iarg += 1;
} else if (strcmp(arg[iarg],"fene") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = 0.0;
special_lj[2] = 1.0;
special_lj[3] = 1.0;
special_coul[1] = 0.0;
special_coul[2] = 1.0;
special_coul[3] = 1.0;
iarg += 1;
} else if (strcmp(arg[iarg],"lj/coul") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = special_coul[1] = atof(arg[iarg+1]);
special_lj[2] = special_coul[2] = atof(arg[iarg+2]);
special_lj[3] = special_coul[3] = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"lj") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command");
special_lj[1] = atof(arg[iarg+1]);
special_lj[2] = atof(arg[iarg+2]);
special_lj[3] = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"coul") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal special_bonds command");
special_coul[1] = atof(arg[iarg+1]);
special_coul[2] = atof(arg[iarg+2]);
special_coul[3] = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"angle") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command");
if (strcmp(arg[iarg+1],"no") == 0) special_angle = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) special_angle = 1;
else error->all(FLERR,"Illegal special_bonds command");
iarg += 2;
} else if (strcmp(arg[iarg],"dihedral") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command");
if (strcmp(arg[iarg+1],"no") == 0) special_dihedral = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) special_dihedral = 1;
else error->all(FLERR,"Illegal special_bonds command");
iarg += 2;
} else if (strcmp(arg[iarg],"extra") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal special_bonds command");
special_extra = atoi(arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal special_bonds command");
}
for (int i = 1; i <= 3; i++)
if (special_lj[i] < 0.0 || special_lj[i] > 1.0 ||
special_coul[i] < 0.0 || special_coul[i] > 1.0)
error->all(FLERR,"Illegal special_bonds command");
if (special_extra < 0) error->all(FLERR,"Illegal special_bonds command");
}
/* ----------------------------------------------------------------------
compute bounds implied by numeric str with a possible wildcard asterik
- nmax = upper bound
+ 1 = lower bound, nmax = upper bound
5 possibilities:
(1) i = i to i, (2) * = 1 to nmax,
(3) i* = i to nmax, (4) *j = 1 to j, (5) i*j = i to j
return nlo,nhi
------------------------------------------------------------------------- */
void Force::bounds(char *str, int nmax, int &nlo, int &nhi)
{
char *ptr = strchr(str,'*');
if (ptr == NULL) {
- nlo = MAX(atoi(str),1);
- nhi = MIN(atoi(str),nmax);
+ nlo = nhi = atoi(str);
} else if (strlen(str) == 1) {
nlo = 1;
nhi = nmax;
} else if (ptr == str) {
nlo = 1;
- nhi = MIN(atoi(ptr+1),nmax);
+ nhi = atoi(ptr+1);
} else if (strlen(ptr+1) == 0) {
- nlo = MAX(atoi(str),1);
+ nlo = atoi(str);
nhi = nmax;
} else {
- nlo = MAX(atoi(str),1);
- nhi = MIN(atoi(ptr+1),nmax);
+ nlo = atoi(str);
+ nhi = atoi(ptr+1);
}
+
+ if (nlo < 1 || nhi > nmax) error->all(FLERR,"Numeric index is out of bounds");
}
/* ----------------------------------------------------------------------
read a floating point value from a string
generate an error if not a legitimate floating point value
called by force fields to check validity of their arguments
------------------------------------------------------------------------- */
double Force::numeric(char *str)
{
int n = strlen(str);
for (int i = 0; i < n; i++) {
if (isdigit(str[i])) continue;
if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue;
if (str[i] == 'e' || str[i] == 'E') continue;
error->all(FLERR,"Expected floating point parameter in "
"input script or data file");
}
return atof(str);
}
/* ----------------------------------------------------------------------
read an integer value from a string
generate an error if not a legitimate integer value
called by force fields to check validity of their arguments
------------------------------------------------------------------------- */
int Force::inumeric(char *str)
{
int n = strlen(str);
for (int i = 0; i < n; i++) {
if (isdigit(str[i]) || str[i] == '-' || str[i] == '+') continue;
error->all(FLERR,"Expected integer parameter in input script or data file");
}
return atoi(str);
}
/* ----------------------------------------------------------------------
memory usage of force classes
------------------------------------------------------------------------- */
bigint Force::memory_usage()
{
bigint bytes = 0;
if (pair) bytes += static_cast<bigint> (pair->memory_usage());
if (bond) bytes += static_cast<bigint> (bond->memory_usage());
if (angle) bytes += static_cast<bigint> (angle->memory_usage());
if (dihedral) bytes += static_cast<bigint> (dihedral->memory_usage());
if (improper) bytes += static_cast<bigint> (improper->memory_usage());
if (kspace) bytes += static_cast<bigint> (kspace->memory_usage());
return bytes;
}
diff --git a/src/force.h b/src/force.h
index a7089070d..bafa38acf 100644
--- a/src/force.h
+++ b/src/force.h
@@ -1,101 +1,102 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_FORCE_H
#define LMP_FORCE_H
#include "pointers.h"
namespace LAMMPS_NS {
class Force : protected Pointers {
public:
double boltz; // Boltzmann constant (eng/degree-K)
double hplanck; // Planck's constant (energy-time)
double mvv2e; // conversion of mv^2 to energy
double ftm2v; // conversion of ft/m to velocity
double mv2d; // conversion of mass/volume to density
double nktv2p; // conversion of NkT/V to pressure
double qqr2e; // conversion of q^2/r to energy
double qe2f; // conversion of qE to force
double vxmu2f; // conversion of vx dynamic-visc to force
double xxt2kmu; // conversion of xx/t to kinematic-visc
double dielectric; // dielectric constant
double qqrd2e; // q^2/r to energy w/ dielectric constant
double e_mass; // electron mass
double hhmrr2e; // conversion of (hbar)^2/(mr^2) to energy
double mvh2r; // conversion of mv/hbar to distance
// hbar = h/(2*pi)
int newton,newton_pair,newton_bond; // Newton's 3rd law settings
class Pair *pair;
char *pair_style;
class Bond *bond;
char *bond_style;
class Angle *angle;
char *angle_style;
class Dihedral *dihedral;
char *dihedral_style;
class Improper *improper;
char *improper_style;
class KSpace *kspace;
char *kspace_style;
// index [0] is not used in these arrays
double special_lj[4]; // 1-2, 1-3, 1-4 prefactors for LJ
double special_coul[4]; // 1-2, 1-3, 1-4 prefactors for Coulombics
int special_angle; // 0 if defined angles are ignored
// 1 if only weight 1,3 atoms if in an angle
int special_dihedral; // 0 if defined dihedrals are ignored
// 1 if only weight 1,4 atoms if in a dihedral
int special_extra; // extra space for added bonds
Force(class LAMMPS *);
~Force();
void init();
void create_pair(const char *, const char *suffix = NULL);
class Pair *new_pair(const char *, const char *, int &);
class Pair *pair_match(const char *, int);
void create_bond(const char *, const char *suffix = NULL);
class Bond *new_bond(const char *, const char *, int &);
class Bond *bond_match(const char *);
void create_angle(const char *, const char *suffix = NULL);
class Angle *new_angle(const char *, const char *, int &);
void create_dihedral(const char *, const char *suffix = NULL);
class Dihedral *new_dihedral(const char *, const char *, int &);
void create_improper(const char *, const char *suffix = NULL);
class Improper *new_improper(const char *, const char *, int &);
void create_kspace(int, char **, const char *suffix = NULL);
class KSpace *new_kspace(int, char **, const char *, int &);
+ class KSpace *kspace_match(const char *, int);
void set_special(int, char **);
void bounds(char *, int, int &, int &);
double numeric(char *);
int inumeric(char *);
bigint memory_usage();
};
}
#endif
diff --git a/src/input.cpp b/src/input.cpp
index 457faf4ac..b0358004d 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -1,1370 +1,1387 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#include "unistd.h"
#include "sys/stat.h"
#include "input.h"
#include "style_command.h"
#include "universe.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "group.h"
#include "domain.h"
#include "output.h"
#include "thermo.h"
#include "force.h"
#include "pair.h"
#include "min.h"
#include "modify.h"
#include "compute.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "kspace.h"
#include "update.h"
#include "neighbor.h"
#include "special.h"
#include "variable.h"
#include "accelerator_cuda.h"
#include "error.h"
#include "memory.h"
#ifdef _OPENMP
#include "omp.h"
#endif
using namespace LAMMPS_NS;
#define MAXLINE 2048
#define DELTA 4
/* ---------------------------------------------------------------------- */
Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
line = new char[MAXLINE];
copy = new char[MAXLINE];
work = new char[MAXLINE];
narg = maxarg = 0;
arg = NULL;
echo_screen = 0;
echo_log = 1;
label_active = 0;
labelstr = NULL;
jump_skip = 0;
if (me == 0) {
nfile = maxfile = 1;
infiles = (FILE **) memory->smalloc(sizeof(FILE *),"input:infiles");
infiles[0] = infile;
} else infiles = NULL;
variable = new Variable(lmp);
// process command-line args
// check for args "-var" and "-echo"
// caller has already checked that sufficient arguments exist
int iarg = 0;
while (iarg < argc) {
if (strcmp(argv[iarg],"-var") == 0 || strcmp(argv[iarg],"-v") == 0) {
int jarg = iarg+3;
while (jarg < argc && argv[jarg][0] != '-') jarg++;
variable->set(argv[iarg+1],jarg-iarg-2,&argv[iarg+2]);
iarg = jarg;
} else if (strcmp(argv[iarg],"-echo") == 0 ||
strcmp(argv[iarg],"-e") == 0) {
narg = 1;
char **tmp = arg; // trick echo() into using argv instead of arg
arg = &argv[iarg+1];
echo();
arg = tmp;
iarg += 2;
} else iarg++;
}
}
/* ---------------------------------------------------------------------- */
Input::~Input()
{
// don't free command and arg strings
// they just point to other allocated memory
delete variable;
delete [] line;
delete [] copy;
delete [] work;
if (labelstr) delete [] labelstr;
memory->sfree(arg);
memory->sfree(infiles);
}
/* ----------------------------------------------------------------------
process all input from infile
infile = stdin or file if command-line arg "-in" was used
------------------------------------------------------------------------- */
void Input::file()
{
int m,n;
while (1) {
// read a line from input script
// if line ends in continuation char '&', concatenate next line(s)
// n = length of line including str terminator, 0 if end of file
// m = position of last printable char in line or -1 if blank line
if (me == 0) {
m = 0;
while (1) {
if (fgets(&line[m],MAXLINE-m,infile) == NULL) n = 0;
else n = strlen(line) + 1;
if (n == 0) break;
m = n-2;
while (m >= 0 && isspace(line[m])) m--;
if (m < 0 || line[m] != '&') break;
}
}
// bcast the line
// if n = 0, end-of-file
// error if label_active is set, since label wasn't encountered
// if original input file, code is done
// else go back to previous input file
MPI_Bcast(&n,1,MPI_INT,0,world);
if (n == 0) {
if (label_active) error->all(FLERR,"Label wasn't found in input script");
if (me == 0) {
if (infile != stdin) fclose(infile);
nfile--;
}
MPI_Bcast(&nfile,1,MPI_INT,0,world);
if (nfile == 0) break;
if (me == 0) infile = infiles[nfile-1];
continue;
}
MPI_Bcast(line,n,MPI_CHAR,0,world);
// if n = MAXLINE, line is too long
if (n == MAXLINE) {
char str[MAXLINE+32];
sprintf(str,"Input line too long: %s",line);
error->all(FLERR,str);
}
// echo the command unless scanning for label
if (me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s",line);
if (echo_log && logfile) fprintf(logfile,"%s",line);
}
// parse the line
// if no command, skip to next line in input script
parse();
if (command == NULL) continue;
// if scanning for label, skip command unless it's a label command
if (label_active && strcmp(command,"label") != 0) continue;
// execute the command
if (execute_command()) {
char str[MAXLINE];
sprintf(str,"Unknown command: %s",line);
error->all(FLERR,str);
}
}
}
/* ----------------------------------------------------------------------
process all input from filename
------------------------------------------------------------------------- */
void Input::file(const char *filename)
{
// error if another nested file still open
// if single open file is not stdin, close it
// open new filename and set infile, infiles[0]
if (me == 0) {
if (nfile > 1)
error->one(FLERR,"Another input script is already being processed");
if (infile != stdin) fclose(infile);
infile = fopen(filename,"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",filename);
error->one(FLERR,str);
}
infiles[0] = infile;
} else infile = NULL;
file();
}
/* ----------------------------------------------------------------------
parse the command in single and execute it
return command name to caller
------------------------------------------------------------------------- */
char *Input::one(const char *single)
{
strcpy(line,single);
// echo the command unless scanning for label
if (me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s\n",line);
if (echo_log && logfile) fprintf(logfile,"%s\n",line);
}
// parse the line
// if no command, just return NULL
parse();
if (command == NULL) return NULL;
// if scanning for label, skip command unless it's a label command
if (label_active && strcmp(command,"label") != 0) return NULL;
// execute the command and return its name
if (execute_command()) {
char str[MAXLINE];
sprintf(str,"Unknown command: %s",line);
error->all(FLERR,str);
}
return command;
}
/* ----------------------------------------------------------------------
parse copy of command line
strip comment = all chars from # on
replace all $ via variable substitution
command = first word
narg = # of args
arg[] = individual args
treat text between single/double quotes as one arg
------------------------------------------------------------------------- */
void Input::parse()
{
// make a copy to work on
strcpy(copy,line);
// strip any # comment by resetting string terminator
// do not strip # inside single/double quotes
char quote = '\0';
char *ptr = copy;
while (*ptr) {
if (*ptr == '#' && !quote) {
*ptr = '\0';
break;
}
if (*ptr == quote) quote = '\0';
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
ptr++;
}
// perform $ variable substitution (print changes)
// except if searching for a label since earlier variable may not be defined
if (!label_active) substitute(copy,1);
// command = 1st arg
command = strtok(copy," \t\n\r\f");
if (command == NULL) return;
// point arg[] at each subsequent arg
// treat text between single/double quotes as one arg
// insert string terminators in copy to delimit args
quote = '\0';
int iarg,argstart;
narg = 0;
while (1) {
if (narg == maxarg) {
maxarg += DELTA;
arg = (char **) memory->srealloc(arg,maxarg*sizeof(char *),"input:arg");
}
arg[narg] = strtok(NULL," \t\n\r\f");
if (!arg[narg]) break;
if (!quote && (arg[narg][0] == '"' || arg[narg][0] == '\'')) {
quote = arg[narg][0];
argstart = narg;
arg[narg] = &arg[narg][1];
}
if (quote && arg[narg][strlen(arg[narg])-1] == quote) {
for (iarg = argstart; iarg < narg; iarg++)
arg[iarg][strlen(arg[iarg])] = ' ';
arg[narg][strlen(arg[narg])-1] = '\0';
narg = argstart;
quote = '\0';
}
narg++;
}
if (quote) error->all(FLERR,"Unbalanced quotes in input line");
}
/* ----------------------------------------------------------------------
substitute for $ variables in str and return it
str assumed to be long enough to hold expanded version
print updated string if flag is set and not searching for label
------------------------------------------------------------------------- */
void Input::substitute(char *str, int flag)
{
// use work[] as scratch space to expand str, then copy back to str
// do not replace $ inside single/double quotes
// var = pts at variable name, ended by NULL
// if $ is followed by '{', trailing '}' becomes NULL
// else $x becomes x followed by NULL
// beyond = pts at text following variable
char *var,*value,*beyond;
char quote = '\0';
char *ptr = str;
while (*ptr) {
if (*ptr == '$' && !quote) {
if (*(ptr+1) == '{') {
var = ptr+2;
int i = 0;
while (var[i] != '\0' && var[i] != '}') i++;
if (var[i] == '\0') error->one(FLERR,"Invalid variable name");
var[i] = '\0';
beyond = ptr + strlen(var) + 3;
} else {
var = ptr;
var[0] = var[1];
var[1] = '\0';
beyond = ptr + strlen(var) + 1;
}
value = variable->retrieve(var);
if (value == NULL) error->one(FLERR,"Substitution for illegal variable");
*ptr = '\0';
strcpy(work,str);
if (strlen(work)+strlen(value) >= MAXLINE)
error->one(FLERR,"Input line too long after variable substitution");
strcat(work,value);
if (strlen(work)+strlen(beyond) >= MAXLINE)
error->one(FLERR,"Input line too long after variable substitution");
strcat(work,beyond);
strcpy(str,work);
ptr += strlen(value);
if (flag && me == 0 && label_active == 0) {
if (echo_screen && screen) fprintf(screen,"%s",str);
if (echo_log && logfile) fprintf(logfile,"%s",str);
}
continue;
}
if (*ptr == quote) quote = '\0';
else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
ptr++;
}
}
/* ----------------------------------------------------------------------
process a single parsed command
return 0 if successful, -1 if did not recognize command
------------------------------------------------------------------------- */
int Input::execute_command()
{
int flag = 1;
if (!strcmp(command,"clear")) clear();
else if (!strcmp(command,"echo")) echo();
else if (!strcmp(command,"if")) ifthenelse();
else if (!strcmp(command,"include")) include();
else if (!strcmp(command,"jump")) jump();
else if (!strcmp(command,"label")) label();
else if (!strcmp(command,"log")) log();
else if (!strcmp(command,"next")) next_command();
+ else if (!strcmp(command,"partition")) partition();
else if (!strcmp(command,"print")) print();
else if (!strcmp(command,"shell")) shell();
else if (!strcmp(command,"variable")) variable_command();
else if (!strcmp(command,"angle_coeff")) angle_coeff();
else if (!strcmp(command,"angle_style")) angle_style();
else if (!strcmp(command,"atom_modify")) atom_modify();
else if (!strcmp(command,"atom_style")) atom_style();
else if (!strcmp(command,"bond_coeff")) bond_coeff();
else if (!strcmp(command,"bond_style")) bond_style();
else if (!strcmp(command,"boundary")) boundary();
else if (!strcmp(command,"communicate")) communicate();
else if (!strcmp(command,"compute")) compute();
else if (!strcmp(command,"compute_modify")) compute_modify();
else if (!strcmp(command,"dielectric")) dielectric();
else if (!strcmp(command,"dihedral_coeff")) dihedral_coeff();
else if (!strcmp(command,"dihedral_style")) dihedral_style();
else if (!strcmp(command,"dimension")) dimension();
else if (!strcmp(command,"dump")) dump();
else if (!strcmp(command,"dump_modify")) dump_modify();
else if (!strcmp(command,"fix")) fix();
else if (!strcmp(command,"fix_modify")) fix_modify();
else if (!strcmp(command,"group")) group_command();
else if (!strcmp(command,"improper_coeff")) improper_coeff();
else if (!strcmp(command,"improper_style")) improper_style();
else if (!strcmp(command,"kspace_modify")) kspace_modify();
else if (!strcmp(command,"kspace_style")) kspace_style();
else if (!strcmp(command,"lattice")) lattice();
else if (!strcmp(command,"mass")) mass();
else if (!strcmp(command,"min_modify")) min_modify();
else if (!strcmp(command,"min_style")) min_style();
else if (!strcmp(command,"neigh_modify")) neigh_modify();
else if (!strcmp(command,"neighbor")) neighbor_command();
else if (!strcmp(command,"newton")) newton();
else if (!strcmp(command,"package")) package();
else if (!strcmp(command,"pair_coeff")) pair_coeff();
else if (!strcmp(command,"pair_modify")) pair_modify();
else if (!strcmp(command,"pair_style")) pair_style();
else if (!strcmp(command,"pair_write")) pair_write();
else if (!strcmp(command,"processors")) processors();
else if (!strcmp(command,"region")) region();
else if (!strcmp(command,"reset_timestep")) reset_timestep();
else if (!strcmp(command,"restart")) restart();
else if (!strcmp(command,"run_style")) run_style();
else if (!strcmp(command,"special_bonds")) special_bonds();
else if (!strcmp(command,"suffix")) suffix();
else if (!strcmp(command,"thermo")) thermo();
else if (!strcmp(command,"thermo_modify")) thermo_modify();
else if (!strcmp(command,"thermo_style")) thermo_style();
else if (!strcmp(command,"timestep")) timestep();
else if (!strcmp(command,"uncompute")) uncompute();
else if (!strcmp(command,"undump")) undump();
else if (!strcmp(command,"unfix")) unfix();
else if (!strcmp(command,"units")) units();
else flag = 0;
// return if command was listed above
if (flag) return 0;
// check if command is added via style.h
if (0) return 0; // dummy line to enable else-if macro expansion
#define COMMAND_CLASS
#define CommandStyle(key,Class) \
else if (strcmp(command,#key) == 0) { \
Class key(lmp); \
key.command(narg,arg); \
return 0; \
}
#include "style_command.h"
#undef COMMAND_CLASS
// unrecognized command
return -1;
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void Input::clear()
{
if (narg > 0) error->all(FLERR,"Illegal clear command");
lmp->destroy();
lmp->create();
+ lmp->post_create();
}
/* ---------------------------------------------------------------------- */
void Input::echo()
{
if (narg != 1) error->all(FLERR,"Illegal echo command");
if (strcmp(arg[0],"none") == 0) {
echo_screen = 0;
echo_log = 0;
} else if (strcmp(arg[0],"screen") == 0) {
echo_screen = 1;
echo_log = 0;
} else if (strcmp(arg[0],"log") == 0) {
echo_screen = 0;
echo_log = 1;
} else if (strcmp(arg[0],"both") == 0) {
echo_screen = 1;
echo_log = 1;
} else error->all(FLERR,"Illegal echo command");
}
/* ---------------------------------------------------------------------- */
void Input::ifthenelse()
{
if (narg < 3) error->all(FLERR,"Illegal if command");
// substitute for variables in Boolean expression for "if"
// in case expression was enclosed in quotes
// must substitute on copy of arg else will step on subsequent args
char *scopy = new char[MAXLINE];
strcpy(scopy,arg[0]);
substitute(scopy,0);
// evaluate Boolean expression for "if"
double btest = variable->evaluate_boolean(scopy);
// bound "then" commands
if (strcmp(arg[1],"then") != 0) error->all(FLERR,"Illegal if command");
int first = 2;
int iarg = first;
while (iarg < narg &&
(strcmp(arg[iarg],"elif") != 0 && strcmp(arg[iarg],"else") != 0))
iarg++;
int last = iarg-1;
// execute "then" commands
// make copies of all arg string commands
// required because re-parsing a command via one() will wipe out args
if (btest != 0.0) {
int ncommands = last-first + 1;
if (ncommands <= 0) error->all(FLERR,"Illegal if command");
char **commands = new char*[ncommands];
ncommands = 0;
for (int i = first; i <= last; i++) {
int n = strlen(arg[i]) + 1;
if (n == 1) error->all(FLERR,"Illegal if command");
commands[ncommands] = new char[n];
strcpy(commands[ncommands],arg[i]);
ncommands++;
}
- for (int i = 0; i < ncommands; i++) input->one(commands[i]);
+ for (int i = 0; i < ncommands; i++) one(commands[i]);
for (int i = 0; i < ncommands; i++) delete [] commands[i];
delete [] commands;
delete [] scopy;
return;
}
// done if no "elif" or "else"
if (iarg == narg) {
delete [] scopy;
return;
}
// check "elif" or "else" until find commands to execute
// substitute for variables and evaluate Boolean expression for "elif"
// must substitute on copy of arg else will step on subsequent args
// bound and execute "elif" or "else" commands
while (1) {
if (iarg+2 > narg) error->all(FLERR,"Illegal if command");
if (strcmp(arg[iarg],"elif") == 0) {
strcpy(scopy,arg[iarg+1]);
substitute(scopy,0);
btest = variable->evaluate_boolean(scopy);
first = iarg+2;
} else {
btest = 1.0;
first = iarg+1;
}
iarg = first;
while (iarg < narg &&
(strcmp(arg[iarg],"elif") != 0 && strcmp(arg[iarg],"else") != 0))
iarg++;
last = iarg-1;
if (btest == 0.0) continue;
int ncommands = last-first + 1;
if (ncommands <= 0) error->all(FLERR,"Illegal if command");
char **commands = new char*[ncommands];
ncommands = 0;
for (int i = first; i <= last; i++) {
int n = strlen(arg[i]) + 1;
if (n == 1) error->all(FLERR,"Illegal if command");
commands[ncommands] = new char[n];
strcpy(commands[ncommands],arg[i]);
ncommands++;
}
// execute the list of commands
- for (int i = 0; i < ncommands; i++) input->one(commands[i]);
+ for (int i = 0; i < ncommands; i++) one(commands[i]);
// clean up
for (int i = 0; i < ncommands; i++) delete [] commands[i];
delete [] commands;
delete [] scopy;
return;
}
}
/* ---------------------------------------------------------------------- */
void Input::include()
{
if (narg != 1) error->all(FLERR,"Illegal include command");
if (me == 0) {
if (nfile == maxfile) {
maxfile++;
infiles = (FILE **)
memory->srealloc(infiles,maxfile*sizeof(FILE *),"input:infiles");
}
infile = fopen(arg[0],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[0]);
error->one(FLERR,str);
}
infiles[nfile++] = infile;
}
}
/* ---------------------------------------------------------------------- */
void Input::jump()
{
if (narg < 1 || narg > 2) error->all(FLERR,"Illegal jump command");
if (jump_skip) {
jump_skip = 0;
return;
}
if (me == 0) {
if (strcmp(arg[0],"SELF") == 0) rewind(infile);
else {
if (infile != stdin) fclose(infile);
infile = fopen(arg[0],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[0]);
error->one(FLERR,str);
}
infiles[nfile-1] = infile;
}
}
if (narg == 2) {
label_active = 1;
if (labelstr) delete [] labelstr;
int n = strlen(arg[1]) + 1;
labelstr = new char[n];
strcpy(labelstr,arg[1]);
}
}
/* ---------------------------------------------------------------------- */
void Input::label()
{
if (narg != 1) error->all(FLERR,"Illegal label command");
if (label_active && strcmp(labelstr,arg[0]) == 0) label_active = 0;
}
/* ---------------------------------------------------------------------- */
void Input::log()
{
if (narg != 1) error->all(FLERR,"Illegal log command");
if (me == 0) {
if (logfile) fclose(logfile);
if (strcmp(arg[0],"none") == 0) logfile = NULL;
else {
logfile = fopen(arg[0],"w");
if (logfile == NULL) {
char str[128];
sprintf(str,"Cannot open logfile %s",arg[0]);
error->one(FLERR,str);
}
}
if (universe->nworlds == 1) universe->ulogfile = logfile;
}
}
/* ---------------------------------------------------------------------- */
void Input::next_command()
{
if (variable->next(narg,arg)) jump_skip = 1;
}
/* ---------------------------------------------------------------------- */
+void Input::partition()
+{
+ if (narg < 3) error->all(FLERR,"Illegal partition command");
+
+ int yesflag;
+ if (strcmp(arg[0],"yes") == 0) yesflag = 1;
+ else if (strcmp(arg[0],"no") == 0) yesflag = 0;
+ else error->all(FLERR,"Illegal partition command");
+
+ int ilo,ihi;
+ force->bounds(arg[1],universe->nworlds,ilo,ihi);
+
+ // copy original line to copy, since will use strtok() on it
+ // ptr = start of 4th word
+
+ strcpy(copy,line);
+ copy[strlen(copy)-1] = '\0';
+ char *ptr = strtok(copy," \t\n\r\f");
+ ptr = strtok(NULL," \t\n\r\f");
+ ptr = strtok(NULL," \t\n\r\f");
+ ptr += strlen(ptr) + 1;
+ ptr += strspn(ptr," \t\n\r\f");
+
+ // execute the remaining command line on requested partitions
+
+ if (yesflag) {
+ if (universe->iworld+1 >= ilo && universe->iworld+1 <= ihi) one(ptr);
+ } else {
+ if (universe->iworld+1 < ilo || universe->iworld+1 > ihi) one(ptr);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
void Input::print()
{
if (narg != 1) error->all(FLERR,"Illegal print command");
// substitute for $ variables (no printing) and print arg
substitute(arg[0],0);
if (me == 0) {
if (screen) fprintf(screen,"%s\n",arg[0]);
if (logfile) fprintf(logfile,"%s\n",arg[0]);
}
}
/* ---------------------------------------------------------------------- */
void Input::shell()
{
if (narg < 1) error->all(FLERR,"Illegal shell command");
if (strcmp(arg[0],"cd") == 0) {
if (narg != 2) error->all(FLERR,"Illegal shell command");
chdir(arg[1]);
} else if (strcmp(arg[0],"mkdir") == 0) {
if (narg < 2) error->all(FLERR,"Illegal shell command");
#if !defined(WINDOWS) && !defined(__MINGW32_VERSION)
if (me == 0)
for (int i = 1; i < narg; i++)
mkdir(arg[i], S_IRWXU | S_IRGRP | S_IXGRP);
#endif
} else if (strcmp(arg[0],"mv") == 0) {
if (narg != 3) error->all(FLERR,"Illegal shell command");
if (me == 0) rename(arg[1],arg[2]);
} else if (strcmp(arg[0],"rm") == 0) {
if (narg < 2) error->all(FLERR,"Illegal shell command");
if (me == 0)
for (int i = 1; i < narg; i++) unlink(arg[i]);
} else if (strcmp(arg[0],"rmdir") == 0) {
if (narg < 2) error->all(FLERR,"Illegal shell command");
if (me == 0)
for (int i = 1; i < narg; i++) rmdir(arg[i]);
// use work to concat args back into one string separated by spaces
// invoke string in shell via system()
} else {
strcpy(work,arg[0]);
for (int i = 1; i < narg; i++) {
strcat(work," ");
strcat(work,arg[i]);
}
if (me == 0) system(work);
}
}
/* ---------------------------------------------------------------------- */
void Input::variable_command()
{
variable->set(narg,arg);
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
one function for each LAMMPS-specific input script command
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void Input::angle_coeff()
{
if (domain->box_exist == 0)
error->all(FLERR,"Angle_coeff command before simulation box is defined");
if (force->angle == NULL)
error->all(FLERR,"Angle_coeff command before angle_style is defined");
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Angle_coeff command when no angles allowed");
force->angle->coeff(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::angle_style()
{
if (narg < 1) error->all(FLERR,"Illegal angle_style command");
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Angle_style command when no angles allowed");
force->create_angle(arg[0],lmp->suffix);
if (force->angle) force->angle->settings(narg-1,&arg[1]);
}
/* ---------------------------------------------------------------------- */
void Input::atom_modify()
{
atom->modify_params(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::atom_style()
{
if (narg < 1) error->all(FLERR,"Illegal atom_style command");
if (domain->box_exist)
error->all(FLERR,"Atom_style command after simulation box is defined");
atom->create_avec(arg[0],narg-1,&arg[1],lmp->suffix);
}
/* ---------------------------------------------------------------------- */
void Input::bond_coeff()
{
if (domain->box_exist == 0)
error->all(FLERR,"Bond_coeff command before simulation box is defined");
if (force->bond == NULL)
error->all(FLERR,"Bond_coeff command before bond_style is defined");
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Bond_coeff command when no bonds allowed");
force->bond->coeff(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::bond_style()
{
if (narg < 1) error->all(FLERR,"Illegal bond_style command");
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Bond_style command when no bonds allowed");
force->create_bond(arg[0],lmp->suffix);
if (force->bond) force->bond->settings(narg-1,&arg[1]);
}
/* ---------------------------------------------------------------------- */
void Input::boundary()
{
if (domain->box_exist)
error->all(FLERR,"Boundary command after simulation box is defined");
domain->set_boundary(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::communicate()
{
comm->set(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::compute()
{
modify->add_compute(narg,arg,lmp->suffix);
}
/* ---------------------------------------------------------------------- */
void Input::compute_modify()
{
modify->modify_compute(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::dielectric()
{
if (narg != 1) error->all(FLERR,"Illegal dielectric command");
force->dielectric = atof(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::dihedral_coeff()
{
if (domain->box_exist == 0)
error->all(FLERR,"Dihedral_coeff command before simulation box is defined");
if (force->dihedral == NULL)
error->all(FLERR,"Dihedral_coeff command before dihedral_style is defined");
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Dihedral_coeff command when no dihedrals allowed");
force->dihedral->coeff(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::dihedral_style()
{
if (narg < 1) error->all(FLERR,"Illegal dihedral_style command");
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Dihedral_style command when no dihedrals allowed");
force->create_dihedral(arg[0],lmp->suffix);
if (force->dihedral) force->dihedral->settings(narg-1,&arg[1]);
}
/* ---------------------------------------------------------------------- */
void Input::dimension()
{
if (narg != 1) error->all(FLERR,"Illegal dimension command");
if (domain->box_exist)
error->all(FLERR,"Dimension command after simulation box is defined");
domain->dimension = atoi(arg[0]);
if (domain->dimension != 2 && domain->dimension != 3)
error->all(FLERR,"Illegal dimension command");
// must reset default extra_dof of all computes
// since some were created before dimension command is encountered
for (int i = 0; i < modify->ncompute; i++)
modify->compute[i]->reset_extra_dof();
}
/* ---------------------------------------------------------------------- */
void Input::dump()
{
output->add_dump(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::dump_modify()
{
output->modify_dump(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::fix()
{
modify->add_fix(narg,arg,lmp->suffix);
}
/* ---------------------------------------------------------------------- */
void Input::fix_modify()
{
modify->modify_fix(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::group_command()
{
group->assign(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::improper_coeff()
{
if (domain->box_exist == 0)
error->all(FLERR,"Improper_coeff command before simulation box is defined");
if (force->improper == NULL)
error->all(FLERR,"Improper_coeff command before improper_style is defined");
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Improper_coeff command when no impropers allowed");
force->improper->coeff(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::improper_style()
{
if (narg < 1) error->all(FLERR,"Illegal improper_style command");
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Improper_style command when no impropers allowed");
force->create_improper(arg[0],lmp->suffix);
if (force->improper) force->improper->settings(narg-1,&arg[1]);
}
/* ---------------------------------------------------------------------- */
void Input::kspace_modify()
{
if (force->kspace == NULL)
error->all(FLERR,"KSpace style has not yet been set");
force->kspace->modify_params(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::kspace_style()
{
force->create_kspace(narg,arg,lmp->suffix);
}
/* ---------------------------------------------------------------------- */
void Input::lattice()
{
domain->set_lattice(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::mass()
{
if (narg != 2) error->all(FLERR,"Illegal mass command");
if (domain->box_exist == 0)
error->all(FLERR,"Mass command before simulation box is defined");
atom->set_mass(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::min_modify()
{
update->minimize->modify_params(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::min_style()
{
if (domain->box_exist == 0)
error->all(FLERR,"Min_style command before simulation box is defined");
update->create_minimize(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::neigh_modify()
{
neighbor->modify_params(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::neighbor_command()
{
neighbor->set(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::newton()
{
int newton_pair,newton_bond;
if (narg == 1) {
if (strcmp(arg[0],"off") == 0) newton_pair = newton_bond = 0;
else if (strcmp(arg[0],"on") == 0) newton_pair = newton_bond = 1;
else error->all(FLERR,"Illegal newton command");
} else if (narg == 2) {
if (strcmp(arg[0],"off") == 0) newton_pair = 0;
else if (strcmp(arg[0],"on") == 0) newton_pair= 1;
else error->all(FLERR,"Illegal newton command");
if (strcmp(arg[1],"off") == 0) newton_bond = 0;
else if (strcmp(arg[1],"on") == 0) newton_bond = 1;
else error->all(FLERR,"Illegal newton command");
} else error->all(FLERR,"Illegal newton command");
force->newton_pair = newton_pair;
if (newton_bond == 0) {
if (domain->box_exist && force->newton_bond == 1)
error->all(FLERR,"Newton bond change after simulation box is defined");
force->newton_bond = 0;
} else {
if (domain->box_exist && force->newton_bond == 0)
error->all(FLERR,"Newton bond change after simulation box is defined");
force->newton_bond = 1;
}
if (newton_pair || newton_bond) force->newton = 1;
else force->newton = 0;
}
/* ---------------------------------------------------------------------- */
void Input::package()
{
if (domain->box_exist)
error->all(FLERR,"Package command after simulation box is defined");
if (narg < 1) error->all(FLERR,"Illegal package command");
if (strcmp(arg[0],"cuda") == 0) {
if (!lmp->cuda)
error->all(FLERR,"Package cuda command without USER-CUDA installed");
lmp->cuda->accelerator(narg-1,&arg[1]);
} else if (strcmp(arg[0],"gpu") == 0) {
char **fixarg = new char*[2+narg];
fixarg[0] = "package_gpu";
fixarg[1] = "all";
fixarg[2] = "GPU";
for (int i = 1; i < narg; i++) fixarg[i+2] = arg[i];
modify->allow_early_fix = 1;
modify->add_fix(2+narg,fixarg,NULL);
modify->allow_early_fix = 0;
delete [] fixarg;
} else if (strcmp(arg[0],"omp") == 0) {
-
-#ifdef _OPENMP
- if (narg != 2) error->all(FLERR,"Illegal package command");
- comm->nthreads = atoi(arg[1]);
- if (comm->nthreads < 1) error->all(FLERR,"Illegal package command");
-
- omp_set_num_threads(comm->nthreads);
- if (me == 0) {
- if (screen)
- fprintf(screen," reset %d OpenMP thread(s) per MPI task\n",
- comm->nthreads);
- if (logfile)
- fprintf(logfile," reset %d OpenMP thread(s) per MPI task\n",
- comm->nthreads);
- }
-#else
- error->all(FLERR,"Cannot use package omp command with no OpenMP support");
-#endif
+ char **fixarg = new char*[2+narg];
+ fixarg[0] = "package_omp";
+ fixarg[1] = "all";
+ fixarg[2] = "OMP";
+ for (int i = 1; i < narg; i++) fixarg[i+2] = arg[i];
+ modify->allow_early_fix = 1;
+ modify->add_fix(2+narg,fixarg,NULL);
+ modify->allow_early_fix = 0;
+ delete [] fixarg;
} else error->all(FLERR,"Illegal package command");
}
/* ---------------------------------------------------------------------- */
void Input::pair_coeff()
{
if (domain->box_exist == 0)
error->all(FLERR,"Pair_coeff command before simulation box is defined");
if (force->pair == NULL)
error->all(FLERR,"Pair_coeff command before pair_style is defined");
force->pair->coeff(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::pair_modify()
{
if (force->pair == NULL)
error->all(FLERR,"Pair_modify command before pair_style is defined");
force->pair->modify_params(narg,arg);
}
/* ----------------------------------------------------------------------
if old pair style exists and new style is same, just change settings
else create new pair class
------------------------------------------------------------------------- */
void Input::pair_style()
{
if (narg < 1) error->all(FLERR,"Illegal pair_style command");
if (force->pair && strcmp(arg[0],force->pair_style) == 0) {
force->pair->settings(narg-1,&arg[1]);
return;
}
force->create_pair(arg[0],lmp->suffix);
if (force->pair) force->pair->settings(narg-1,&arg[1]);
}
/* ---------------------------------------------------------------------- */
void Input::pair_write()
{
if (force->pair == NULL)
error->all(FLERR,"Pair_write command before pair_style is defined");
force->pair->write_file(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::processors()
{
- if (narg != 3) error->all(FLERR,"Illegal processors command");
if (domain->box_exist)
error->all(FLERR,"Processors command after simulation box is defined");
-
- if (strcmp(arg[0],"*") == 0) comm->user_procgrid[0] = 0;
- else comm->user_procgrid[0] = atoi(arg[0]);
- if (strcmp(arg[1],"*") == 0) comm->user_procgrid[1] = 0;
- else comm->user_procgrid[1] = atoi(arg[1]);
- if (strcmp(arg[2],"*") == 0) comm->user_procgrid[2] = 0;
- else comm->user_procgrid[2] = atoi(arg[2]);
-
- if (comm->user_procgrid[0] < 0 || comm->user_procgrid[1] < 0 ||
- comm->user_procgrid[2] < 0) error->all(FLERR,"Illegal processors command");
+ comm->set_processors(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::region()
{
domain->add_region(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::reset_timestep()
{
update->reset_timestep(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::restart()
{
output->create_restart(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::run_style()
{
if (domain->box_exist == 0)
error->all(FLERR,"Run_style command before simulation box is defined");
update->create_integrate(narg,arg,lmp->suffix);
}
/* ---------------------------------------------------------------------- */
void Input::special_bonds()
{
// store 1-3,1-4 and dihedral/extra flag values before change
// change in 1-2 coeffs will not change the special list
double lj2 = force->special_lj[2];
double lj3 = force->special_lj[3];
double coul2 = force->special_coul[2];
double coul3 = force->special_coul[3];
int angle = force->special_angle;
int dihedral = force->special_dihedral;
int extra = force->special_extra;
force->set_special(narg,arg);
// if simulation box defined and saved values changed, redo special list
if (domain->box_exist && atom->molecular) {
if (lj2 != force->special_lj[2] || lj3 != force->special_lj[3] ||
coul2 != force->special_coul[2] || coul3 != force->special_coul[3] ||
angle != force->special_angle ||
dihedral != force->special_dihedral ||
extra != force->special_extra) {
Special special(lmp);
special.build();
}
}
}
/* ---------------------------------------------------------------------- */
void Input::suffix()
{
if (narg != 1) error->all(FLERR,"Illegal suffix command");
if (strcmp(arg[0],"off") == 0) lmp->suffix_enable = 0;
else if (strcmp(arg[0],"on") == 0) lmp->suffix_enable = 1;
else {
delete [] lmp->suffix;
int n = strlen(arg[0]) + 1;
lmp->suffix = new char[n];
strcpy(lmp->suffix,arg[0]);
lmp->suffix_enable = 1;
}
}
/* ---------------------------------------------------------------------- */
void Input::thermo()
{
if (narg != 1) error->all(FLERR,"Illegal thermo command");
output->thermo_every = atoi(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::thermo_modify()
{
output->thermo->modify_params(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::thermo_style()
{
output->create_thermo(narg,arg);
}
/* ---------------------------------------------------------------------- */
void Input::timestep()
{
if (narg != 1) error->all(FLERR,"Illegal timestep command");
update->dt = atof(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::uncompute()
{
if (narg != 1) error->all(FLERR,"Illegal uncompute command");
modify->delete_compute(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::undump()
{
if (narg != 1) error->all(FLERR,"Illegal undump command");
output->delete_dump(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::unfix()
{
if (narg != 1) error->all(FLERR,"Illegal unfix command");
modify->delete_fix(arg[0]);
}
/* ---------------------------------------------------------------------- */
void Input::units()
{
if (narg != 1) error->all(FLERR,"Illegal units command");
if (domain->box_exist)
error->all(FLERR,"Units command after simulation box is defined");
update->set_units(arg[0]);
}
diff --git a/src/input.h b/src/input.h
index 2e3259b9f..fd08a6098 100644
--- a/src/input.h
+++ b/src/input.h
@@ -1,118 +1,119 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_INPUT_H
#define LMP_INPUT_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Input : protected Pointers {
public:
int narg; // # of command args
char **arg; // parsed args for command
class Variable *variable; // defined variables
Input(class LAMMPS *, int, char **);
~Input();
void file(); // process all input
void file(const char *); // process an input script
char *one(const char *); // process a single command
void substitute(char *, int); // substitute for variables in a string
private:
int me; // proc ID
char *command; // ptr to current command
int maxarg; // max # of args in arg
char *line,*copy,*work; // input line & copy of it
int echo_screen; // 0 = no, 1 = yes
int echo_log; // 0 = no, 1 = yes
int nfile,maxfile; // current # and max # of open input files
int label_active; // 0 = no label, 1 = looking for label
char *labelstr; // label string being looked for
int jump_skip; // 1 if skipping next jump, 0 otherwise
FILE **infiles; // list of open input files
void parse(); // parse an input text line
int execute_command(); // execute a single command
void clear(); // input script commands
void echo();
void ifthenelse();
void include();
void jump();
void label();
void log();
void next_command();
+ void partition();
void print();
void shell();
void variable_command();
void angle_coeff(); // LAMMPS commands
void angle_style();
void atom_modify();
void atom_style();
void bond_coeff();
void bond_style();
void boundary();
void communicate();
void compute();
void compute_modify();
void dielectric();
void dihedral_coeff();
void dihedral_style();
void dimension();
void dump();
void dump_modify();
void fix();
void fix_modify();
void group_command();
void improper_coeff();
void improper_style();
void kspace_modify();
void kspace_style();
void lattice();
void mass();
void min_modify();
void min_style();
void neigh_modify();
void neighbor_command();
void newton();
void package();
void pair_coeff();
void pair_modify();
void pair_style();
void pair_write();
void processors();
void region();
void reset_timestep();
void restart();
void run_style();
void special_bonds();
void suffix();
void thermo();
void thermo_modify();
void thermo_style();
void timestep();
void uncompute();
void undump();
void unfix();
void units();
};
}
#endif
diff --git a/src/lammps.cpp b/src/lammps.cpp
index f316a03ad..537ab1748 100644
--- a/src/lammps.cpp
+++ b/src/lammps.cpp
@@ -1,618 +1,641 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "string.h"
#include "lammps.h"
#include "style_angle.h"
#include "style_atom.h"
#include "style_bond.h"
#include "style_command.h"
#include "style_compute.h"
#include "style_dihedral.h"
#include "style_dump.h"
#include "style_fix.h"
#include "style_improper.h"
#include "style_integrate.h"
#include "style_kspace.h"
#include "style_minimize.h"
#include "style_pair.h"
#include "style_region.h"
#include "universe.h"
#include "input.h"
#include "atom.h"
#include "update.h"
#include "neighbor.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "modify.h"
#include "group.h"
#include "output.h"
#include "accelerator_cuda.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ----------------------------------------------------------------------
start up LAMMPS
allocate fundamental classes (memory, error, universe, input)
parse input switches
initialize communicators, screen & logfile output
input is allocated at end after MPI info is setup
------------------------------------------------------------------------- */
LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
{
memory = new Memory(this);
error = new Error(this);
universe = new Universe(this,communicator);
output = NULL;
screen = NULL;
logfile = NULL;
// parse input switches
int inflag = 0;
int screenflag = 0;
int logflag = 0;
int partscreenflag = 0;
int partlogflag = 0;
int cudaflag = -1;
int helpflag = 0;
suffix = NULL;
suffix_enable = 0;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"-partition") == 0 ||
strcmp(arg[iarg],"-p") == 0) {
universe->existflag = 1;
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
iarg++;
while (iarg < narg && arg[iarg][0] != '-') {
universe->add_world(arg[iarg]);
iarg++;
}
} else if (strcmp(arg[iarg],"-in") == 0 ||
strcmp(arg[iarg],"-i") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
inflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-screen") == 0 ||
strcmp(arg[iarg],"-sc") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
screenflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-log") == 0 ||
strcmp(arg[iarg],"-l") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
logflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-var") == 0 ||
strcmp(arg[iarg],"-v") == 0) {
if (iarg+3 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
iarg += 3;
while (iarg < narg && arg[iarg][0] != '-') iarg++;
} else if (strcmp(arg[iarg],"-echo") == 0 ||
strcmp(arg[iarg],"-e") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
iarg += 2;
} else if (strcmp(arg[iarg],"-pscreen") == 0 ||
strcmp(arg[iarg],"-ps") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
partscreenflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-plog") == 0 ||
strcmp(arg[iarg],"-pl") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
partlogflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-cuda") == 0 ||
strcmp(arg[iarg],"-c") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
if (strcmp(arg[iarg+1],"on") == 0) cudaflag = 1;
else if (strcmp(arg[iarg+1],"off") == 0) cudaflag = 0;
else error->universe_all(FLERR,"Invalid command-line argument");
iarg += 2;
} else if (strcmp(arg[iarg],"-suffix") == 0 ||
strcmp(arg[iarg],"-sf") == 0) {
if (iarg+2 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
delete [] suffix;
int n = strlen(arg[iarg+1]) + 1;
suffix = new char[n];
strcpy(suffix,arg[iarg+1]);
suffix_enable = 1;
iarg += 2;
+ } else if (strcmp(arg[iarg],"-reorder") == 0 ||
+ strcmp(arg[iarg],"-r") == 0) {
+ if (iarg+3 > narg)
+ error->universe_all(FLERR,"Invalid command-line argument");
+ if (universe->existflag)
+ error->universe_all(FLERR,"Cannot use -reorder after -partition");
+ universe->reorder(arg[iarg+1],arg[iarg+2]);
+ iarg += 3;
} else if (strcmp(arg[iarg],"-help") == 0 ||
strcmp(arg[iarg],"-h") == 0) {
if (iarg+1 > narg)
error->universe_all(FLERR,"Invalid command-line argument");
helpflag = 1;
iarg += 1;
} else error->universe_all(FLERR,"Invalid command-line argument");
}
- // if no partition command-line switch, universe is one world w/ all procs
+ // if no partition command-line switch, universe is one world with all procs
if (universe->existflag == 0) universe->add_world(NULL);
// sum of procs in all worlds must equal total # of procs
if (!universe->consistent())
error->universe_all(FLERR,"Processor partitions are inconsistent");
// universe cannot use stdin for input file
if (universe->existflag && inflag == 0)
error->universe_all(FLERR,"Must use -in switch with multiple partitions");
// if no partition command-line switch, cannot use -pscreen option
if (universe->existflag == 0 && partscreenflag)
error->universe_all(FLERR,"Can only use -pscreen with multiple partitions");
// if no partition command-line switch, cannot use -plog option
if (universe->existflag == 0 && partlogflag)
error->universe_all(FLERR,"Can only use -plog with multiple partitions");
// set universe screen and logfile
if (universe->me == 0) {
if (screenflag == 0)
universe->uscreen = stdout;
else if (strcmp(arg[screenflag],"none") == 0)
universe->uscreen = NULL;
else {
universe->uscreen = fopen(arg[screenflag],"w");
if (universe->uscreen == NULL)
error->universe_one(FLERR,"Cannot open universe screen file");
}
if (logflag == 0) {
universe->ulogfile = fopen("log.lammps","w");
if (universe->ulogfile == NULL)
error->universe_one(FLERR,"Cannot open log.lammps");
} else if (strcmp(arg[logflag],"none") == 0)
universe->ulogfile = NULL;
else {
universe->ulogfile = fopen(arg[logflag],"w");
if (universe->ulogfile == NULL)
error->universe_one(FLERR,"Cannot open universe log file");
}
}
if (universe->me > 0) {
if (screenflag == 0) universe->uscreen = stdout;
else universe->uscreen = NULL;
universe->ulogfile = NULL;
}
- // universe does not exist on its own, only a single world
- // inherit settings from universe
+ // make universe and single world the same, since no partition switch
+ // world inherits settings from universe
// set world screen, logfile, communicator, infile
// open input script if from file
if (universe->existflag == 0) {
screen = universe->uscreen;
logfile = universe->ulogfile;
world = universe->uworld;
infile = NULL;
if (universe->me == 0) {
if (inflag == 0) infile = stdin;
else infile = fopen(arg[inflag],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[inflag]);
error->one(FLERR,str);
}
}
if (universe->me == 0) {
if (screen) fprintf(screen,"LAMMPS (%s)\n",universe->version);
if (logfile) fprintf(logfile,"LAMMPS (%s)\n",universe->version);
}
- // universe is one or more worlds
- // split into separate communicators
+ // universe is one or more worlds, as setup by partition switch
+ // split universe communicator into separate world communicators
// set world screen, logfile, communicator, infile
// open input script
} else {
int me;
MPI_Comm_split(universe->uworld,universe->iworld,0,&world);
MPI_Comm_rank(world,&me);
if (me == 0)
if (partscreenflag == 0)
if (screenflag == 0) {
char str[32];
sprintf(str,"screen.%d",universe->iworld);
screen = fopen(str,"w");
if (screen == NULL) error->one(FLERR,"Cannot open screen file");
} else if (strcmp(arg[screenflag],"none") == 0)
screen = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[screenflag],universe->iworld);
screen = fopen(str,"w");
if (screen == NULL) error->one(FLERR,"Cannot open screen file");
}
else if (strcmp(arg[partscreenflag],"none") == 0)
screen = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[partscreenflag],universe->iworld);
screen = fopen(str,"w");
if (screen == NULL) error->one(FLERR,"Cannot open screen file");
} else screen = NULL;
if (me == 0)
if (partlogflag == 0)
if (logflag == 0) {
char str[32];
sprintf(str,"log.lammps.%d",universe->iworld);
logfile = fopen(str,"w");
if (logfile == NULL) error->one(FLERR,"Cannot open logfile");
} else if (strcmp(arg[logflag],"none") == 0)
logfile = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[logflag],universe->iworld);
logfile = fopen(str,"w");
if (logfile == NULL) error->one(FLERR,"Cannot open logfile");
}
else if (strcmp(arg[partlogflag],"none") == 0)
logfile = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[partlogflag],universe->iworld);
logfile = fopen(str,"w");
if (logfile == NULL) error->one(FLERR,"Cannot open logfile");
} else logfile = NULL;
if (me == 0) {
infile = fopen(arg[inflag],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[inflag]);
error->one(FLERR,str);
}
} else infile = NULL;
// screen and logfile messages for universe and world
if (universe->me == 0) {
if (universe->uscreen) {
fprintf(universe->uscreen,"LAMMPS (%s)\n",universe->version);
fprintf(universe->uscreen,"Running on %d partitions of processors\n",
universe->nworlds);
}
if (universe->ulogfile) {
fprintf(universe->ulogfile,"LAMMPS (%s)\n",universe->version);
fprintf(universe->ulogfile,"Running on %d partitions of processors\n",
universe->nworlds);
}
}
if (me == 0) {
if (screen) {
fprintf(screen,"LAMMPS (%s)\n",universe->version);
fprintf(screen,"Processor partition = %d\n",universe->iworld);
}
if (logfile) {
fprintf(logfile,"LAMMPS (%s)\n",universe->version);
fprintf(logfile,"Processor partition = %d\n",universe->iworld);
}
}
}
// check datatype settings in lmptype.h
if (sizeof(smallint) != sizeof(int))
error->all(FLERR,"Smallint setting in lmptype.h is invalid");
if (sizeof(tagint) < sizeof(smallint))
error->all(FLERR,"Tagint setting in lmptype.h is invalid");
if (sizeof(bigint) < sizeof(tagint))
error->all(FLERR,"Bigint setting in lmptype.h is invalid");
int mpisize;
MPI_Type_size(MPI_LMP_TAGINT,&mpisize);
if (mpisize != sizeof(tagint))
error->all(FLERR,
"MPI_LMP_TAGINT and tagint in lmptype.h are not compatible");
MPI_Type_size(MPI_LMP_BIGINT,&mpisize);
if (mpisize != sizeof(bigint))
error->all(FLERR,
"MPI_LMP_BIGINT and bigint in lmptype.h are not compatible");
#ifdef LAMMPS_SMALLBIG
if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 8)
error->all(FLERR,"Small, tag, big integers are not sized correctly");
#endif
#ifdef LAMMPS_BIGBIG
if (sizeof(smallint) != 4 || sizeof(tagint) != 8 || sizeof(bigint) != 8)
error->all(FLERR,"Small, tag, big integers are not sized correctly");
#endif
#ifdef LAMMPS_SMALLSMALL
if (sizeof(smallint) != 4 || sizeof(tagint) != 4 || sizeof(bigint) != 4)
error->all(FLERR,"Small, tag, big integers are not sized correctly");
#endif
if (sizeof(tagint) == 8)
error->all(FLERR,"64-bit atom IDs are not yet supported");
// create CUDA class if USER-CUDA installed, unless explicitly switched off
// instantiation creates dummy CUDA class if USER-CUDA is not installed
if (cudaflag == 0) {
cuda = NULL;
} else if (cudaflag == 1) {
cuda = new Cuda(this);
if (!cuda->cuda_exists)
error->all(FLERR,"Cannot use -cuda on without USER-CUDA installed");
} else {
cuda = new Cuda(this);
if (!cuda->cuda_exists) {
delete cuda;
cuda = NULL;
}
}
int me;
MPI_Comm_rank(world,&me);
if (cuda && me == 0) error->message(FLERR,"USER-CUDA mode is enabled");
// allocate input class now that MPI is fully setup
input = new Input(this,narg,arg);
// allocate top-level classes
create();
+ post_create();
// if helpflag set, print help and exit
if (helpflag) {
if (universe->me == 0) print_styles();
error->done();
}
}
/* ----------------------------------------------------------------------
shutdown LAMMPS
delete top-level classes
close screen and log files in world and universe
output files were already closed in destroy()
delete fundamental classes
------------------------------------------------------------------------- */
LAMMPS::~LAMMPS()
{
destroy();
if (universe->nworlds == 1) {
if (logfile) fclose(logfile);
} else {
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
if (universe->ulogfile) fclose(universe->ulogfile);
}
if (world != universe->uworld) MPI_Comm_free(&world);
delete cuda;
delete [] suffix;
delete input;
delete universe;
delete error;
delete memory;
}
/* ----------------------------------------------------------------------
allocate single instance of top-level classes
fundamental classes are allocated in constructor
some classes have package variants
------------------------------------------------------------------------- */
void LAMMPS::create()
{
atom = new Atom(this);
if (cuda) neighbor = new NeighborCuda(this);
else neighbor = new Neighbor(this);
if (cuda) comm = new CommCuda(this);
else comm = new Comm(this);
if (cuda) domain = new DomainCuda(this);
else domain = new Domain(this);
group = new Group(this);
force = new Force(this); // must be after group, to create temperature
if (cuda) modify = new ModifyCuda(this);
else modify = new Modify(this);
output = new Output(this); // must be after group, so "all" exists
// must be after modify so can create Computes
update = new Update(this); // must be after output, force, neighbor
timer = new Timer(this);
}
+/* ----------------------------------------------------------------------
+ invoke package-specific setup commands
+ called from LAMMPS constructor and after clear() command
+ only invoke if suffix is set and enabled
+------------------------------------------------------------------------- */
+
+void LAMMPS::post_create()
+{
+ if (suffix && suffix_enable) {
+ if (strcmp(suffix,"gpu") == 0) input->one("package gpu force/neigh 0 0 1");
+ if (strcmp(suffix,"omp") == 0) input->one("package omp *");
+ }
+}
+
/* ----------------------------------------------------------------------
initialize top-level classes
+ do not initialize Timer class, other classes like Run() do that explicitly
------------------------------------------------------------------------- */
void LAMMPS::init()
{
if (cuda) cuda->accelerator(0,NULL);
update->init();
force->init(); // pair must come after update due to minimizer
domain->init();
atom->init(); // atom must come after force and domain
// atom deletes extra array
// used by fix shear_history::unpack_restart()
// when force->pair->gran_history creates fix ??
// atom_vec init uses deform_vremap
modify->init(); // modify must come after update, force, atom, domain
neighbor->init(); // neighbor must come after force, modify
comm->init(); // comm must come after force, modify, neighbor, atom
output->init(); // output must come after domain, force, modify
- timer->init();
}
/* ----------------------------------------------------------------------
delete single instance of top-level classes
fundamental classes are deleted in destructor
------------------------------------------------------------------------- */
void LAMMPS::destroy()
{
delete update;
delete neighbor;
delete comm;
delete force;
delete group;
delete output;
delete modify; // modify must come after output, force, update
// since they delete fixes
delete domain; // domain must come after modify
// since fix destructors access domain
delete atom; // atom must come after modify, neighbor
// since fixes delete callbacks in atom
delete timer;
}
/* ----------------------------------------------------------------------
for each style, print name of all child classes build into executable
------------------------------------------------------------------------- */
void LAMMPS::print_styles()
{
printf("\nList of style options included in this executable:\n\n");
printf("Atom styles:");
#define ATOM_CLASS
#define AtomStyle(key,Class) printf(" %s",#key);
#include "style_atom.h"
#undef ATOM_CLASS
printf("\n\n");
printf("Integrate styles:");
#define INTEGRATE_CLASS
#define IntegrateStyle(key,Class) printf(" %s",#key);
#include "style_integrate.h"
#undef INTEGRATE_CLASS
printf("\n\n");
printf("Minimize styles:");
#define MINIMIZE_CLASS
#define MinimizeStyle(key,Class) printf(" %s",#key);
#include "style_minimize.h"
#undef MINIMIZE_CLASS
printf("\n\n");
printf("Pair styles:");
#define PAIR_CLASS
#define PairStyle(key,Class) printf(" %s",#key);
#include "style_pair.h"
#undef PAIR_CLASS
printf("\n\n");
printf("Bond styles:");
#define BOND_CLASS
#define BondStyle(key,Class) printf(" %s",#key);
#include "style_bond.h"
#undef BOND_CLASS
printf("\n\n");
printf("Angle styles:");
#define ANGLE_CLASS
#define AngleStyle(key,Class) printf(" %s",#key);
#include "style_angle.h"
#undef ANGLE_CLASS
printf("\n\n");
printf("Dihedral styles:");
#define DIHEDRAL_CLASS
#define DihedralStyle(key,Class) printf(" %s",#key);
#include "style_dihedral.h"
#undef DIHEDRAL_CLASS
printf("\n\n");
printf("Improper styles:");
#define IMPROPER_CLASS
#define ImproperStyle(key,Class) printf(" %s",#key);
#include "style_improper.h"
#undef IMPROPER_CLASS
printf("\n\n");
printf("KSpace styles:");
#define KSPACE_CLASS
#define KSpaceStyle(key,Class) printf(" %s",#key);
#include "style_kspace.h"
#undef KSPACE_CLASS
printf("\n\n");
printf("Fix styles (upper case are only for internal use):");
#define FIX_CLASS
#define FixStyle(key,Class) printf(" %s",#key);
#include "style_fix.h"
#undef FIX_CLASS
printf("\n\n");
printf("Compute styles:");
#define COMPUTE_CLASS
#define ComputeStyle(key,Class) printf(" %s",#key);
#include "style_compute.h"
#undef COMPUTE_CLASS
printf("\n\n");
printf("Region styles:");
#define REGION_CLASS
#define RegionStyle(key,Class) printf(" %s",#key);
#include "style_region.h"
#undef REGION_CLASS
printf("\n\n");
printf("Dump styles:");
#define DUMP_CLASS
#define DumpStyle(key,Class) printf(" %s",#key);
#include "style_dump.h"
#undef DUMP_CLASS
printf("\n\n");
printf("Command styles (add-on input script commands):");
#define COMMAND_CLASS
#define CommandStyle(key,Class) printf(" %s",#key);
#include "style_command.h"
#undef COMMAND_CLASS
printf("\n");
}
diff --git a/src/lammps.h b/src/lammps.h
index af25717ee..811e01b2a 100644
--- a/src/lammps.h
+++ b/src/lammps.h
@@ -1,60 +1,61 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_LAMMPS_H
#define LMP_LAMMPS_H
#include "stdio.h"
namespace LAMMPS_NS {
class LAMMPS {
public:
// ptrs to fundamental LAMMPS classes
class Memory *memory; // memory allocation functions
class Error *error; // error handling
class Universe *universe; // universe of processors
class Input *input; // input script processing
// ptrs to top-level LAMMPS-specific classes
class Atom *atom; // atom-based quantities
class Update *update; // integrators/minimizers
class Neighbor *neighbor; // neighbor lists
class Comm *comm; // inter-processor communication
class Domain *domain; // simulation box
class Force *force; // inter-particle forces
class Modify *modify; // fixes and computes
class Group *group; // groups of atoms
class Output *output; // thermo/dump/restart
class Timer *timer; // CPU timing info
MPI_Comm world; // MPI communicator
FILE *infile; // infile
FILE *screen; // screen output
FILE *logfile; // logfile
char *suffix; // suffix to add to input script style names
int suffix_enable; // 1 if suffix enabled, 0 if disabled
class Cuda *cuda; // CUDA accelerator class
LAMMPS(int, char **, MPI_Comm);
~LAMMPS();
void create();
+ void post_create();
void init();
void destroy();
void print_styles();
};
}
#endif
diff --git a/src/library.h b/src/library.h
index db2d05169..3d692b4f5 100644
--- a/src/library.h
+++ b/src/library.h
@@ -1,46 +1,46 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/*
C or Fortran style library interface to LAMMPS
new LAMMPS-specific functions can be added
*/
#include "mpi.h"
/* ifdefs allow this file to be included in a C program */
#ifdef __cplusplus
extern "C" {
#endif
void lammps_open(int, char **, MPI_Comm, void **);
void lammps_open_no_mpi(int, char **, void **);
void lammps_close(void *);
void lammps_file(void *, char *);
char *lammps_command(void *, char *);
void lammps_free(void *);
void *lammps_extract_global(void *, char *);
void *lammps_extract_atom(void *, char *);
void *lammps_extract_compute(void *, char *, int, int);
-void *lammps_extract_fix(void *, int, int, int, int);
+void *lammps_extract_fix(void *, char *, int, int, int, int);
void *lammps_extract_variable(void *, char *, char *);
int lammps_get_natoms(void *);
void lammps_get_coords(void *, double *);
void lammps_put_coords(void *, double *);
#ifdef __cplusplus
}
#endif
diff --git a/src/main.cpp b/src/main.cpp
index a3764872e..13b391e12 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,33 +1,34 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "lammps.h"
#include "input.h"
+#include "string.h"
using namespace LAMMPS_NS;
/* ----------------------------------------------------------------------
main program to drive LAMMPS
------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
MPI_Init(&argc,&argv);
LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD);
lammps->input->file();
delete lammps;
MPI_Finalize();
}
diff --git a/src/math_extra.h b/src/math_extra.h
index a5fdc81ce..c161b40f1 100755
--- a/src/math_extra.h
+++ b/src/math_extra.h
@@ -1,612 +1,612 @@
/* ----------------------------------------------------------------------
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: Mike Brown (SNL)
------------------------------------------------------------------------- */
#ifndef LMP_MATH_EXTRA_H
#define LMP_MATH_EXTRA_H
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "error.h"
namespace MathExtra {
// 3 vector operations
inline void norm3(double *v);
inline void normalize3(const double *v, double *ans);
inline void snormalize3(const double, const double *v, double *ans);
inline void negate3(double *v);
inline void scale3(double s, double *v);
inline void add3(const double *v1, const double *v2, double *ans);
inline void sub3(const double *v1, const double *v2, double *ans);
inline double len3(const double *v);
inline double lensq3(const double *v);
inline double dot3(const double *v1, const double *v2);
inline void cross3(const double *v1, const double *v2, double *ans);
// 3x3 matrix operations
inline double det3(const double mat[3][3]);
inline void diag_times3(const double *diagonal, const double mat[3][3],
double ans[3][3]);
inline void plus3(const double m[3][3], const double m2[3][3],
double ans[3][3]);
inline void times3(const double m[3][3], const double m2[3][3],
double ans[3][3]);
inline void transpose_times3(const double mat1[3][3],
const double mat2[3][3],
double ans[3][3]);
inline void times3_transpose(const double mat1[3][3],
const double mat2[3][3],
double ans[3][3]);
inline void invert3(const double mat[3][3], double ans[3][3]);
inline void matvec(const double mat[3][3], const double*vec, double *ans);
inline void matvec(const double *ex, const double *ey, const double *ez,
const double *vec, double *ans);
inline void transpose_matvec(const double mat[3][3], const double*vec,
double *ans);
inline void transpose_matvec(const double *ex, const double *ey,
const double *ez, const double *v,
double *ans);
inline void transpose_diag3(const double mat[3][3], const double*vec,
double ans[3][3]);
inline void vecmat(const double *v, const double m[3][3], double *ans);
inline void scalar_times3(const double f, double m[3][3]);
void write3(const double mat[3][3]);
int mldivide3(const double mat[3][3], const double *vec, double *ans);
int jacobi(double matrix[3][3], double *evalues, double evectors[3][3]);
void rotate(double matrix[3][3], int i, int j, int k, int l,
double s, double tau);
void richardson(double *q, double *m, double *w, double *moments, double dtq);
// shape matrix operations
// upper-triangular 3x3 matrix stored in Voigt notation as 6-vector
inline void multiply_shape_shape(const double *one, const double *two,
double *ans);
// quaternion operations
inline void qnormalize(double *q);
inline void qconjugate(double *q, double *qc);
inline void vecquat(double *a, double *b, double *c);
inline void quatvec(double *a, double *b, double *c);
inline void quatquat(double *a, double *b, double *c);
inline void invquatvec(double *a, double *b, double *c);
inline void axisangle_to_quat(const double *v, const double angle,
double *quat);
void angmom_to_omega(double *m, double *ex, double *ey, double *ez,
double *idiag, double *w);
void omega_to_angmom(double *w, double *ex, double *ey, double *ez,
double *idiag, double *m);
void mq_to_omega(double *m, double *q, double *moments, double *w);
void exyz_to_q(double *ex, double *ey, double *ez, double *q);
void q_to_exyz(double *q, double *ex, double *ey, double *ez);
void quat_to_mat(const double *quat, double mat[3][3]);
void quat_to_mat_trans(const double *quat, double mat[3][3]);
// rotation operations
inline void rotation_generator_x(const double m[3][3], double ans[3][3]);
inline void rotation_generator_y(const double m[3][3], double ans[3][3]);
inline void rotation_generator_z(const double m[3][3], double ans[3][3]);
// moment of inertia operations
void inertia_ellipsoid(double *shape, double *quat, double mass,
double *inertia);
void inertia_line(double length, double theta, double mass,
double *inertia);
void inertia_triangle(double *v0, double *v1, double *v2,
double mass, double *inertia);
void inertia_triangle(double *idiag, double *quat, double mass,
double *inertia);
}
/* ----------------------------------------------------------------------
normalize a vector in place
------------------------------------------------------------------------- */
void MathExtra::norm3(double *v)
{
double scale = 1.0/sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
v[0] *= scale;
v[1] *= scale;
v[2] *= scale;
}
/* ----------------------------------------------------------------------
normalize a vector, return in ans
------------------------------------------------------------------------- */
void MathExtra::normalize3(const double *v, double *ans)
{
double scale = 1.0/sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
ans[0] = v[0]*scale;
ans[1] = v[1]*scale;
ans[2] = v[2]*scale;
}
/* ----------------------------------------------------------------------
scale a vector to length
------------------------------------------------------------------------- */
void MathExtra::snormalize3(const double length, const double *v, double *ans)
{
double scale = length/sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
ans[0] = v[0]*scale;
ans[1] = v[1]*scale;
ans[2] = v[2]*scale;
}
/* ----------------------------------------------------------------------
negate vector v
------------------------------------------------------------------------- */
void MathExtra::negate3(double *v)
{
v[0] = -v[0];
v[1] = -v[1];
v[2] = -v[2];
}
/* ----------------------------------------------------------------------
scale vector v by s
------------------------------------------------------------------------- */
void MathExtra::scale3(double s, double *v)
{
v[0] *= s;
v[1] *= s;
v[2] *= s;
}
/* ----------------------------------------------------------------------
ans = v1 + v2
------------------------------------------------------------------------- */
void MathExtra::add3(const double *v1, const double *v2, double *ans)
{
ans[0] = v1[0] + v2[0];
ans[1] = v1[1] + v2[1];
ans[2] = v1[2] + v2[2];
}
/* ----------------------------------------------------------------------
ans = v1 - v2
------------------------------------------------------------------------- */
void MathExtra::sub3(const double *v1, const double *v2, double *ans)
{
ans[0] = v1[0] - v2[0];
ans[1] = v1[1] - v2[1];
ans[2] = v1[2] - v2[2];
}
/* ----------------------------------------------------------------------
length of vector v
------------------------------------------------------------------------- */
double MathExtra::len3(const double *v)
{
return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
}
/* ----------------------------------------------------------------------
squared length of vector v, or dot product of v with itself
------------------------------------------------------------------------- */
double MathExtra::lensq3(const double *v)
{
return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
}
/* ----------------------------------------------------------------------
dot product of 2 vectors
------------------------------------------------------------------------- */
double MathExtra::dot3(const double *v1, const double *v2)
{
return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
}
/* ----------------------------------------------------------------------
cross product of 2 vectors
------------------------------------------------------------------------- */
void MathExtra::cross3(const double *v1, const double *v2, double *ans)
{
- ans[0] = v1[1]*v2[2]-v1[2]*v2[1];
- ans[1] = v1[2]*v2[0]-v1[0]*v2[2];
- ans[2] = v1[0]*v2[1]-v1[1]*v2[0];
+ ans[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ ans[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ ans[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
/* ----------------------------------------------------------------------
determinant of a matrix
------------------------------------------------------------------------- */
double MathExtra::det3(const double m[3][3])
{
double ans = m[0][0]*m[1][1]*m[2][2] - m[0][0]*m[1][2]*m[2][1] -
m[1][0]*m[0][1]*m[2][2] + m[1][0]*m[0][2]*m[2][1] +
m[2][0]*m[0][1]*m[1][2] - m[2][0]*m[0][2]*m[1][1];
return ans;
}
/* ----------------------------------------------------------------------
diagonal matrix times a full matrix
------------------------------------------------------------------------- */
void MathExtra::diag_times3(const double *d, const double m[3][3],
double ans[3][3])
{
ans[0][0] = d[0]*m[0][0];
ans[0][1] = d[0]*m[0][1];
ans[0][2] = d[0]*m[0][2];
ans[1][0] = d[1]*m[1][0];
ans[1][1] = d[1]*m[1][1];
ans[1][2] = d[1]*m[1][2];
ans[2][0] = d[2]*m[2][0];
ans[2][1] = d[2]*m[2][1];
ans[2][2] = d[2]*m[2][2];
}
/* ----------------------------------------------------------------------
add two matrices
------------------------------------------------------------------------- */
void MathExtra::plus3(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]+m2[0][0];
ans[0][1] = m[0][1]+m2[0][1];
ans[0][2] = m[0][2]+m2[0][2];
ans[1][0] = m[1][0]+m2[1][0];
ans[1][1] = m[1][1]+m2[1][1];
ans[1][2] = m[1][2]+m2[1][2];
ans[2][0] = m[2][0]+m2[2][0];
ans[2][1] = m[2][1]+m2[2][1];
ans[2][2] = m[2][2]+m2[2][2];
}
/* ----------------------------------------------------------------------
multiply mat1 times mat2
------------------------------------------------------------------------- */
void MathExtra::times3(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]*m2[0][0] + m[0][1]*m2[1][0] + m[0][2]*m2[2][0];
ans[0][1] = m[0][0]*m2[0][1] + m[0][1]*m2[1][1] + m[0][2]*m2[2][1];
ans[0][2] = m[0][0]*m2[0][2] + m[0][1]*m2[1][2] + m[0][2]*m2[2][2];
ans[1][0] = m[1][0]*m2[0][0] + m[1][1]*m2[1][0] + m[1][2]*m2[2][0];
ans[1][1] = m[1][0]*m2[0][1] + m[1][1]*m2[1][1] + m[1][2]*m2[2][1];
ans[1][2] = m[1][0]*m2[0][2] + m[1][1]*m2[1][2] + m[1][2]*m2[2][2];
ans[2][0] = m[2][0]*m2[0][0] + m[2][1]*m2[1][0] + m[2][2]*m2[2][0];
ans[2][1] = m[2][0]*m2[0][1] + m[2][1]*m2[1][1] + m[2][2]*m2[2][1];
ans[2][2] = m[2][0]*m2[0][2] + m[2][1]*m2[1][2] + m[2][2]*m2[2][2];
}
/* ----------------------------------------------------------------------
multiply the transpose of mat1 times mat2
------------------------------------------------------------------------- */
void MathExtra::transpose_times3(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]*m2[0][0] + m[1][0]*m2[1][0] + m[2][0]*m2[2][0];
ans[0][1] = m[0][0]*m2[0][1] + m[1][0]*m2[1][1] + m[2][0]*m2[2][1];
ans[0][2] = m[0][0]*m2[0][2] + m[1][0]*m2[1][2] + m[2][0]*m2[2][2];
ans[1][0] = m[0][1]*m2[0][0] + m[1][1]*m2[1][0] + m[2][1]*m2[2][0];
ans[1][1] = m[0][1]*m2[0][1] + m[1][1]*m2[1][1] + m[2][1]*m2[2][1];
ans[1][2] = m[0][1]*m2[0][2] + m[1][1]*m2[1][2] + m[2][1]*m2[2][2];
ans[2][0] = m[0][2]*m2[0][0] + m[1][2]*m2[1][0] + m[2][2]*m2[2][0];
ans[2][1] = m[0][2]*m2[0][1] + m[1][2]*m2[1][1] + m[2][2]*m2[2][1];
ans[2][2] = m[0][2]*m2[0][2] + m[1][2]*m2[1][2] + m[2][2]*m2[2][2];
}
/* ----------------------------------------------------------------------
multiply mat1 times transpose of mat2
------------------------------------------------------------------------- */
void MathExtra::times3_transpose(const double m[3][3], const double m2[3][3],
double ans[3][3])
{
ans[0][0] = m[0][0]*m2[0][0] + m[0][1]*m2[0][1] + m[0][2]*m2[0][2];
ans[0][1] = m[0][0]*m2[1][0] + m[0][1]*m2[1][1] + m[0][2]*m2[1][2];
ans[0][2] = m[0][0]*m2[2][0] + m[0][1]*m2[2][1] + m[0][2]*m2[2][2];
ans[1][0] = m[1][0]*m2[0][0] + m[1][1]*m2[0][1] + m[1][2]*m2[0][2];
ans[1][1] = m[1][0]*m2[1][0] + m[1][1]*m2[1][1] + m[1][2]*m2[1][2];
ans[1][2] = m[1][0]*m2[2][0] + m[1][1]*m2[2][1] + m[1][2]*m2[2][2];
ans[2][0] = m[2][0]*m2[0][0] + m[2][1]*m2[0][1] + m[2][2]*m2[0][2];
ans[2][1] = m[2][0]*m2[1][0] + m[2][1]*m2[1][1] + m[2][2]*m2[1][2];
ans[2][2] = m[2][0]*m2[2][0] + m[2][1]*m2[2][1] + m[2][2]*m2[2][2];
}
/* ----------------------------------------------------------------------
invert a matrix
does NOT checks for singular or badly scaled matrix
------------------------------------------------------------------------- */
void MathExtra::invert3(const double m[3][3], double ans[3][3])
{
double den = m[0][0]*m[1][1]*m[2][2]-m[0][0]*m[1][2]*m[2][1];
den += -m[1][0]*m[0][1]*m[2][2]+m[1][0]*m[0][2]*m[2][1];
den += m[2][0]*m[0][1]*m[1][2]-m[2][0]*m[0][2]*m[1][1];
ans[0][0] = (m[1][1]*m[2][2]-m[1][2]*m[2][1]) / den;
ans[0][1] = -(m[0][1]*m[2][2]-m[0][2]*m[2][1]) / den;
ans[0][2] = (m[0][1]*m[1][2]-m[0][2]*m[1][1]) / den;
ans[1][0] = -(m[1][0]*m[2][2]-m[1][2]*m[2][0]) / den;
ans[1][1] = (m[0][0]*m[2][2]-m[0][2]*m[2][0]) / den;
ans[1][2] = -(m[0][0]*m[1][2]-m[0][2]*m[1][0]) / den;
ans[2][0] = (m[1][0]*m[2][1]-m[1][1]*m[2][0]) / den;
ans[2][1] = -(m[0][0]*m[2][1]-m[0][1]*m[2][0]) / den;
ans[2][2] = (m[0][0]*m[1][1]-m[0][1]*m[1][0]) / den;
}
/* ----------------------------------------------------------------------
matrix times vector
------------------------------------------------------------------------- */
void MathExtra::matvec(const double m[3][3], const double *v, double *ans)
{
ans[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
ans[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
ans[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
}
/* ----------------------------------------------------------------------
matrix times vector
------------------------------------------------------------------------- */
void MathExtra::matvec(const double *ex, const double *ey, const double *ez,
const double *v, double *ans)
{
ans[0] = ex[0]*v[0] + ey[0]*v[1] + ez[0]*v[2];
ans[1] = ex[1]*v[0] + ey[1]*v[1] + ez[1]*v[2];
ans[2] = ex[2]*v[0] + ey[2]*v[1] + ez[2]*v[2];
}
/* ----------------------------------------------------------------------
transposed matrix times vector
------------------------------------------------------------------------- */
void MathExtra::transpose_matvec(const double m[3][3], const double *v,
double *ans)
{
ans[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2];
ans[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2];
ans[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2];
}
/* ----------------------------------------------------------------------
transposed matrix times vector
------------------------------------------------------------------------- */
void MathExtra::transpose_matvec(const double *ex, const double *ey,
const double *ez, const double *v,
double *ans)
{
ans[0] = ex[0]*v[0] + ex[1]*v[1] + ex[2]*v[2];
ans[1] = ey[0]*v[0] + ey[1]*v[1] + ey[2]*v[2];
ans[2] = ez[0]*v[0] + ez[1]*v[1] + ez[2]*v[2];
}
/* ----------------------------------------------------------------------
transposed matrix times diagonal matrix
------------------------------------------------------------------------- */
void MathExtra::transpose_diag3(const double m[3][3], const double *d,
double ans[3][3])
{
ans[0][0] = m[0][0]*d[0];
ans[0][1] = m[1][0]*d[1];
ans[0][2] = m[2][0]*d[2];
ans[1][0] = m[0][1]*d[0];
ans[1][1] = m[1][1]*d[1];
ans[1][2] = m[2][1]*d[2];
ans[2][0] = m[0][2]*d[0];
ans[2][1] = m[1][2]*d[1];
ans[2][2] = m[2][2]*d[2];
}
/* ----------------------------------------------------------------------
row vector times matrix
------------------------------------------------------------------------- */
void MathExtra::vecmat(const double *v, const double m[3][3], double *ans)
{
ans[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0];
ans[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1];
ans[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2];
}
/* ----------------------------------------------------------------------
matrix times scalar, in place
------------------------------------------------------------------------- */
inline void MathExtra::scalar_times3(const double f, double m[3][3])
{
m[0][0] *= f; m[0][1] *= f; m[0][2] *= f;
m[1][0] *= f; m[1][1] *= f; m[1][2] *= f;
m[2][0] *= f; m[2][1] *= f; m[2][2] *= f;
}
/* ----------------------------------------------------------------------
multiply 2 shape matrices
upper-triangular 3x3, stored as 6-vector in Voigt notation
------------------------------------------------------------------------- */
void MathExtra::multiply_shape_shape(const double *one, const double *two,
double *ans)
{
ans[0] = one[0]*two[0];
ans[1] = one[1]*two[1];
ans[2] = one[2]*two[2];
ans[3] = one[1]*two[3] + one[3]*two[2];
ans[4] = one[0]*two[4] + one[5]*two[3] + one[4]*two[2];
ans[5] = one[0]*two[5] + one[5]*two[1];
}
/* ----------------------------------------------------------------------
normalize a quaternion
------------------------------------------------------------------------- */
void MathExtra::qnormalize(double *q)
{
double norm = 1.0 / sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
q[0] *= norm;
q[1] *= norm;
q[2] *= norm;
q[3] *= norm;
}
/* ----------------------------------------------------------------------
conjugate of a quaternion: qc = conjugate of q
assume q is of unit length
------------------------------------------------------------------------- */
void MathExtra::qconjugate(double *q, double *qc)
{
qc[0] = q[0];
qc[1] = -q[1];
qc[2] = -q[2];
qc[3] = -q[3];
}
/* ----------------------------------------------------------------------
vector-quaternion multiply: c = a*b, where a = (0,a)
------------------------------------------------------------------------- */
void MathExtra::vecquat(double *a, double *b, double *c)
{
c[0] = -a[0]*b[1] - a[1]*b[2] - a[2]*b[3];
c[1] = b[0]*a[0] + a[1]*b[3] - a[2]*b[2];
c[2] = b[0]*a[1] + a[2]*b[1] - a[0]*b[3];
c[3] = b[0]*a[2] + a[0]*b[2] - a[1]*b[1];
}
/* ----------------------------------------------------------------------
quaternion-vector multiply: c = a*b, where b = (0,b)
------------------------------------------------------------------------- */
void MathExtra::quatvec(double *a, double *b, double *c)
{
c[0] = -a[1]*b[0] - a[2]*b[1] - a[3]*b[2];
c[1] = a[0]*b[0] + a[2]*b[2] - a[3]*b[1];
c[2] = a[0]*b[1] + a[3]*b[0] - a[1]*b[2];
c[3] = a[0]*b[2] + a[1]*b[1] - a[2]*b[0];
}
/* ----------------------------------------------------------------------
quaternion-quaternion multiply: c = a*b
------------------------------------------------------------------------- */
void MathExtra::quatquat(double *a, double *b, double *c)
{
c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3];
c[1] = a[0]*b[1] + b[0]*a[1] + a[2]*b[3] - a[3]*b[2];
c[2] = a[0]*b[2] + b[0]*a[2] + a[3]*b[1] - a[1]*b[3];
c[3] = a[0]*b[3] + b[0]*a[3] + a[1]*b[2] - a[2]*b[1];
}
/* ----------------------------------------------------------------------
quaternion multiply: c = inv(a)*b
a is a quaternion
b is a four component vector
c is a three component vector
------------------------------------------------------------------------- */
void MathExtra::invquatvec(double *a, double *b, double *c)
{
c[0] = -a[1]*b[0] + a[0]*b[1] + a[3]*b[2] - a[2]*b[3];
c[1] = -a[2]*b[0] - a[3]*b[1] + a[0]*b[2] + a[1]*b[3];
c[2] = -a[3]*b[0] + a[2]*b[1] - a[1]*b[2] + a[0]*b[3];
}
/* ----------------------------------------------------------------------
compute quaternion from axis-angle rotation
v MUST be a unit vector
------------------------------------------------------------------------- */
void MathExtra::axisangle_to_quat(const double *v, const double angle,
double *quat)
{
double halfa = 0.5*angle;
double sina = sin(halfa);
quat[0] = cos(halfa);
quat[1] = v[0]*sina;
quat[2] = v[1]*sina;
quat[3] = v[2]*sina;
}
/* ----------------------------------------------------------------------
Apply principal rotation generator about x to rotation matrix m
------------------------------------------------------------------------- */
void MathExtra::rotation_generator_x(const double m[3][3], double ans[3][3])
{
ans[0][0] = 0;
ans[0][1] = -m[0][2];
ans[0][2] = m[0][1];
ans[1][0] = 0;
ans[1][1] = -m[1][2];
ans[1][2] = m[1][1];
ans[2][0] = 0;
ans[2][1] = -m[2][2];
ans[2][2] = m[2][1];
}
/* ----------------------------------------------------------------------
Apply principal rotation generator about y to rotation matrix m
------------------------------------------------------------------------- */
void MathExtra::rotation_generator_y(const double m[3][3], double ans[3][3])
{
ans[0][0] = m[0][2];
ans[0][1] = 0;
ans[0][2] = -m[0][0];
ans[1][0] = m[1][2];
ans[1][1] = 0;
ans[1][2] = -m[1][0];
ans[2][0] = m[2][2];
ans[2][1] = 0;
ans[2][2] = -m[2][0];
}
/* ----------------------------------------------------------------------
Apply principal rotation generator about z to rotation matrix m
------------------------------------------------------------------------- */
void MathExtra::rotation_generator_z(const double m[3][3], double ans[3][3])
{
ans[0][0] = -m[0][1];
ans[0][1] = m[0][0];
ans[0][2] = 0;
ans[1][0] = -m[1][1];
ans[1][1] = m[1][0];
ans[1][2] = 0;
ans[2][0] = -m[2][1];
ans[2][1] = m[2][0];
ans[2][2] = 0;
}
#endif
diff --git a/src/memory.cpp b/src/memory.cpp
index 11e15f10e..c98f40fd3 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -1,85 +1,90 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Memory::Memory(LAMMPS *lmp) : Pointers(lmp) {}
/* ----------------------------------------------------------------------
safe malloc
------------------------------------------------------------------------- */
void *Memory::smalloc(bigint nbytes, const char *name)
{
if (nbytes == 0) return NULL;
+#if defined(LAMMPS_MEMALIGN)
+ void *ptr;
+ posix_memalign(&ptr, LAMMPS_MEMALIGN, nbytes);
+#else
void *ptr = malloc(nbytes);
+#endif
if (ptr == NULL) {
char str[128];
sprintf(str,"Failed to allocate " BIGINT_FORMAT " bytes for array %s",
nbytes,name);
error->one(FLERR,str);
}
return ptr;
}
/* ----------------------------------------------------------------------
safe realloc
------------------------------------------------------------------------- */
void *Memory::srealloc(void *ptr, bigint nbytes, const char *name)
{
if (nbytes == 0) {
destroy(ptr);
return NULL;
}
ptr = realloc(ptr,nbytes);
if (ptr == NULL) {
char str[128];
sprintf(str,"Failed to reallocate " BIGINT_FORMAT " bytes for array %s",
nbytes,name);
error->one(FLERR,str);
}
return ptr;
}
/* ----------------------------------------------------------------------
safe free
------------------------------------------------------------------------- */
void Memory::sfree(void *ptr)
{
if (ptr == NULL) return;
free(ptr);
}
/* ----------------------------------------------------------------------
erroneous usage of templated create/grow functions
------------------------------------------------------------------------- */
void Memory::fail(const char *name)
{
char str[128];
sprintf(str,"Cannot create/grow a vector/array of pointers for %s",name);
error->one(FLERR,str);
}
diff --git a/src/min.cpp b/src/min.cpp
index f380a103d..eebfd03dc 100644
--- a/src/min.cpp
+++ b/src/min.cpp
@@ -1,779 +1,764 @@
/* ----------------------------------------------------------------------
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: Aidan Thompson (SNL)
improved CG and backtrack ls, added quadratic ls
Sources: Numerical Recipes frprmn routine
"Conjugate Gradient Method Without the Agonizing Pain" by
JR Shewchuk, http://www-2.cs.cmu.edu/~jrs/jrspapers.html#cg
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "min.h"
#include "atom.h"
#include "domain.h"
#include "comm.h"
#include "update.h"
#include "modify.h"
#include "fix_minimize.h"
#include "compute.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "kspace.h"
#include "output.h"
#include "thermo.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Min::Min(LAMMPS *lmp) : Pointers(lmp)
{
dmax = 0.1;
searchflag = 0;
linestyle = 0;
elist_global = elist_atom = NULL;
vlist_global = vlist_atom = NULL;
nextra_global = 0;
fextra = NULL;
nextra_atom = 0;
xextra_atom = fextra_atom = NULL;
extra_peratom = extra_nlen = NULL;
extra_max = NULL;
requestor = NULL;
external_force_clear = 0;
}
/* ---------------------------------------------------------------------- */
Min::~Min()
{
delete [] elist_global;
delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
delete [] fextra;
memory->sfree(xextra_atom);
memory->sfree(fextra_atom);
memory->destroy(extra_peratom);
memory->destroy(extra_nlen);
memory->destroy(extra_max);
memory->sfree(requestor);
}
/* ---------------------------------------------------------------------- */
void Min::init()
{
// create fix needed for storing atom-based quantities
// will delete it at end of run
char **fixarg = new char*[3];
fixarg[0] = (char *) "MINIMIZE";
fixarg[1] = (char *) "all";
fixarg[2] = (char *) "MINIMIZE";
modify->add_fix(3,fixarg);
delete [] fixarg;
fix_minimize = (FixMinimize *) modify->fix[modify->nfix-1];
// clear out extra global and per-atom dof
// will receive requests for new per-atom dof during pair init()
// can then add vectors to fix_minimize in setup()
nextra_global = 0;
delete [] fextra;
fextra = NULL;
nextra_atom = 0;
memory->sfree(xextra_atom);
memory->sfree(fextra_atom);
memory->destroy(extra_peratom);
memory->destroy(extra_nlen);
memory->destroy(extra_max);
memory->sfree(requestor);
xextra_atom = fextra_atom = NULL;
extra_peratom = extra_nlen = NULL;
extra_max = NULL;
requestor = NULL;
// virial_style:
// 1 if computed explicitly by pair->compute via sum over pair interactions
// 2 if computed implicitly by pair->virial_compute via sum over ghost atoms
if (force->newton_pair) virial_style = 2;
else virial_style = 1;
// setup lists of computes for global and per-atom PE and pressure
ev_setup();
+ // detect if fix omp is present for clearing force arrays
+
+ int ifix = modify->find_fix("package_omp");
+ if (ifix >= 0) external_force_clear = 1;
+
// set flags for what arrays to clear in force_clear()
// need to clear additionals arrays if they exist
torqueflag = 0;
if (atom->torque_flag) torqueflag = 1;
erforceflag = 0;
if (atom->erforce_flag) erforceflag = 1;
e_flag = 0;
if (atom->e_flag) e_flag = 1;
rho_flag = 0;
if (atom->rho_flag) rho_flag = 1;
// orthogonal vs triclinic simulation box
triclinic = domain->triclinic;
// reset reneighboring criteria if necessary
neigh_every = neighbor->every;
neigh_delay = neighbor->delay;
neigh_dist_check = neighbor->dist_check;
if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
if (comm->me == 0)
error->warning(FLERR,
"Resetting reneighboring criteria during minimization");
}
neighbor->every = 1;
neighbor->delay = 0;
neighbor->dist_check = 1;
niter = neval = 0;
// style-specific initialization
init_style();
}
/* ----------------------------------------------------------------------
setup before run
------------------------------------------------------------------------- */
void Min::setup()
{
if (comm->me == 0 && screen) fprintf(screen,"Setting up minimization ...\n");
// setup extra global dof due to fixes
// cannot be done in init() b/c update init() is before modify init()
nextra_global = modify->min_dof();
if (nextra_global) fextra = new double[nextra_global];
// compute for potential energy
int id = modify->find_compute("thermo_pe");
if (id < 0) error->all(FLERR,"Minimization could not find thermo_pe compute");
pe_compute = modify->compute[id];
// style-specific setup does two tasks
// setup extra global dof vectors
// setup extra per-atom dof vectors due to requests from Pair classes
// cannot be done in init() b/c update init() is before modify/pair init()
setup_style();
// ndoftotal = total dof for entire minimization problem
// dof for atoms, extra per-atom, extra global
bigint ndofme = 3*atom->nlocal;
for (int m = 0; m < nextra_atom; m++)
ndofme += extra_peratom[m]*atom->nlocal;
MPI_Allreduce(&ndofme,&ndoftotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
ndoftotal += nextra_global;
// setup domain, communication and neighboring
// acquire ghosts
// build neighbor lists
atom->setup();
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
comm->exchange();
if (atom->sortfreq > 0) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build();
neighbor->ncalls = 0;
// remove these restriction eventually
if (nextra_global && searchflag == 0)
error->all(FLERR,
"Cannot use a damped dynamics min style with fix box/relax");
if (nextra_atom && searchflag == 0)
error->all(FLERR,
"Cannot use a damped dynamics min style with per-atom DOF");
// atoms may have migrated in comm->exchange()
reset_vectors();
// compute all forces
ev_set(update->ntimestep);
force_clear();
modify->setup_pre_force(vflag);
if (force->pair) force->pair->compute(eflag,vflag);
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
}
if (force->newton) comm->reverse_comm();
// update per-atom minimization variables stored by pair styles
if (nextra_atom)
for (int m = 0; m < nextra_atom; m++)
requestor[m]->min_xf_get(m);
modify->setup(vflag);
output->setup(1);
// stats for Finish to print
ecurrent = pe_compute->compute_scalar();
if (nextra_global) ecurrent += modify->min_energy(fextra);
if (output->thermo->normflag) ecurrent /= atom->natoms;
einitial = ecurrent;
fnorm2_init = sqrt(fnorm_sqr());
fnorminf_init = fnorm_inf();
}
/* ----------------------------------------------------------------------
setup without output or one-time post-init setup
flag = 0 = just force calculation
flag = 1 = reneighbor and force calculation
------------------------------------------------------------------------- */
void Min::setup_minimal(int flag)
{
// setup domain, communication and neighboring
// acquire ghosts
// build neighbor lists
if (flag) {
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
comm->exchange();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build();
neighbor->ncalls = 0;
}
// atoms may have migrated in comm->exchange()
reset_vectors();
// compute all forces
ev_set(update->ntimestep);
force_clear();
modify->setup_pre_force(vflag);
if (force->pair) force->pair->compute(eflag,vflag);
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
}
if (force->newton) comm->reverse_comm();
// update per-atom minimization variables stored by pair styles
if (nextra_atom)
for (int m = 0; m < nextra_atom; m++)
requestor[m]->min_xf_get(m);
modify->setup(vflag);
// stats for Finish to print
ecurrent = pe_compute->compute_scalar();
if (nextra_global) ecurrent += modify->min_energy(fextra);
if (output->thermo->normflag) ecurrent /= atom->natoms;
einitial = ecurrent;
fnorm2_init = sqrt(fnorm_sqr());
fnorminf_init = fnorm_inf();
}
/* ----------------------------------------------------------------------
perform minimization, calling iterate() for N steps
------------------------------------------------------------------------- */
void Min::run(int n)
{
// minimizer iterations
stop_condition = iterate(n);
stopstr = stopstrings(stop_condition);
// if early exit from iterate loop:
// set update->nsteps to niter for Finish stats to print
// set output->next values to this timestep
// call energy_force() to insure vflag is set when forces computed
// output->write does final output for thermo, dump, restart files
// add ntimestep to all computes that store invocation times
// since are hardwiring call to thermo/dumps and computes may not be ready
if (stop_condition) {
update->nsteps = niter;
if (update->restrict_output == 0) {
for (int idump = 0; idump < output->ndump; idump++)
output->next_dump[idump] = update->ntimestep;
output->next_dump_any = update->ntimestep;
if (output->restart_every) output->next_restart = update->ntimestep;
}
output->next_thermo = update->ntimestep;
modify->addstep_compute_all(update->ntimestep);
ecurrent = energy_force(0);
output->write(update->ntimestep);
}
}
/* ---------------------------------------------------------------------- */
void Min::cleanup()
{
// stats for Finish to print
efinal = ecurrent;
fnorm2_final = sqrt(fnorm_sqr());
fnorminf_final = fnorm_inf();
// reset reneighboring criteria
neighbor->every = neigh_every;
neighbor->delay = neigh_delay;
neighbor->dist_check = neigh_dist_check;
// delete fix at end of run, so its atom arrays won't persist
modify->delete_fix("MINIMIZE");
}
/* ----------------------------------------------------------------------
evaluate potential energy and forces
may migrate atoms due to reneighboring
return new energy, which should include nextra_global dof
return negative gradient stored in atom->f
return negative gradient for nextra_global dof in fextra
------------------------------------------------------------------------- */
double Min::energy_force(int resetflag)
{
// check for reneighboring
// always communicate since minimizer moved atoms
int nflag = neighbor->decide();
if (nflag == 0) {
timer->stamp();
comm->forward_comm();
timer->stamp(TIME_COMM);
} else {
if (modify->n_min_pre_exchange) modify->min_pre_exchange();
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
if (domain->box_change) {
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
}
timer->stamp();
comm->exchange();
if (atom->sortfreq > 0 &&
update->ntimestep >= atom->nextsort) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(TIME_COMM);
neighbor->build();
timer->stamp(TIME_NEIGHBOR);
}
ev_set(update->ntimestep);
force_clear();
if (modify->n_min_pre_force) modify->min_pre_force(vflag);
timer->stamp();
if (force->pair) {
force->pair->compute(eflag,vflag);
timer->stamp(TIME_PAIR);
}
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
timer->stamp(TIME_BOND);
}
if (force->kspace) {
force->kspace->compute(eflag,vflag);
timer->stamp(TIME_KSPACE);
}
if (force->newton) {
comm->reverse_comm();
timer->stamp(TIME_COMM);
}
// update per-atom minimization variables stored by pair styles
if (nextra_atom)
for (int m = 0; m < nextra_atom; m++)
requestor[m]->min_xf_get(m);
// fixes that affect minimization
if (modify->n_min_post_force) modify->min_post_force(vflag);
// compute potential energy of system
// normalize if thermo PE does
double energy = pe_compute->compute_scalar();
if (nextra_global) energy += modify->min_energy(fextra);
if (output->thermo->normflag) energy /= atom->natoms;
// if reneighbored, atoms migrated
// if resetflag = 1, update x0 of atoms crossing PBC
// reset vectors used by lo-level minimizer
if (nflag) {
if (resetflag) fix_minimize->reset_coords();
reset_vectors();
}
return energy;
}
/* ----------------------------------------------------------------------
clear force on own & ghost atoms
setup and clear other arrays as needed
------------------------------------------------------------------------- */
void Min::force_clear()
{
+ if (external_force_clear) return;
+
int i;
if (external_force_clear) return;
// clear global force array
// nall includes ghosts only if either newton flag is set
int nall;
if (force->newton) nall = atom->nlocal + atom->nghost;
else nall = atom->nlocal;
- int ntot = nall * comm->nthreads;
-
- double **f = atom->f;
- for (i = 0; i < ntot; i++) {
- f[i][0] = 0.0;
- f[i][1] = 0.0;
- f[i][2] = 0.0;
- }
- if (torqueflag) {
- double **torque = atom->torque;
- for (i = 0; i < nall; i++) {
- torque[i][0] = 0.0;
- torque[i][1] = 0.0;
- torque[i][2] = 0.0;
- }
- }
-
- if (erforceflag) {
- double *erforce = atom->erforce;
- for (i = 0; i < nall; i++) erforce[i] = 0.0;
- }
+ size_t nbytes = sizeof(double) * nall;
- if (e_flag) {
- double *de = atom->de;
- for (i = 0; i < nall; i++) de[i] = 0.0;
- }
-
- if (rho_flag) {
- double *drho = atom->drho;
- for (i = 0; i < nall; i++) drho[i] = 0.0;
+ if (nbytes) {
+ memset(&(atom->f[0][0]),0,3*nbytes);
+ if (torqueflag) memset(&(atom->torque[0][0]),0,3*nbytes);
+ if (erforceflag) memset(&(atom->erforce[0]), 0, nbytes);
+ if (e_flag) memset(&(atom->de[0]), 0, nbytes);
+ if (rho_flag) memset(&(atom->drho[0]), 0, nbytes);
}
}
/* ----------------------------------------------------------------------
pair style makes request to add a per-atom variables to minimization
requestor stores callback to pair class to invoke during min
to get current variable and forces on it and to update the variable
return flag that pair can use if it registers multiple variables
------------------------------------------------------------------------- */
int Min::request(Pair *pair, int peratom, double maxvalue)
{
int n = nextra_atom + 1;
xextra_atom = (double **) memory->srealloc(xextra_atom,n*sizeof(double *),
"min:xextra_atom");
fextra_atom = (double **) memory->srealloc(fextra_atom,n*sizeof(double *),
"min:fextra_atom");
memory->grow(extra_peratom,n,"min:extra_peratom");
memory->grow(extra_nlen,n,"min:extra_nlen");
memory->grow(extra_max,n,"min:extra_max");
requestor = (Pair **) memory->srealloc(requestor,n*sizeof(Pair *),
"min:requestor");
requestor[nextra_atom] = pair;
extra_peratom[nextra_atom] = peratom;
extra_max[nextra_atom] = maxvalue;
nextra_atom++;
return nextra_atom-1;
}
/* ---------------------------------------------------------------------- */
void Min::modify_params(int narg, char **arg)
{
if (narg == 0) error->all(FLERR,"Illegal min_modify command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"dmax") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
dmax = atof(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"line") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command");
if (strcmp(arg[iarg+1],"backtrack") == 0) linestyle = 0;
else if (strcmp(arg[iarg+1],"quadratic") == 0) linestyle = 1;
else error->all(FLERR,"Illegal min_modify command");
iarg += 2;
} else error->all(FLERR,"Illegal min_modify command");
}
}
/* ----------------------------------------------------------------------
setup lists of computes for global and per-atom PE and pressure
------------------------------------------------------------------------- */
void Min::ev_setup()
{
delete [] elist_global;
delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
elist_global = elist_atom = NULL;
vlist_global = vlist_atom = NULL;
nelist_global = nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peflag) nelist_global++;
if (modify->compute[i]->peatomflag) nelist_atom++;
if (modify->compute[i]->pressflag) nvlist_global++;
if (modify->compute[i]->pressatomflag) nvlist_atom++;
}
if (nelist_global) elist_global = new Compute*[nelist_global];
if (nelist_atom) elist_atom = new Compute*[nelist_atom];
if (nvlist_global) vlist_global = new Compute*[nvlist_global];
if (nvlist_atom) vlist_atom = new Compute*[nvlist_atom];
nelist_global = nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peflag)
elist_global[nelist_global++] = modify->compute[i];
if (modify->compute[i]->peatomflag)
elist_atom[nelist_atom++] = modify->compute[i];
if (modify->compute[i]->pressflag)
vlist_global[nvlist_global++] = modify->compute[i];
if (modify->compute[i]->pressatomflag)
vlist_atom[nvlist_atom++] = modify->compute[i];
}
}
/* ----------------------------------------------------------------------
set eflag,vflag for current iteration
invoke matchstep() on all timestep-dependent computes to clear their arrays
eflag/vflag based on computes that need info on this ntimestep
always set eflag_global = 1, since need energy every iteration
eflag = 0 = no energy computation
eflag = 1 = global energy only
eflag = 2 = per-atom energy only
eflag = 3 = both global and per-atom energy
vflag = 0 = no virial computation (pressure)
vflag = 1 = global virial with pair portion via sum of pairwise interactions
vflag = 2 = global virial with pair portion via F dot r including ghosts
vflag = 4 = per-atom virial only
vflag = 5 or 6 = both global and per-atom virial
------------------------------------------------------------------------- */
void Min::ev_set(bigint ntimestep)
{
int i,flag;
int eflag_global = 1;
for (i = 0; i < nelist_global; i++)
elist_global[i]->matchstep(ntimestep);
flag = 0;
int eflag_atom = 0;
for (i = 0; i < nelist_atom; i++)
if (elist_atom[i]->matchstep(ntimestep)) flag = 1;
if (flag) eflag_atom = 2;
if (eflag_global) update->eflag_global = update->ntimestep;
if (eflag_atom) update->eflag_atom = update->ntimestep;
eflag = eflag_global + eflag_atom;
flag = 0;
int vflag_global = 0;
for (i = 0; i < nvlist_global; i++)
if (vlist_global[i]->matchstep(ntimestep)) flag = 1;
if (flag) vflag_global = virial_style;
flag = 0;
int vflag_atom = 0;
for (i = 0; i < nvlist_atom; i++)
if (vlist_atom[i]->matchstep(ntimestep)) flag = 1;
if (flag) vflag_atom = 4;
if (vflag_global) update->vflag_global = update->ntimestep;
if (vflag_atom) update->vflag_atom = update->ntimestep;
vflag = vflag_global + vflag_atom;
}
/* ----------------------------------------------------------------------
compute and return ||force||_2^2
------------------------------------------------------------------------- */
double Min::fnorm_sqr()
{
int i,n;
double *fatom;
double local_norm2_sqr = 0.0;
for (i = 0; i < nvec; i++) local_norm2_sqr += fvec[i]*fvec[i];
if (nextra_atom) {
for (int m = 0; m < nextra_atom; m++) {
fatom = fextra_atom[m];
n = extra_nlen[m];
for (i = 0; i < n; i++)
local_norm2_sqr += fatom[i]*fatom[i];
}
}
double norm2_sqr = 0.0;
MPI_Allreduce(&local_norm2_sqr,&norm2_sqr,1,MPI_DOUBLE,MPI_SUM,world);
if (nextra_global)
for (i = 0; i < nextra_global; i++)
norm2_sqr += fextra[i]*fextra[i];
return norm2_sqr;
}
/* ----------------------------------------------------------------------
compute and return ||force||_inf
------------------------------------------------------------------------- */
double Min::fnorm_inf()
{
int i,n;
double *fatom;
double local_norm_inf = 0.0;
for (i = 0; i < nvec; i++)
local_norm_inf = MAX(fabs(fvec[i]),local_norm_inf);
if (nextra_atom) {
for (int m = 0; m < nextra_atom; m++) {
fatom = fextra_atom[m];
n = extra_nlen[m];
for (i = 0; i < n; i++)
local_norm_inf = MAX(fabs(fatom[i]),local_norm_inf);
}
}
double norm_inf = 0.0;
MPI_Allreduce(&local_norm_inf,&norm_inf,1,MPI_DOUBLE,MPI_MAX,world);
if (nextra_global)
for (i = 0; i < nextra_global; i++)
norm_inf = MAX(fabs(fextra[i]),norm_inf);
return norm_inf;
}
/* ----------------------------------------------------------------------
possible stop conditions
------------------------------------------------------------------------- */
char *Min::stopstrings(int n)
{
char *strings[] = {"max iterations",
"max force evaluations",
"energy tolerance",
"force tolerance",
"search direction is not downhill",
"linesearch alpha is zero",
"forces are zero",
"quadratic factors are zero",
"trust region too small",
"HFTN minimizer error"};
return strings[n];
}
diff --git a/src/minimize.cpp b/src/minimize.cpp
index f93fbf538..8f8f9d654 100644
--- a/src/minimize.cpp
+++ b/src/minimize.cpp
@@ -1,68 +1,69 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "stdlib.h"
#include "minimize.h"
#include "domain.h"
#include "update.h"
#include "min.h"
#include "finish.h"
#include "timer.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Minimize::Minimize(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void Minimize::command(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Illegal minimize command");
if (domain->box_exist == 0)
error->all(FLERR,"Minimize command before simulation box is defined");
update->etol = atof(arg[0]);
update->ftol = atof(arg[1]);
update->nsteps = atoi(arg[2]);
update->max_eval = atoi(arg[3]);
if (update->etol < 0.0 || update->ftol < 0.0)
error->all(FLERR,"Illegal minimize command");
update->whichflag = 2;
update->beginstep = update->firststep = update->ntimestep;
update->endstep = update->laststep = update->firststep + update->nsteps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many iterations");
lmp->init();
update->minimize->setup();
+ timer->init();
timer->barrier_start(TIME_LOOP);
update->minimize->run(update->nsteps);
timer->barrier_stop(TIME_LOOP);
update->minimize->cleanup();
Finish finish(lmp);
finish.end(1);
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
}
diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp
index 13dc4a217..963ee03cf 100644
--- a/src/neigh_list.cpp
+++ b/src/neigh_list.cpp
@@ -1,290 +1,291 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "neigh_list.h"
#include "atom.h"
#include "comm.h"
#include "update.h"
#include "neighbor.h"
#include "neigh_request.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define PGDELTA 1
enum{NSQ,BIN,MULTI}; // also in neighbor.cpp
/* ---------------------------------------------------------------------- */
NeighList::NeighList(LAMMPS *lmp, int size) : Pointers(lmp)
{
maxatoms = 0;
pgsize = size;
inum = gnum = 0;
ilist = NULL;
numneigh = NULL;
firstneigh = NULL;
firstdouble = NULL;
maxpage = 0;
pages = NULL;
dpages = NULL;
dnum = 0;
iskip = NULL;
ijskip = NULL;
listgranhistory = NULL;
fix_history = NULL;
respamiddle = 0;
listinner = NULL;
listmiddle = NULL;
listfull = NULL;
listcopy = NULL;
listskip = NULL;
maxstencil = 0;
stencil = NULL;
stencilxyz = NULL;
maxstencil_multi = 0;
nstencil_multi = NULL;
stencil_multi = NULL;
distsq_multi = NULL;
}
/* ---------------------------------------------------------------------- */
NeighList::~NeighList()
{
if (!listcopy) {
memory->destroy(ilist);
memory->destroy(numneigh);
memory->sfree(firstneigh);
memory->sfree(firstdouble);
for (int i = 0; i < maxpage; i++) memory->destroy(pages[i]);
memory->sfree(pages);
if (dnum) {
for (int i = 0; i < maxpage; i++) memory->destroy(dpages[i]);
memory->sfree(dpages);
}
}
delete [] iskip;
memory->destroy(ijskip);
if (maxstencil) memory->destroy(stencil);
if (ghostflag) memory->destroy(stencilxyz);
if (maxstencil_multi) {
for (int i = 1; i <= atom->ntypes; i++) {
memory->destroy(stencil_multi[i]);
memory->destroy(distsq_multi[i]);
}
delete [] nstencil_multi;
delete [] stencil_multi;
delete [] distsq_multi;
}
}
/* ----------------------------------------------------------------------
grow atom arrays to allow for nmax atoms
triggered by more atoms on a processor
caller knows if this list stores neighs of local atoms or local+ghost
------------------------------------------------------------------------- */
void NeighList::grow(int nmax)
{
// skip if this list is already long enough to store nmax atoms
if (nmax <= maxatoms) return;
maxatoms = nmax;
memory->destroy(ilist);
memory->destroy(numneigh);
memory->sfree(firstneigh);
memory->sfree(firstdouble);
memory->create(ilist,maxatoms,"neighlist:ilist");
memory->create(numneigh,maxatoms,"neighlist:numneigh");
firstneigh = (int **) memory->smalloc(maxatoms*sizeof(int *),
"neighlist:firstneigh");
if (dnum)
firstdouble = (double **) memory->smalloc(maxatoms*sizeof(double *),
"neighlist:firstdouble");
}
/* ----------------------------------------------------------------------
insure stencils are large enough for smax bins
style = BIN or MULTI
------------------------------------------------------------------------- */
void NeighList::stencil_allocate(int smax, int style)
{
int i;
if (style == BIN) {
if (smax > maxstencil) {
maxstencil = smax;
memory->destroy(stencil);
memory->create(stencil,maxstencil,"neighlist:stencil");
if (ghostflag) {
memory->destroy(stencilxyz);
memory->create(stencilxyz,maxstencil,3,"neighlist:stencilxyz");
}
}
} else {
int n = atom->ntypes;
if (maxstencil_multi == 0) {
nstencil_multi = new int[n+1];
stencil_multi = new int*[n+1];
distsq_multi = new double*[n+1];
for (i = 1; i <= n; i++) {
nstencil_multi[i] = 0;
stencil_multi[i] = NULL;
distsq_multi[i] = NULL;
}
}
if (smax > maxstencil_multi) {
maxstencil_multi = smax;
for (i = 1; i <= n; i++) {
memory->destroy(stencil_multi[i]);
memory->destroy(distsq_multi[i]);
memory->create(stencil_multi[i],maxstencil_multi,
"neighlist:stencil_multi");
memory->create(distsq_multi[i],maxstencil_multi,
"neighlist:distsq_multi");
}
}
}
}
/* ----------------------------------------------------------------------
add PGDELTA pages to neighbor list
------------------------------------------------------------------------- */
-int **NeighList::add_pages()
+int **NeighList::add_pages(int howmany)
{
int toppage = maxpage;
- maxpage += PGDELTA;
+ maxpage += howmany*PGDELTA;
pages = (int **)
memory->srealloc(pages,maxpage*sizeof(int *),"neighlist:pages");
for (int i = toppage; i < maxpage; i++)
memory->create(pages[i],pgsize,"neighlist:pages[i]");
if (dnum) {
dpages = (double **)
memory->srealloc(dpages,maxpage*sizeof(double *),"neighlist:dpages");
for (int i = toppage; i < maxpage; i++)
memory->create(dpages[i],dnum*pgsize,"neighlist:dpages[i]");
}
return pages;
}
/* ----------------------------------------------------------------------
copy skip info from request rq into list's iskip,ijskip
------------------------------------------------------------------------- */
void NeighList::copy_skip_info(int *rq_iskip, int **rq_ijskip)
{
int ntypes = atom->ntypes;
iskip = new int[ntypes+1];
memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip");
int i,j;
for (i = 1; i <= ntypes; i++) iskip[i] = rq_iskip[i];
for (i = 1; i <= ntypes; i++)
for (j = 1; j <= ntypes; j++)
ijskip[i][j] = rq_ijskip[i][j];
}
/* ----------------------------------------------------------------------
print attributes of this list and associated request
------------------------------------------------------------------------- */
void NeighList::print_attributes()
{
if (comm->me != 0) return;
NeighRequest *rq = neighbor->requests[index];
printf("Neighbor list/request %d:\n",index);
printf(" %d = build flag\n",buildflag);
printf(" %d = grow flag\n",growflag);
printf(" %d = stencil flag\n",stencilflag);
printf(" %d = ghost flag\n",ghostflag);
printf("\n");
printf(" %d = pair\n",rq->pair);
printf(" %d = fix\n",rq->fix);
printf(" %d = compute\n",rq->compute);
printf(" %d = command\n",rq->command);
printf("\n");
printf(" %d = half\n",rq->half);
printf(" %d = full\n",rq->full);
printf(" %d = gran\n",rq->gran);
printf(" %d = granhistory\n",rq->granhistory);
printf(" %d = respainner\n",rq->respainner);
printf(" %d = respamiddle\n",rq->respamiddle);
printf(" %d = respaouter\n",rq->respaouter);
printf(" %d = half_from_full\n",rq->half_from_full);
printf("\n");
printf(" %d = occasional\n",rq->occasional);
printf(" %d = dnum\n",rq->dnum);
+ printf(" %d = omp\n",rq->omp);
printf(" %d = ghost\n",rq->ghost);
printf(" %d = cudable\n",rq->cudable);
printf(" %d = omp\n",rq->omp);
printf(" %d = copy\n",rq->copy);
printf(" %d = skip\n",rq->skip);
printf(" %d = otherlist\n",rq->otherlist);
printf(" %p = listskip\n",listskip);
printf("\n");
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
if growflag = 0, maxatoms & maxpage will also be 0
if stencilflag = 0, maxstencil * maxstencil_multi will also be 0
------------------------------------------------------------------------- */
bigint NeighList::memory_usage()
{
bigint bytes = 0;
bytes += memory->usage(ilist,maxatoms);
bytes += memory->usage(numneigh,maxatoms);
bytes += maxatoms * sizeof(int *);
bytes += memory->usage(pages,maxpage,pgsize);
if (dnum) {
bytes += maxatoms * sizeof(double *);
bytes += memory->usage(dpages,maxpage,dnum*pgsize);
}
if (maxstencil) bytes += memory->usage(stencil,maxstencil);
if (ghostflag) bytes += memory->usage(stencilxyz,maxstencil,3);
if (maxstencil_multi) {
bytes += memory->usage(stencil_multi,atom->ntypes,maxstencil_multi);
bytes += memory->usage(distsq_multi,atom->ntypes,maxstencil_multi);
}
return bytes;
}
diff --git a/src/neigh_list.h b/src/neigh_list.h
index 63675503c..a8857811a 100644
--- a/src/neigh_list.h
+++ b/src/neigh_list.h
@@ -1,94 +1,94 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_NEIGH_LIST_H
#define LMP_NEIGH_LIST_H
#include "pointers.h"
namespace LAMMPS_NS {
class NeighList : protected Pointers {
public:
int index; // index of which neigh list it is
// needed when a class invokes it directly
int buildflag; // 1 if pair_build invoked every reneigh
int growflag; // 1 if stores atom-based arrays & pages
int stencilflag; // 1 if stores stencil arrays
int ghostflag; // 1 if it stores neighbors of ghosts
// data structs to store neighbor pairs I,J and associated values
int inum; // # of I atoms neighbors are stored for
int gnum; // # of ghost atoms neighbors are stored for
int *ilist; // local indices of I atoms
int *numneigh; // # of J neighbors for each I atom
int **firstneigh; // ptr to 1st J int value of each I atom
double **firstdouble; // ptr to 1st J double value of each I atom
int pgsize; // size of each page
int maxpage; // # of pages currently allocated
int **pages; // neighbor list pages for ints
double **dpages; // neighbor list pages for doubles
int dnum; // # of doubles for each pair (0 if none)
// atom types to skip when building list
// iskip,ijskip are just ptrs to corresponding request
int *iskip; // iskip[i] = 1 if atoms of type I are not in list
int **ijskip; // ijskip[i][j] = 1 if pairs of type I,J are not in list
// settings and pointers for related neighbor lists and fixes
NeighList *listgranhistory; // point at history list
class FixShearHistory *fix_history; // fix that stores history info
int respamiddle; // 1 if this respaouter has middle list
NeighList *listinner; // me = respaouter, point to respainner
NeighList *listmiddle; // me = respaouter, point to respamiddle
NeighList *listfull; // me = half list, point to full I derive from
NeighList *listcopy; // me = copy list, point to list I copy from
NeighList *listskip; // me = skip list, point to list I skip from
// stencils of bin indices for neighbor finding
int maxstencil; // max size of stencil
int nstencil; // # of bins in stencil
int *stencil; // list of bin offsets
int **stencilxyz; // bin offsets in xyz dims
int maxstencil_multi; // max sizes of stencils
int *nstencil_multi; // # bins in each type-based multi stencil
int **stencil_multi; // list of bin offsets in each stencil
double **distsq_multi; // sq distances to bins in each stencil
class CudaNeighList *cuda_list; // CUDA neighbor list
NeighList(class LAMMPS *, int);
~NeighList();
void grow(int); // grow maxlocal
void stencil_allocate(int, int); // allocate stencil arrays
- int **add_pages(); // add pages to neigh list
+ int **add_pages(int howmany=1); // add pages to neigh list
void copy_skip_info(int *, int **); // copy skip info from a neigh request
void print_attributes(); // debug routine
int get_maxlocal() {return maxatoms;}
bigint memory_usage();
private:
int maxatoms; // size of allocated atom arrays
};
}
#endif
diff --git a/src/neighbor.cpp b/src/neighbor.cpp
index f56c31373..a918249f9 100644
--- a/src/neighbor.cpp
+++ b/src/neighbor.cpp
@@ -1,1754 +1,1846 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author (triclinic and multi-neigh) : Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "group.h"
#include "modify.h"
#include "fix.h"
#include "compute.h"
#include "update.h"
#include "respa.h"
#include "output.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define RQDELTA 1
#define EXDELTA 1
#define LB_FACTOR 1.5
#define SMALL 1.0e-6
#define BIG 1.0e20
#define CUT2BIN_RATIO 100
enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp
//#define NEIGH_LIST_DEBUG 1
/* ---------------------------------------------------------------------- */
Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
style = BIN;
every = 1;
delay = 10;
dist_check = 1;
pgsize = 100000;
oneatom = 2000;
binsizeflag = 0;
build_once = 0;
cutneighsq = NULL;
cutneighghostsq = NULL;
cuttype = NULL;
cuttypesq = NULL;
fixchecklist = NULL;
// coords at last neighboring
maxhold = 0;
xhold = NULL;
// binning
maxhead = 0;
binhead = NULL;
maxbin = 0;
bins = NULL;
// pair exclusion list info
includegroup = 0;
nex_type = maxex_type = 0;
ex1_type = ex2_type = NULL;
ex_type = NULL;
nex_group = maxex_group = 0;
ex1_group = ex2_group = ex1_bit = ex2_bit = NULL;
nex_mol = maxex_mol = 0;
ex_mol_group = ex_mol_bit = NULL;
// pair lists
maxatom = 0;
nblist = nglist = nslist = 0;
nlist = 0;
lists = NULL;
pair_build = NULL;
stencil_create = NULL;
blist = glist = slist = NULL;
anyghostlist = 0;
nrequest = maxrequest = 0;
requests = NULL;
old_style = BIN;
old_triclinic = 0;
old_nrequest = 0;
old_requests = NULL;
// bond lists
maxbond = 0;
bondlist = NULL;
maxangle = 0;
anglelist = NULL;
maxdihedral = 0;
dihedrallist = NULL;
maximproper = 0;
improperlist = NULL;
}
/* ---------------------------------------------------------------------- */
Neighbor::~Neighbor()
{
memory->destroy(cutneighsq);
memory->destroy(cutneighghostsq);
delete [] cuttype;
delete [] cuttypesq;
delete [] fixchecklist;
memory->destroy(xhold);
memory->destroy(binhead);
memory->destroy(bins);
memory->destroy(ex1_type);
memory->destroy(ex2_type);
memory->destroy(ex_type);
memory->destroy(ex1_group);
memory->destroy(ex2_group);
delete [] ex1_bit;
delete [] ex2_bit;
memory->destroy(ex_mol_group);
delete [] ex_mol_bit;
for (int i = 0; i < nlist; i++) delete lists[i];
delete [] lists;
delete [] pair_build;
delete [] stencil_create;
delete [] blist;
delete [] glist;
delete [] slist;
for (int i = 0; i < nrequest; i++) delete requests[i];
memory->sfree(requests);
for (int i = 0; i < old_nrequest; i++) delete old_requests[i];
memory->sfree(old_requests);
memory->destroy(bondlist);
memory->destroy(anglelist);
memory->destroy(dihedrallist);
memory->destroy(improperlist);
}
/* ---------------------------------------------------------------------- */
void Neighbor::init()
{
int i,j,m,n;
ncalls = ndanger = 0;
dimension = domain->dimension;
triclinic = domain->triclinic;
newton_pair = force->newton_pair;
// error check
if (delay > 0 && (delay % every) != 0)
error->all(FLERR,"Neighbor delay must be 0 or multiple of every setting");
if (pgsize < 10*oneatom)
error->all(FLERR,"Neighbor page size must be >= 10x the one atom setting");
// ------------------------------------------------------------------
// settings
// bbox lo/hi = bounding box of entire domain, stored by Domain
if (triclinic == 0) {
bboxlo = domain->boxlo;
bboxhi = domain->boxhi;
} else {
bboxlo = domain->boxlo_bound;
bboxhi = domain->boxhi_bound;
}
// set neighbor cutoffs (force cutoff + skin)
// trigger determines when atoms migrate and neighbor lists are rebuilt
// needs to be non-zero for migration distance check
// even if pair = NULL and no neighbor lists are used
// cutneigh = force cutoff + skin if cutforce > 0, else cutneigh = 0
triggersq = 0.25*skin*skin;
boxcheck = 0;
if (domain->box_change && (domain->xperiodic || domain->yperiodic ||
(dimension == 3 && domain->zperiodic)))
boxcheck = 1;
n = atom->ntypes;
if (cutneighsq == NULL) {
memory->create(cutneighsq,n+1,n+1,"neigh:cutneighsq");
memory->create(cutneighghostsq,n+1,n+1,"neigh:cutneighghostsq");
cuttype = new double[n+1];
cuttypesq = new double[n+1];
}
double cutoff,delta,cut;
cutneighmin = BIG;
cutneighmax = 0.0;
for (i = 1; i <= n; i++) {
cuttype[i] = cuttypesq[i] = 0.0;
for (j = 1; j <= n; j++) {
if (force->pair) cutoff = sqrt(force->pair->cutsq[i][j]);
else cutoff = 0.0;
if (cutoff > 0.0) delta = skin;
else delta = 0.0;
cut = cutoff + delta;
cutneighsq[i][j] = cut*cut;
cuttype[i] = MAX(cuttype[i],cut);
cuttypesq[i] = MAX(cuttypesq[i],cut*cut);
cutneighmin = MIN(cutneighmin,cut);
cutneighmax = MAX(cutneighmax,cut);
if (force->pair && force->pair->ghostneigh) {
cut = force->pair->cutghost[i][j] + skin;
cutneighghostsq[i][j] = cut*cut;
}
}
}
cutneighmaxsq = cutneighmax * cutneighmax;
// check other classes that can induce reneighboring in decide()
// don't check if build_once is set
restart_check = 0;
if (output->restart_every) restart_check = 1;
delete [] fixchecklist;
fixchecklist = NULL;
fixchecklist = new int[modify->nfix];
fix_check = 0;
for (i = 0; i < modify->nfix; i++)
if (modify->fix[i]->force_reneighbor)
fixchecklist[fix_check++] = i;
must_check = 0;
if (restart_check || fix_check) must_check = 1;
if (build_once) must_check = 0;
// set special_flag for 1-2, 1-3, 1-4 neighbors
// flag[0] is not used, flag[1] = 1-2, flag[2] = 1-3, flag[3] = 1-4
// flag = 0 if both LJ/Coulomb special values are 0.0
// flag = 1 if both LJ/Coulomb special values are 1.0
// flag = 2 otherwise or if KSpace solver is enabled
// pairwise portion of KSpace solver uses all 1-2,1-3,1-4 neighbors
if (force->special_lj[1] == 0.0 && force->special_coul[1] == 0.0)
special_flag[1] = 0;
else if (force->special_lj[1] == 1.0 && force->special_coul[1] == 1.0)
special_flag[1] = 1;
else special_flag[1] = 2;
if (force->special_lj[2] == 0.0 && force->special_coul[2] == 0.0)
special_flag[2] = 0;
else if (force->special_lj[2] == 1.0 && force->special_coul[2] == 1.0)
special_flag[2] = 1;
else special_flag[2] = 2;
if (force->special_lj[3] == 0.0 && force->special_coul[3] == 0.0)
special_flag[3] = 0;
else if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0)
special_flag[3] = 1;
else special_flag[3] = 2;
if (force->kspace) special_flag[1] = special_flag[2] = special_flag[3] = 2;
// maxwt = max multiplicative factor on atom indices stored in neigh list
maxwt = 0;
if (special_flag[1] == 2) maxwt = 2;
if (special_flag[2] == 2) maxwt = 3;
if (special_flag[3] == 2) maxwt = 4;
// rRESPA cutoffs
int respa = 0;
if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) {
if (((Respa *) update->integrate)->level_inner >= 0) respa = 1;
if (((Respa *) update->integrate)->level_middle >= 0) respa = 2;
}
if (respa) {
double *cut_respa = ((Respa *) update->integrate)->cutoff;
cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin);
cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin);
cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin);
}
// ------------------------------------------------------------------
// xhold, bins, exclusion lists
// free xhold and bins if not needed for this run
if (dist_check == 0) {
memory->destroy(xhold);
maxhold = 0;
xhold = NULL;
}
if (style == NSQ) {
memory->destroy(bins);
memory->destroy(binhead);
maxbin = maxhead = 0;
binhead = NULL;
bins = NULL;
}
// 1st time allocation of xhold and bins
if (dist_check) {
if (maxhold == 0) {
maxhold = atom->nmax;
memory->create(xhold,maxhold,3,"neigh:xhold");
}
}
if (style != NSQ) {
if (maxbin == 0) {
maxbin = atom->nmax;
memory->create(bins,maxbin,"bins");
}
}
// exclusion lists for type, group, molecule settings from neigh_modify
n = atom->ntypes;
if (nex_type == 0 && nex_group == 0 && nex_mol == 0) exclude = 0;
else exclude = 1;
if (nex_type) {
memory->destroy(ex_type);
memory->create(ex_type,n+1,n+1,"neigh:ex_type");
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
ex_type[i][j] = 0;
for (i = 0; i < nex_type; i++) {
if (ex1_type[i] <= 0 || ex1_type[i] > n ||
ex2_type[i] <= 0 || ex2_type[i] > n)
error->all(FLERR,"Invalid atom type in neighbor exclusion list");
ex_type[ex1_type[i]][ex2_type[i]] = 1;
ex_type[ex2_type[i]][ex1_type[i]] = 1;
}
}
if (nex_group) {
delete [] ex1_bit;
delete [] ex2_bit;
ex1_bit = new int[nex_group];
ex2_bit = new int[nex_group];
for (i = 0; i < nex_group; i++) {
ex1_bit[i] = group->bitmask[ex1_group[i]];
ex2_bit[i] = group->bitmask[ex2_group[i]];
}
}
if (nex_mol) {
delete [] ex_mol_bit;
ex_mol_bit = new int[nex_mol];
for (i = 0; i < nex_mol; i++)
ex_mol_bit[i] = group->bitmask[ex_mol_group[i]];
}
// ------------------------------------------------------------------
// pairwise lists
// test if pairwise lists need to be re-created
// no need to re-create if:
// neigh style and triclinic has not changed and
// current requests = old requests
int same = 1;
if (style != old_style) same = 0;
if (triclinic != old_triclinic) same = 0;
if (nrequest != old_nrequest) same = 0;
else
for (i = 0; i < nrequest; i++)
if (requests[i]->identical(old_requests[i]) == 0) same = 0;
#ifdef NEIGH_LIST_DEBUG
if (comm->me == 0) printf("SAME flag %d\n",same);
#endif
// if old and new are not the same, create new pairwise lists
if (!same) {
// delete old lists and create new ones
for (i = 0; i < nlist; i++) delete lists[i];
delete [] lists;
delete [] pair_build;
delete [] stencil_create;
nlist = nrequest;
lists = new NeighList*[nlist];
pair_build = new PairPtr[nlist];
stencil_create = new StencilPtr[nlist];
// create individual lists, one per request
// copy dnum setting from request to list
// pass list ptr back to requestor (except for Command class)
for (i = 0; i < nlist; i++) {
lists[i] = new NeighList(lmp,pgsize);
lists[i]->index = i;
lists[i]->dnum = requests[i]->dnum;
if (requests[i]->pair) {
Pair *pair = (Pair *) requests[i]->requestor;
pair->init_list(requests[i]->id,lists[i]);
} else if (requests[i]->fix) {
Fix *fix = (Fix *) requests[i]->requestor;
fix->init_list(requests[i]->id,lists[i]);
} else if (requests[i]->compute) {
Compute *compute = (Compute *) requests[i]->requestor;
compute->init_list(requests[i]->id,lists[i]);
}
}
// detect lists that are connected to other lists
// if-then-else sequence is important
// since don't want to re-process skip or copy lists further down
// copy: point this list at request->otherlist, could be a skip list
// skip: point this list at request->otherlist, copy skip info from request
// half_from_full: point this list at preceeding full list
// granhistory: set preceeding list's listgranhistory to this list
// also set preceeding list's ptr to FixShearHistory
// respaouter: point this list at preceeding 1/2 inner/middle lists
// pair and half: if there is a full non-occasional non-skip list
// change this list to half_from_full and point at the full list
// parent could be copy list or pair or fix
// fix/compute requests:
// kind of request = half or full, occasional or not doesn't matter
// if request = half and non-skip pair half/respaouter exists,
// become copy of that list if cudable flag matches
// if request = full and non-skip pair full exists,
// become copy of that list if cudable flag matches
// if request = half and non-skip pair full exists,
// become half_from_full of that list if cudable flag matches
// if no matches, do nothing, fix/compute list will be built directly
// ok if parent is copy list
for (i = 0; i < nlist; i++) {
if (requests[i]->copy)
lists[i]->listcopy = lists[requests[i]->otherlist];
else if (requests[i]->skip) {
lists[i]->listskip = lists[requests[i]->otherlist];
lists[i]->copy_skip_info(requests[i]->iskip,requests[i]->ijskip);
} else if (requests[i]->half_from_full)
lists[i]->listfull = lists[i-1];
else if (requests[i]->granhistory) {
lists[i-1]->listgranhistory = lists[i];
for (int ifix = 0; ifix < modify->nfix; ifix++)
if (strcmp(modify->fix[ifix]->style,"SHEAR_HISTORY") == 0)
lists[i-1]->fix_history = (FixShearHistory *) modify->fix[ifix];
} else if (requests[i]->respaouter) {
if (requests[i-1]->respainner) {
lists[i]->respamiddle = 0;
lists[i]->listinner = lists[i-1];
} else {
lists[i]->respamiddle = 1;
lists[i]->listmiddle = lists[i-1];
lists[i]->listinner = lists[i-2];
}
} else if (requests[i]->pair && requests[i]->half) {
for (j = 0; j < nlist; j++)
if (requests[j]->full && requests[j]->occasional == 0 &&
requests[j]->skip == 0) break;
if (j < nlist) {
requests[i]->half = 0;
requests[i]->half_from_full = 1;
lists[i]->listfull = lists[j];
}
} else if (requests[i]->fix || requests[i]->compute) {
for (j = 0; j < nlist; j++) {
if (requests[i]->half && requests[j]->pair &&
requests[j]->skip == 0 && requests[j]->half) break;
if (requests[i]->full && requests[j]->pair &&
requests[j]->skip == 0 && requests[j]->full) break;
if (requests[i]->half && requests[j]->pair &&
requests[j]->skip == 0 && requests[j]->respaouter) break;
}
if (j < nlist && requests[j]->cudable != requests[i]->cudable)
j = nlist;
if (j < nlist) {
requests[i]->copy = 1;
lists[i]->listcopy = lists[j];
} else {
for (j = 0; j < nlist; j++) {
if (requests[i]->half && requests[j]->pair &&
requests[j]->skip == 0 && requests[j]->full) break;
}
if (j < nlist && requests[j]->cudable != requests[i]->cudable)
j = nlist;
if (j < nlist) {
requests[i]->half = 0;
requests[i]->half_from_full = 1;
lists[i]->listfull = lists[j];
}
}
}
}
// set ptrs to pair_build and stencil_create functions for each list
// ptrs set to NULL if not set explicitly
// also set cudable to 0 if any neigh list request is not cudable
for (i = 0; i < nlist; i++) {
choose_build(i,requests[i]);
if (style != NSQ) choose_stencil(i,requests[i]);
else stencil_create[i] = NULL;
if (!requests[i]->cudable) cudable = 0;
}
// set each list's build/grow/stencil/ghost flags based on neigh request
// buildflag = 1 if its pair_build() invoked every reneighbor
// growflag = 1 if it stores atom-based arrays and pages
// stencilflag = 1 if it stores stencil arrays
// ghostflag = 1 if it stores neighbors of ghosts
// anyghostlist = 1 if any non-occasional list stores neighbors of ghosts
anyghostlist = 0;
for (i = 0; i < nlist; i++) {
lists[i]->buildflag = 1;
if (pair_build[i] == NULL) lists[i]->buildflag = 0;
if (requests[i]->occasional) lists[i]->buildflag = 0;
lists[i]->growflag = 1;
if (requests[i]->copy) lists[i]->growflag = 0;
lists[i]->stencilflag = 1;
if (style == NSQ) lists[i]->stencilflag = 0;
if (stencil_create[i] == NULL) lists[i]->stencilflag = 0;
lists[i]->ghostflag = 0;
if (requests[i]->ghost) lists[i]->ghostflag = 1;
if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1;
}
#ifdef NEIGH_LIST_DEBUG
for (i = 0; i < nlist; i++) lists[i]->print_attributes();
#endif
// allocate atom arrays and 1st pages of lists that store them
maxatom = atom->nmax;
for (i = 0; i < nlist; i++)
if (lists[i]->growflag) {
lists[i]->grow(maxatom);
lists[i]->add_pages();
}
// setup 3 vectors of pairwise neighbor lists
// blist = lists whose pair_build() is invoked every reneighbor
// glist = lists who store atom arrays which are used every reneighbor
// slist = lists who store stencil arrays which are used every reneighbor
// blist and glist vectors are used by neighbor::build()
// slist vector is used by neighbor::setup_bins()
nblist = nglist = nslist = 0;
delete [] blist;
delete [] glist;
delete [] slist;
blist = new int[nlist];
glist = new int[nlist];
slist = new int[nlist];
for (i = 0; i < nlist; i++) {
if (lists[i]->buildflag) blist[nblist++] = i;
if (lists[i]->growflag && requests[i]->occasional == 0)
glist[nglist++] = i;
if (lists[i]->stencilflag && requests[i]->occasional == 0)
slist[nslist++] = i;
}
#ifdef NEIGH_LIST_DEBUG
print_lists_of_lists();
#endif
// reorder build vector if necessary
// relevant for lists that copy/skip/half-full from parent
// the derived list must appear in blist after the parent list
// no occasional lists are in build vector
// swap two lists within blist when dependency is mis-ordered
// done when entire pass thru blist results in no swaps
int done = 0;
while (!done) {
done = 1;
for (i = 0; i < nblist; i++) {
NeighList *ptr = NULL;
if (lists[blist[i]]->listfull) ptr = lists[blist[i]]->listfull;
if (lists[blist[i]]->listcopy) ptr = lists[blist[i]]->listcopy;
if (lists[blist[i]]->listskip) ptr = lists[blist[i]]->listskip;
if (ptr == NULL) continue;
for (m = 0; m < nlist; m++)
if (ptr == lists[m]) break;
for (j = 0; j < nblist; j++)
if (m == blist[j]) break;
if (j < i) continue;
int tmp = blist[i];
blist[i] = blist[j];
blist[j] = tmp;
done = 0;
break;
}
}
#ifdef NEIGH_LIST_DEBUG
print_lists_of_lists();
#endif
}
// delete old requests
// copy current requests and style to old for next run
for (i = 0; i < old_nrequest; i++) delete old_requests[i];
memory->sfree(old_requests);
old_nrequest = nrequest;
old_requests = requests;
nrequest = maxrequest = 0;
requests = NULL;
old_style = style;
old_triclinic = triclinic;
// ------------------------------------------------------------------
// topology lists
// 1st time allocation of topology lists
if (atom->molecular && atom->nbonds && maxbond == 0) {
if (nprocs == 1) maxbond = atom->nbonds;
else maxbond = static_cast<int> (LB_FACTOR * atom->nbonds / nprocs);
memory->create(bondlist,maxbond,3,"neigh:bondlist");
}
if (atom->molecular && atom->nangles && maxangle == 0) {
if (nprocs == 1) maxangle = atom->nangles;
else maxangle = static_cast<int> (LB_FACTOR * atom->nangles / nprocs);
memory->create(anglelist,maxangle,4,"neigh:anglelist");
}
if (atom->molecular && atom->ndihedrals && maxdihedral == 0) {
if (nprocs == 1) maxdihedral = atom->ndihedrals;
else maxdihedral = static_cast<int>
(LB_FACTOR * atom->ndihedrals / nprocs);
memory->create(dihedrallist,maxdihedral,5,"neigh:dihedrallist");
}
if (atom->molecular && atom->nimpropers && maximproper == 0) {
if (nprocs == 1) maximproper = atom->nimpropers;
else maximproper = static_cast<int>
(LB_FACTOR * atom->nimpropers / nprocs);
memory->create(improperlist,maximproper,5,"neigh:improperlist");
}
// set flags that determine which topology neighboring routines to use
// SHAKE sets bonds and angles negative
// bond_quartic sets bonds to 0
// delete_bonds sets all interactions negative
int bond_off = 0;
int angle_off = 0;
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"shake") == 0)
bond_off = angle_off = 1;
if (force->bond && force->bond_match("quartic")) bond_off = 1;
if (atom->avec->bonds_allow) {
for (i = 0; i < atom->nlocal; i++) {
if (bond_off) break;
for (m = 0; m < atom->num_bond[i]; m++)
if (atom->bond_type[i][m] <= 0) bond_off = 1;
}
}
if (atom->avec->angles_allow) {
for (i = 0; i < atom->nlocal; i++) {
if (angle_off) break;
for (m = 0; m < atom->num_angle[i]; m++)
if (atom->angle_type[i][m] <= 0) angle_off = 1;
}
}
int dihedral_off = 0;
if (atom->avec->dihedrals_allow) {
for (i = 0; i < atom->nlocal; i++) {
if (dihedral_off) break;
for (m = 0; m < atom->num_dihedral[i]; m++)
if (atom->dihedral_type[i][m] <= 0) dihedral_off = 1;
}
}
int improper_off = 0;
if (atom->avec->impropers_allow) {
for (i = 0; i < atom->nlocal; i++) {
if (improper_off) break;
for (m = 0; m < atom->num_improper[i]; m++)
if (atom->improper_type[i][m] <= 0) improper_off = 1;
}
}
// set ptrs to topology build functions
if (bond_off) bond_build = &Neighbor::bond_partial;
else bond_build = &Neighbor::bond_all;
if (angle_off) angle_build = &Neighbor::angle_partial;
else angle_build = &Neighbor::angle_all;
if (dihedral_off) dihedral_build = &Neighbor::dihedral_partial;
else dihedral_build = &Neighbor::dihedral_all;
if (improper_off) improper_build = &Neighbor::improper_partial;
else improper_build = &Neighbor::improper_all;
// set topology neighbor list counts to 0
// in case all are turned off but potential is still defined
nbondlist = nanglelist = ndihedrallist = nimproperlist = 0;
}
/* ---------------------------------------------------------------------- */
int Neighbor::request(void *requestor)
{
if (nrequest == maxrequest) {
maxrequest += RQDELTA;
requests = (NeighRequest **)
memory->srealloc(requests,maxrequest*sizeof(NeighRequest *),
"neighbor:requests");
}
requests[nrequest] = new NeighRequest(lmp);
requests[nrequest]->requestor = requestor;
nrequest++;
return nrequest-1;
}
/* ----------------------------------------------------------------------
determine which pair_build function each neigh list needs
based on settings of neigh request
copy -> copy_from function
skip -> granular function if gran with granhistory,
respa function if respaouter,
skip_from function for everything else
half_from_full, half, full, gran, respaouter ->
choose by newton and rq->newton and tri settings
style NSQ options = newton off, newton on
style BIN options = newton off, newton on and not tri, newton on and tri
stlye MULTI options = same options as BIN
if none of these, ptr = NULL since pair_build is not invoked for this list
use "else if" b/c skip,copy can be set in addition to half,full,etc
------------------------------------------------------------------------- */
void Neighbor::choose_build(int index, NeighRequest *rq)
{
PairPtr pb = NULL;
- if (rq->copy) pb = &Neighbor::copy_from;
+ if (rq->omp == 0) {
+
+ if (rq->copy) pb = &Neighbor::copy_from;
+
+ else if (rq->skip) {
+ if (rq->gran && lists[index]->listgranhistory)
+ pb = &Neighbor::skip_from_granular;
+ else if (rq->respaouter) pb = &Neighbor::skip_from_respa;
+ else pb = &Neighbor::skip_from;
+
+ } else if (rq->half_from_full) {
+ if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton;
+ else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton;
+
+ } else if (rq->half) {
+ if (style == NSQ) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton;
+ else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton;
+ } else if (rq->newton == 1) {
+ pb = &Neighbor::half_nsq_newton;
+ } else if (rq->newton == 2) {
+ pb = &Neighbor::half_nsq_no_newton;
+ }
+ } else if (style == BIN) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton;
+ else if (triclinic == 0) pb = &Neighbor::half_bin_newton;
+ else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri;
+ } else if (rq->newton == 1) {
+ if (triclinic == 0) pb = &Neighbor::half_bin_newton;
+ else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri;
+ } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton;
+ } else if (style == MULTI) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton;
+ else if (triclinic == 0) pb = &Neighbor::half_multi_newton;
+ else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri;
+ } else if (rq->newton == 1) {
+ if (triclinic == 0) pb = &Neighbor::half_multi_newton;
+ else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri;
+ } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton;
+ }
- else if (rq->skip) {
- if (rq->gran && lists[index]->listgranhistory)
- pb = &Neighbor::skip_from_granular;
- else if (rq->respaouter) pb = &Neighbor::skip_from_respa;
- else pb = &Neighbor::skip_from;
+ } else if (rq->full) {
+ if (style == NSQ) {
+ if (rq->ghost == 0) pb = &Neighbor::full_nsq;
+ else if (includegroup)
+ error->all(FLERR,
+ "Neighbor include group not allowed with ghost neighbors");
+ else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost;
+ } else if (style == BIN) {
+ if (rq->ghost == 0) pb = &Neighbor::full_bin;
+ else if (includegroup)
+ error->all(FLERR,
+ "Neighbor include group not allowed with ghost neighbors");
+ else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost;
+ } else if (style == MULTI) {
+ if (rq->ghost == 0) pb = &Neighbor::full_multi;
+ else error->all(FLERR,
+ "Neighbor multi not yet enabled for ghost neighbors");
+ }
- } else if (rq->half_from_full) {
- if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton;
- else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton;
+ } else if (rq->gran) {
+ if (style == NSQ) {
+ if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton;
+ else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton;
+ } else if (style == BIN) {
+ if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton;
+ else if (triclinic == 0) pb = &Neighbor::granular_bin_newton;
+ else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri;
+ } else if (style == MULTI)
+ error->all(FLERR,"Neighbor multi not yet enabled for granular");
+
+ } else if (rq->respaouter) {
+ if (style == NSQ) {
+ if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton;
+ else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton;
+ } else if (style == BIN) {
+ if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton;
+ else if (triclinic == 0) pb = &Neighbor::respa_bin_newton;
+ else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri;
+ } else if (style == MULTI)
+ error->all(FLERR,"Neighbor multi not yet enabled for rRESPA");
+ }
+ } else {
- } else if (rq->half) {
- if (style == NSQ) {
- if (rq->newton == 0) {
- if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton;
- else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton;
- } else if (rq->newton == 1) {
- pb = &Neighbor::half_nsq_newton;
- } else if (rq->newton == 2) {
- pb = &Neighbor::half_nsq_no_newton;
+ if (rq->copy) pb = &Neighbor::copy_from;
+
+ else if (rq->skip) {
+ if (rq->gran && lists[index]->listgranhistory)
+ pb = &Neighbor::skip_from_granular;
+ else if (rq->respaouter) pb = &Neighbor::skip_from_respa;
+ else pb = &Neighbor::skip_from;
+
+ } else if (rq->half_from_full) {
+ if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton_omp;
+ else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton_omp;
+
+ } else if (rq->half) {
+ if (style == NSQ) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_nsq_no_newton_omp;
+ else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton_omp;
+ } else if (rq->newton == 1) {
+ pb = &Neighbor::half_nsq_newton_omp;
+ } else if (rq->newton == 2) {
+ pb = &Neighbor::half_nsq_no_newton_omp;
+ }
+ } else if (style == BIN) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton_omp;
+ else if (triclinic == 0) pb = &Neighbor::half_bin_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri_omp;
+ } else if (rq->newton == 1) {
+ if (triclinic == 0) pb = &Neighbor::half_bin_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri_omp;
+ } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton_omp;
+ } else if (style == MULTI) {
+ if (rq->newton == 0) {
+ if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton_omp;
+ else if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp;
+ } else if (rq->newton == 1) {
+ if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp;
+ } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton_omp;
}
- } else if (style == BIN) {
- if (rq->newton == 0) {
- if (newton_pair == 0) pb = &Neighbor::half_bin_no_newton;
- else if (triclinic == 0) pb = &Neighbor::half_bin_newton;
- else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri;
- } else if (rq->newton == 1) {
- if (triclinic == 0) pb = &Neighbor::half_bin_newton;
- else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri;
- } else if (rq->newton == 2) pb = &Neighbor::half_bin_no_newton;
- } else if (style == MULTI) {
- if (rq->newton == 0) {
- if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton;
- else if (triclinic == 0) pb = &Neighbor::half_multi_newton;
- else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri;
- } else if (rq->newton == 1) {
- if (triclinic == 0) pb = &Neighbor::half_multi_newton;
- else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri;
- } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton;
- }
- } else if (rq->full) {
- if (style == NSQ) {
- if (rq->ghost == 0) pb = &Neighbor::full_nsq;
- else if (includegroup)
- error->all(FLERR,"Neighbor include group not allowed with ghost neighbors");
- else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost;
- } else if (style == BIN) {
- if (rq->ghost == 0) pb = &Neighbor::full_bin;
- else if (includegroup)
- error->all(FLERR,"Neighbor include group not allowed with ghost neighbors");
- else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost;
- } else if (style == MULTI) {
- if (rq->ghost == 0) pb = &Neighbor::full_multi;
- else error->all(FLERR,"Neighbor multi not yet enabled for ghost neighbors");
- }
+ } else if (rq->full) {
+ if (style == NSQ) {
+ if (rq->ghost == 0) pb = &Neighbor::full_nsq_omp;
+ else if (includegroup)
+ error->all(FLERR,
+ "Neighbor include group not allowed with ghost neighbors");
+ else if (rq->ghost == 1) pb = &Neighbor::full_nsq_ghost_omp;
+ } else if (style == BIN) {
+ if (rq->ghost == 0) pb = &Neighbor::full_bin_omp;
+ else if (includegroup)
+ error->all(FLERR,
+ "Neighbor include group not allowed with ghost neighbors");
+ else if (rq->ghost == 1) pb = &Neighbor::full_bin_ghost_omp;
+ } else if (style == MULTI) {
+ if (rq->ghost == 0) pb = &Neighbor::full_multi_omp;
+ else error->all(FLERR,
+ "Neighbor multi not yet enabled for ghost neighbors");
+ }
- } else if (rq->gran) {
- if (style == NSQ) {
- if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton;
- else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton;
- } else if (style == BIN) {
- if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton;
- else if (triclinic == 0) pb = &Neighbor::granular_bin_newton;
- else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri;
- } else if (style == MULTI)
- error->all(FLERR,"Neighbor multi not yet enabled for granular");
-
- } else if (rq->respaouter) {
- if (style == NSQ) {
- if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton;
- else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton;
- } else if (style == BIN) {
- if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton;
- else if (triclinic == 0) pb = &Neighbor::respa_bin_newton;
- else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri;
- } else if (style == MULTI)
- error->all(FLERR,"Neighbor multi not yet enabled for rRESPA");
+ } else if (rq->gran) {
+ if (style == NSQ) {
+ if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton_omp;
+ else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton_omp;
+ } else if (style == BIN) {
+ if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton_omp;
+ else if (triclinic == 0) pb = &Neighbor::granular_bin_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri_omp;
+ } else if (style == MULTI)
+ error->all(FLERR,"Neighbor multi not yet enabled for granular");
+
+ } else if (rq->respaouter) {
+ if (style == NSQ) {
+ if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton_omp;
+ else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton_omp;
+ } else if (style == BIN) {
+ if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton_omp;
+ else if (triclinic == 0) pb = &Neighbor::respa_bin_newton_omp;
+ else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri_omp;
+ } else if (style == MULTI)
+ error->all(FLERR,"Neighbor multi not yet enabled for rRESPA");
+ }
}
// general error check
if (rq->ghost && !rq->full)
- error->all(FLERR,"Neighbors of ghost atoms only allowed for full neighbor lists");
+ error->all(FLERR,
+ "Neighbors of ghost atoms only allowed for full neighbor lists");
pair_build[index] = pb;
}
/* ----------------------------------------------------------------------
determine which stencil_create function each neigh list needs
based on settings of neigh request, only called if style != NSQ
skip or copy or half_from_full -> no stencil
half, gran, respaouter, full -> choose by newton and tri and dimension
if none of these, ptr = NULL since this list needs no stencils
use "else if" b/c skip,copy can be set in addition to half,full,etc
------------------------------------------------------------------------- */
void Neighbor::choose_stencil(int index, NeighRequest *rq)
{
StencilPtr sc = NULL;
if (rq->skip || rq->copy || rq->half_from_full) sc = NULL;
else if (rq->half || rq->gran || rq->respaouter) {
if (style == BIN) {
if (rq->newton == 0) {
if (newton_pair == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_no_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_no_newton;
} else if (triclinic == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_newton;
} else if (triclinic == 1) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_newton_tri;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_newton_tri;
}
} else if (rq->newton == 1) {
if (triclinic == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_newton;
} else if (triclinic == 1) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_newton_tri;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_newton_tri;
}
} else if (rq->newton == 2) {
if (dimension == 2)
sc = &Neighbor::stencil_half_bin_2d_no_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_bin_3d_no_newton;
}
} else if (style == MULTI) {
if (rq->newton == 0) {
if (newton_pair == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_no_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_no_newton;
} else if (triclinic == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_newton;
} else if (triclinic == 1) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_newton_tri;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_newton_tri;
}
} else if (rq->newton == 1) {
if (triclinic == 0) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_newton;
} else if (triclinic == 1) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_newton_tri;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_newton_tri;
}
} else if (rq->newton == 2) {
if (dimension == 2)
sc = &Neighbor::stencil_half_multi_2d_no_newton;
else if (dimension == 3)
sc = &Neighbor::stencil_half_multi_3d_no_newton;
}
}
} else if (rq->full) {
if (style == BIN) {
if (dimension == 2) {
if (rq->ghost) sc = &Neighbor::stencil_full_ghost_bin_2d;
else sc = &Neighbor::stencil_full_bin_2d;
}
else if (dimension == 3) {
if (rq->ghost) sc = &Neighbor::stencil_full_ghost_bin_3d;
else sc = &Neighbor::stencil_full_bin_3d;
}
} else if (style == MULTI) {
if (dimension == 2) sc = &Neighbor::stencil_full_multi_2d;
else if (dimension == 3) sc = &Neighbor::stencil_full_multi_3d;
}
}
stencil_create[index] = sc;
}
/* ---------------------------------------------------------------------- */
void Neighbor::print_lists_of_lists()
{
if (comm->me == 0) {
printf("Build lists = %d: ",nblist);
for (int i = 0; i < nblist; i++) printf("%d ",blist[i]);
printf("\n");
printf("Grow lists = %d: ",nglist);
for (int i = 0; i < nglist; i++) printf("%d ",glist[i]);
printf("\n");
printf("Stencil lists = %d: ",nslist);
for (int i = 0; i < nslist; i++) printf("%d ",slist[i]);
printf("\n");
}
}
/* ---------------------------------------------------------------------- */
int Neighbor::decide()
{
if (must_check) {
int n = update->ntimestep;
if (restart_check && n == output->next_restart) return 1;
for (int i = 0; i < fix_check; i++)
if (n == modify->fix[fixchecklist[i]]->next_reneighbor) return 1;
}
ago++;
if (ago >= delay && ago % every == 0) {
if (build_once) return 0;
if (dist_check == 0) return 1;
return check_distance();
} else return 0;
}
/* ----------------------------------------------------------------------
if any atom moved trigger distance (half of neighbor skin) return 1
shrink trigger distance if box size has changed
conservative shrink procedure:
compute distance each of 8 corners of box has moved since last reneighbor
reduce skin distance by sum of 2 largest of the 8 values
new trigger = 1/2 of reduced skin distance
for orthogonal box, only need 2 lo/hi corners
for triclinic, need all 8 corners since deformations can displace all 8
------------------------------------------------------------------------- */
int Neighbor::check_distance()
{
double delx,dely,delz,rsq;
double delta,deltasq,delta1,delta2;
if (boxcheck) {
if (triclinic == 0) {
delx = bboxlo[0] - boxlo_hold[0];
dely = bboxlo[1] - boxlo_hold[1];
delz = bboxlo[2] - boxlo_hold[2];
delta1 = sqrt(delx*delx + dely*dely + delz*delz);
delx = bboxhi[0] - boxhi_hold[0];
dely = bboxhi[1] - boxhi_hold[1];
delz = bboxhi[2] - boxhi_hold[2];
delta2 = sqrt(delx*delx + dely*dely + delz*delz);
delta = 0.5 * (skin - (delta1+delta2));
deltasq = delta*delta;
} else {
domain->box_corners();
delta1 = delta2 = 0.0;
for (int i = 0; i < 8; i++) {
delx = corners[i][0] - corners_hold[i][0];
dely = corners[i][1] - corners_hold[i][1];
delz = corners[i][2] - corners_hold[i][2];
delta = sqrt(delx*delx + dely*dely + delz*delz);
if (delta > delta1) delta1 = delta;
else if (delta > delta2) delta2 = delta;
}
delta = 0.5 * (skin - (delta1+delta2));
deltasq = delta*delta;
}
} else deltasq = triggersq;
double **x = atom->x;
int nlocal = atom->nlocal;
if (includegroup) nlocal = atom->nfirst;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
delx = x[i][0] - xhold[i][0];
dely = x[i][1] - xhold[i][1];
delz = x[i][2] - xhold[i][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq > deltasq) flag = 1;
}
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world);
if (flagall && ago == MAX(every,delay)) ndanger++;
return flagall;
}
/* ----------------------------------------------------------------------
build all perpetual neighbor lists every few timesteps
pairwise & topology lists are created as needed
------------------------------------------------------------------------- */
void Neighbor::build()
{
int i;
ago = 0;
ncalls++;
// store current atom positions and box size if needed
if (dist_check) {
double **x = atom->x;
int nlocal = atom->nlocal;
if (includegroup) nlocal = atom->nfirst;
if (nlocal > maxhold) {
maxhold = atom->nmax;
memory->destroy(xhold);
memory->create(xhold,maxhold,3,"neigh:xhold");
}
for (i = 0; i < nlocal; i++) {
xhold[i][0] = x[i][0];
xhold[i][1] = x[i][1];
xhold[i][2] = x[i][2];
}
if (boxcheck) {
if (triclinic == 0) {
boxlo_hold[0] = bboxlo[0];
boxlo_hold[1] = bboxlo[1];
boxlo_hold[2] = bboxlo[2];
boxhi_hold[0] = bboxhi[0];
boxhi_hold[1] = bboxhi[1];
boxhi_hold[2] = bboxhi[2];
} else {
domain->box_corners();
corners = domain->corners;
for (i = 0; i < 8; i++) {
corners_hold[i][0] = corners[i][0];
corners_hold[i][1] = corners[i][1];
corners_hold[i][2] = corners[i][2];
}
}
}
}
// if any lists store neighbors of ghosts:
// invoke grow() if nlocal+nghost exceeds previous list size
// else only invoke grow() if nlocal exceeds previous list size
// only done for lists with growflag set and which are perpetual
if (anyghostlist && atom->nlocal+atom->nghost > maxatom) {
maxatom = atom->nmax;
for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom);
} else if (atom->nlocal > maxatom) {
maxatom = atom->nmax;
for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom);
}
// extend atom bin list if necessary
if (style != NSQ && atom->nmax > maxbin) {
maxbin = atom->nmax;
memory->destroy(bins);
memory->create(bins,maxbin,"bins");
}
// check that neighbor list with special bond flags will not overflow
if (atom->nlocal+atom->nghost > NEIGHMASK)
error->one(FLERR,"Too many local+ghost atoms for neighbor list");
// invoke building of pair and molecular neighbor lists
// only for pairwise lists with buildflag set
for (i = 0; i < nblist; i++)
(this->*pair_build[blist[i]])(lists[blist[i]]);
if (atom->molecular) {
if (force->bond) (this->*bond_build)();
if (force->angle) (this->*angle_build)();
if (force->dihedral) (this->*dihedral_build)();
if (force->improper) (this->*improper_build)();
}
}
/* ----------------------------------------------------------------------
build a single occasional pairwise neighbor list indexed by I
called by other classes
------------------------------------------------------------------------- */
void Neighbor::build_one(int i)
{
// update stencils and grow atom arrays and bins as needed
// only for relevant settings of stencilflag and growflag
// grow atom array for this list to current size of perpetual lists
if (lists[i]->stencilflag) {
lists[i]->stencil_allocate(smax,style);
(this->*stencil_create[i])(lists[i],sx,sy,sz);
}
if (lists[i]->growflag) lists[i]->grow(maxatom);
if (style != NSQ && atom->nmax > maxbin) {
maxbin = atom->nmax;
memory->destroy(bins);
memory->create(bins,maxbin,"bins");
}
// check that neighbor list with special bond flags will not overflow
if (atom->nlocal+atom->nghost > NEIGHMASK)
error->one(FLERR,"Too many local+ghost atoms for neighbor list");
// when occasional list built, LAMMPS can crash if atoms have moved too far
// why is this?, give warning if this is the case
// no easy workaround b/c all neighbor lists really need to be rebuilt
// solution is for input script to check more often for rebuild
// only check_distance if running a simulation, not between simulations
int flag = 0;
if (dist_check && update->whichflag) flag = check_distance();
if (flag && me == 0)
error->warning(FLERR,"Building an occasional neighobr list when "
"atoms may have moved too far");
(this->*pair_build[i])(lists[i]);
}
/* ----------------------------------------------------------------------
setup neighbor binning parameters
bin numbering in each dimension is global:
0 = 0.0 to binsize, 1 = binsize to 2*binsize, etc
nbin-1,nbin,etc = bbox-binsize to bbox, bbox to bbox+binsize, etc
-1,-2,etc = -binsize to 0.0, -2*binsize to -binsize, etc
code will work for any binsize
since next(xyz) and stencil extend as far as necessary
binsize = 1/2 of cutoff is roughly optimal
for orthogonal boxes:
a dim must be filled exactly by integer # of bins
in periodic, procs on both sides of PBC must see same bin boundary
in non-periodic, coord2bin() still assumes this by use of nbin xyz
for triclinic boxes:
tilted simulation box cannot contain integer # of bins
stencil & neigh list built differently to account for this
mbinlo = lowest global bin any of my ghost atoms could fall into
mbinhi = highest global bin any of my ghost atoms could fall into
mbin = number of bins I need in a dimension
------------------------------------------------------------------------- */
void Neighbor::setup_bins()
{
// bbox = size of bbox of entire domain
// bsubbox lo/hi = bounding box of my subdomain extended by comm->cutghost
// for triclinic:
// bbox bounds all 8 corners of tilted box
// subdomain is in lamda coords
// include dimension-dependent extension via comm->cutghost
// domain->bbox() converts lamda extent to box coords and computes bbox
double bbox[3],bsubboxlo[3],bsubboxhi[3];
double *cutghost = comm->cutghost;
if (triclinic == 0) {
bsubboxlo[0] = domain->sublo[0] - cutghost[0];
bsubboxlo[1] = domain->sublo[1] - cutghost[1];
bsubboxlo[2] = domain->sublo[2] - cutghost[2];
bsubboxhi[0] = domain->subhi[0] + cutghost[0];
bsubboxhi[1] = domain->subhi[1] + cutghost[1];
bsubboxhi[2] = domain->subhi[2] + cutghost[2];
} else {
double lo[3],hi[3];
lo[0] = domain->sublo_lamda[0] - cutghost[0];
lo[1] = domain->sublo_lamda[1] - cutghost[1];
lo[2] = domain->sublo_lamda[2] - cutghost[2];
hi[0] = domain->subhi_lamda[0] + cutghost[0];
hi[1] = domain->subhi_lamda[1] + cutghost[1];
hi[2] = domain->subhi_lamda[2] + cutghost[2];
domain->bbox(lo,hi,bsubboxlo,bsubboxhi);
}
bbox[0] = bboxhi[0] - bboxlo[0];
bbox[1] = bboxhi[1] - bboxlo[1];
bbox[2] = bboxhi[2] - bboxlo[2];
// optimal bin size is roughly 1/2 the cutoff
// for BIN style, binsize = 1/2 of max neighbor cutoff
// for MULTI style, binsize = 1/2 of min neighbor cutoff
// special case of all cutoffs = 0.0, binsize = box size
double binsize_optimal;
if (binsizeflag) binsize_optimal = binsize_user;
else if (style == BIN) binsize_optimal = 0.5*cutneighmax;
else binsize_optimal = 0.5*cutneighmin;
if (binsize_optimal == 0.0) binsize_optimal = bbox[0];
double binsizeinv = 1.0/binsize_optimal;
// test for too many global bins in any dimension due to huge global domain
if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT ||
bbox[2]*binsizeinv > MAXSMALLINT)
error->all(FLERR,"Domain too large for neighbor bins");
// create actual bins
// always have one bin even if cutoff > bbox
// for 2d, nbinz = 1
nbinx = static_cast<int> (bbox[0]*binsizeinv);
nbiny = static_cast<int> (bbox[1]*binsizeinv);
if (dimension == 3) nbinz = static_cast<int> (bbox[2]*binsizeinv);
else nbinz = 1;
if (nbinx == 0) nbinx = 1;
if (nbiny == 0) nbiny = 1;
if (nbinz == 0) nbinz = 1;
// compute actual bin size for nbins to fit into box exactly
// error if actual bin size << cutoff, since will create a zillion bins
// this happens when nbin = 1 and box size << cutoff
// typically due to non-periodic, flat system in a particular dim
// in that extreme case, should use NSQ not BIN neighbor style
binsizex = bbox[0]/nbinx;
binsizey = bbox[1]/nbiny;
binsizez = bbox[2]/nbinz;
bininvx = 1.0 / binsizex;
bininvy = 1.0 / binsizey;
bininvz = 1.0 / binsizez;
if (binsize_optimal*bininvx > CUT2BIN_RATIO ||
binsize_optimal*bininvy > CUT2BIN_RATIO ||
binsize_optimal*bininvz > CUT2BIN_RATIO)
error->all(FLERR,"Cannot use neighbor bins - box size << cutoff");
// mbinlo/hi = lowest and highest global bins my ghost atoms could be in
// coord = lowest and highest values of coords for my ghost atoms
// static_cast(-1.5) = -1, so subract additional -1
// add in SMALL for round-off safety
int mbinxhi,mbinyhi,mbinzhi;
double coord;
coord = bsubboxlo[0] - SMALL*bbox[0];
mbinxlo = static_cast<int> ((coord-bboxlo[0])*bininvx);
if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1;
coord = bsubboxhi[0] + SMALL*bbox[0];
mbinxhi = static_cast<int> ((coord-bboxlo[0])*bininvx);
coord = bsubboxlo[1] - SMALL*bbox[1];
mbinylo = static_cast<int> ((coord-bboxlo[1])*bininvy);
if (coord < bboxlo[1]) mbinylo = mbinylo - 1;
coord = bsubboxhi[1] + SMALL*bbox[1];
mbinyhi = static_cast<int> ((coord-bboxlo[1])*bininvy);
if (dimension == 3) {
coord = bsubboxlo[2] - SMALL*bbox[2];
mbinzlo = static_cast<int> ((coord-bboxlo[2])*bininvz);
if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1;
coord = bsubboxhi[2] + SMALL*bbox[2];
mbinzhi = static_cast<int> ((coord-bboxlo[2])*bininvz);
}
// extend bins by 1 to insure stencil extent is included
// if 2d, only 1 bin in z
mbinxlo = mbinxlo - 1;
mbinxhi = mbinxhi + 1;
mbinx = mbinxhi - mbinxlo + 1;
mbinylo = mbinylo - 1;
mbinyhi = mbinyhi + 1;
mbiny = mbinyhi - mbinylo + 1;
if (dimension == 3) {
mbinzlo = mbinzlo - 1;
mbinzhi = mbinzhi + 1;
} else mbinzlo = mbinzhi = 0;
mbinz = mbinzhi - mbinzlo + 1;
// memory for bin ptrs
bigint bbin = mbinx*mbiny*mbinz;
if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins");
mbins = bbin;
if (mbins > maxhead) {
maxhead = mbins;
memory->destroy(binhead);
memory->create(binhead,maxhead,"neigh:binhead");
}
// create stencil of bins to search over in neighbor list construction
// sx,sy,sz = max range of stencil in each dim
// smax = max possible size of entire 3d stencil
// stencil is empty if cutneighmax = 0.0
sx = static_cast<int> (cutneighmax*bininvx);
if (sx*binsizex < cutneighmax) sx++;
sy = static_cast<int> (cutneighmax*bininvy);
if (sy*binsizey < cutneighmax) sy++;
sz = static_cast<int> (cutneighmax*bininvz);
if (sz*binsizez < cutneighmax) sz++;
if (dimension == 2) sz = 0;
smax = (2*sx+1) * (2*sy+1) * (2*sz+1);
// create stencils for pairwise neighbor lists
// only done for lists with stencilflag and buildflag set
for (int i = 0; i < nslist; i++) {
lists[slist[i]]->stencil_allocate(smax,style);
(this->*stencil_create[slist[i]])(lists[slist[i]],sx,sy,sz);
}
}
/* ----------------------------------------------------------------------
compute closest distance between central bin (0,0,0) and bin (i,j,k)
------------------------------------------------------------------------- */
double Neighbor::bin_distance(int i, int j, int k)
{
double delx,dely,delz;
if (i > 0) delx = (i-1)*binsizex;
else if (i == 0) delx = 0.0;
else delx = (i+1)*binsizex;
if (j > 0) dely = (j-1)*binsizey;
else if (j == 0) dely = 0.0;
else dely = (j+1)*binsizey;
if (k > 0) delz = (k-1)*binsizez;
else if (k == 0) delz = 0.0;
else delz = (k+1)*binsizez;
return (delx*delx + dely*dely + delz*delz);
}
/* ----------------------------------------------------------------------
set neighbor style and skin distance
------------------------------------------------------------------------- */
void Neighbor::set(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal neighbor command");
skin = atof(arg[0]);
if (skin < 0.0) error->all(FLERR,"Illegal neighbor command");
if (strcmp(arg[1],"nsq") == 0) style = NSQ;
else if (strcmp(arg[1],"bin") == 0) style = BIN;
else if (strcmp(arg[1],"multi") == 0) style = MULTI;
else error->all(FLERR,"Illegal neighbor command");
}
/* ----------------------------------------------------------------------
modify parameters of the pair-wise neighbor build
------------------------------------------------------------------------- */
void Neighbor::modify_params(int narg, char **arg)
{
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"every") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
every = atoi(arg[iarg+1]);
if (every <= 0) error->all(FLERR,"Illegal neigh_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"delay") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
delay = atoi(arg[iarg+1]);
if (delay < 0) error->all(FLERR,"Illegal neigh_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"check") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) dist_check = 1;
else if (strcmp(arg[iarg+1],"no") == 0) dist_check = 0;
else error->all(FLERR,"Illegal neigh_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"once") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) build_once = 1;
else if (strcmp(arg[iarg+1],"no") == 0) build_once = 0;
else error->all(FLERR,"Illegal neigh_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"page") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
pgsize = atoi(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"one") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
oneatom = atoi(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"binsize") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
binsize_user = atof(arg[iarg+1]);
if (binsize_user <= 0.0) binsizeflag = 0;
else binsizeflag = 1;
iarg += 2;
} else if (strcmp(arg[iarg],"include") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
includegroup = group->find(arg[iarg+1]);
if (includegroup < 0)
error->all(FLERR,"Invalid group ID in neigh_modify command");
if (includegroup && (atom->firstgroupname == NULL ||
strcmp(arg[iarg+1],atom->firstgroupname) != 0))
error->all(FLERR,"Neigh_modify include group != atom_modify first group");
iarg += 2;
} else if (strcmp(arg[iarg],"exclude") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (strcmp(arg[iarg+1],"type") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (nex_type == maxex_type) {
maxex_type += EXDELTA;
memory->grow(ex1_type,maxex_type,"neigh:ex1_type");
memory->grow(ex2_type,maxex_type,"neigh:ex2_type");
}
ex1_type[nex_type] = atoi(arg[iarg+2]);
ex2_type[nex_type] = atoi(arg[iarg+3]);
nex_type++;
iarg += 4;
} else if (strcmp(arg[iarg+1],"group") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (nex_group == maxex_group) {
maxex_group += EXDELTA;
memory->grow(ex1_group,maxex_group,"neigh:ex1_group");
memory->grow(ex2_group,maxex_group,"neigh:ex2_group");
}
ex1_group[nex_group] = group->find(arg[iarg+2]);
ex2_group[nex_group] = group->find(arg[iarg+3]);
if (ex1_group[nex_group] == -1 || ex2_group[nex_group] == -1)
error->all(FLERR,"Invalid group ID in neigh_modify command");
nex_group++;
iarg += 4;
} else if (strcmp(arg[iarg+1],"molecule") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal neigh_modify command");
if (atom->molecule_flag == 0) {
char *str = (char *)
"Neigh_modify exclude molecule requires atom attribute molecule";
error->all(FLERR,str);
}
if (nex_mol == maxex_mol) {
maxex_mol += EXDELTA;
memory->grow(ex_mol_group,maxex_mol,"neigh:ex_mol_group");
}
ex_mol_group[nex_mol] = group->find(arg[iarg+2]);
if (ex_mol_group[nex_mol] == -1)
error->all(FLERR,"Invalid group ID in neigh_modify command");
nex_mol++;
iarg += 3;
} else if (strcmp(arg[iarg+1],"none") == 0) {
nex_type = nex_group = nex_mol = 0;
iarg += 2;
} else error->all(FLERR,"Illegal neigh_modify command");
} else error->all(FLERR,"Illegal neigh_modify command");
}
}
/* ----------------------------------------------------------------------
bin owned and ghost atoms
------------------------------------------------------------------------- */
void Neighbor::bin_atoms()
{
int i,ibin;
for (i = 0; i < mbins; i++) binhead[i] = -1;
// bin in reverse order so linked list will be in forward order
// also puts ghost atoms at end of list, which is necessary
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
if (includegroup) {
int bitmask = group->bitmask[includegroup];
for (i = nall-1; i >= nlocal; i--) {
if (mask[i] & bitmask) {
ibin = coord2bin(x[i]);
bins[i] = binhead[ibin];
binhead[ibin] = i;
}
}
for (i = atom->nfirst-1; i >= 0; i--) {
ibin = coord2bin(x[i]);
bins[i] = binhead[ibin];
binhead[ibin] = i;
}
} else {
for (i = nall-1; i >= 0; i--) {
ibin = coord2bin(x[i]);
bins[i] = binhead[ibin];
binhead[ibin] = i;
}
}
}
/* ----------------------------------------------------------------------
convert atom coords into local bin #
for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo
take special care to insure ghosts are in correct bins even w/ roundoff
hi ghost atoms = nbin,nbin+1,etc
owned atoms = 0 to nbin-1
lo ghost atoms = -1,-2,etc
this is necessary so that both procs on either side of PBC
treat a pair of atoms straddling the PBC in a consistent way
for triclinic, doesn't matter since stencil & neigh list built differently
------------------------------------------------------------------------- */
int Neighbor::coord2bin(double *x)
{
int ix,iy,iz;
if (x[0] >= bboxhi[0])
ix = static_cast<int> ((x[0]-bboxhi[0])*bininvx) + nbinx;
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx);
ix = MIN(ix,nbinx-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny;
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy);
iy = MIN(iy,nbiny-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz;
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz);
iz = MIN(iz,nbinz-1);
} else
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz) - 1;
return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo);
}
/* ----------------------------------------------------------------------
same as coord2bin, but also return ix,iy,iz offsets in each dim
------------------------------------------------------------------------- */
int Neighbor::coord2bin(double *x, int &ix, int &iy, int &iz)
{
if (x[0] >= bboxhi[0])
ix = static_cast<int> ((x[0]-bboxhi[0])*bininvx) + nbinx;
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx);
ix = MIN(ix,nbinx-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny;
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy);
iy = MIN(iy,nbiny-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz;
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz);
iz = MIN(iz,nbinz-1);
} else
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz) - 1;
ix -= mbinxlo;
iy -= mbinylo;
iz -= mbinzlo;
return iz*mbiny*mbinx + iy*mbinx + ix;
}
/* ----------------------------------------------------------------------
test if atom pair i,j is excluded from neighbor list
due to type, group, molecule settings from neigh_modify command
return 1 if should be excluded, 0 if included
------------------------------------------------------------------------- */
int Neighbor::exclusion(int i, int j, int itype, int jtype,
int *mask, int *molecule) const {
int m;
if (nex_type && ex_type[itype][jtype]) return 1;
if (nex_group) {
for (m = 0; m < nex_group; m++) {
if (mask[i] & ex1_bit[m] && mask[j] & ex2_bit[m]) return 1;
if (mask[i] & ex2_bit[m] && mask[j] & ex1_bit[m]) return 1;
}
}
if (nex_mol) {
for (m = 0; m < nex_mol; m++)
if (mask[i] & ex_mol_bit[m] && mask[j] & ex_mol_bit[m] &&
molecule[i] == molecule[j]) return 1;
}
return 0;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
------------------------------------------------------------------------- */
bigint Neighbor::memory_usage()
{
bigint bytes = 0;
bytes += memory->usage(xhold,maxhold,3);
if (style != NSQ) {
bytes += memory->usage(bins,maxbin);
bytes += memory->usage(binhead,maxhead);
}
for (int i = 0; i < nlist; i++) bytes += lists[i]->memory_usage();
bytes += memory->usage(bondlist,maxbond,3);
bytes += memory->usage(anglelist,maxangle,4);
bytes += memory->usage(dihedrallist,maxdihedral,5);
bytes += memory->usage(improperlist,maximproper,5);
return bytes;
}
/* ----------------------------------------------------------------------
return the value of exclude - used to check compatibility with GPU
------------------------------------------------------------------------- */
int Neighbor::exclude_setting()
{
return exclude;
}
diff --git a/src/neighbor.h b/src/neighbor.h
index 69a36c81e..898298682 100644
--- a/src/neighbor.h
+++ b/src/neighbor.h
@@ -1,295 +1,301 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_NEIGHBOR_H
#define LMP_NEIGHBOR_H
#include "pointers.h"
namespace LAMMPS_NS {
class Neighbor : protected Pointers {
friend class Cuda;
public:
int style; // 0,1,2 = nsq, bin, multi
int every; // build every this many steps
int delay; // delay build for this many steps
int dist_check; // 0 = always build, 1 = only if 1/2 dist
int ago; // how many steps ago neighboring occurred
int pgsize; // size of neighbor page
int oneatom; // max # of neighbors for one atom
int includegroup; // only build pairwise lists for this group
int build_once; // 1 if only build lists once per run
int cudable; // GPU <-> CPU communication flag for CUDA
double skin; // skin distance
double cutneighmin; // min neighbor cutoff for all type pairs
double cutneighmax; // max neighbor cutoff for all type pairs
double *cuttype; // for each type, max neigh cut w/ others
int ncalls; // # of times build has been called
int ndanger; // # of dangerous builds
int nrequest; // requests for pairwise neighbor lists
class NeighRequest **requests; // from Pair, Fix, Compute, Command classes
int maxrequest;
int old_style; // previous run info to avoid
int old_nrequest; // re-creation of pairwise neighbor lists
int old_triclinic;
class NeighRequest **old_requests;
int nlist; // pairwise neighbor lists
class NeighList **lists;
int nbondlist; // list of bonds to compute
int **bondlist;
int nanglelist; // list of angles to compute
int **anglelist;
int ndihedrallist; // list of dihedrals to compute
int **dihedrallist;
int nimproperlist; // list of impropers to compute
int **improperlist;
Neighbor(class LAMMPS *);
virtual ~Neighbor();
virtual void init();
int request(void *); // another class requests a neighbor list
void print_lists_of_lists(); // debug print out
int decide(); // decide whether to build or not
virtual int check_distance(); // check max distance moved since last build
void setup_bins(); // setup bins based on box and cutoff
virtual void build(); // create all neighbor lists (pair,bond)
void build_one(int); // create a single neighbor list
void set(int, char **); // set neighbor style and skin distance
void modify_params(int, char**); // modify parameters that control builds
bigint memory_usage();
- int exclude_setting(); // Returns 0 if no exclusion list
+ int exclude_setting();
protected:
int me,nprocs;
int maxatom; // size of atom-based NeighList arrays
int maxbond,maxangle,maxdihedral,maximproper; // size of bond lists
int maxwt; // max weighting factor applied + 1
int must_check; // 1 if must check other classes to reneigh
int restart_check; // 1 if restart enabled, 0 if no
int fix_check; // # of fixes that induce reneigh
int *fixchecklist; // which fixes to check
double **cutneighsq; // neighbor cutneigh sq for each type pair
double **cutneighghostsq; // neighbor cutnsq for each ghost type pair
double cutneighmaxsq; // cutneighmax squared
double *cuttypesq; // cuttype squared
double triggersq; // trigger = build when atom moves this dist
double **xhold; // atom coords at last neighbor build
int maxhold; // size of xhold array
int boxcheck; // 1 if need to store box size
double boxlo_hold[3],boxhi_hold[3]; // box size at last neighbor build
double corners_hold[8][3]; // box corners at last neighbor build
int nbinx,nbiny,nbinz; // # of global bins
int *bins; // ptr to next atom in each bin
int maxbin; // size of bins array
int *binhead; // ptr to 1st atom in each bin
int maxhead; // size of binhead array
int mbins; // # of local bins and offset
int mbinx,mbiny,mbinz;
int mbinxlo,mbinylo,mbinzlo;
int binsizeflag; // user-chosen bin size
double binsize_user;
double binsizex,binsizey,binsizez; // actual bin sizes and inverse sizes
double bininvx,bininvy,bininvz;
int sx,sy,sz,smax; // bin stencil extents
int dimension; // 2/3 for 2d/3d
int triclinic; // 0 if domain is orthog, 1 if triclinic
int newton_pair; // 0 if newton off, 1 if on for pairwise
double *bboxlo,*bboxhi; // ptrs to full domain bounding box
double (*corners)[3]; // ptr to 8 corners of triclinic box
double inner[2],middle[2]; // rRESPA cutoffs for extra lists
double cut_inner_sq; // outer cutoff for inner neighbor list
double cut_middle_sq; // outer cutoff for middle neighbor list
double cut_middle_inside_sq; // inner cutoff for middle neighbor list
int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors
int anyghostlist; // 1 if any non-occasional list
// stores neighbors of ghosts
int exclude; // 0 if no type/group exclusions, 1 if yes
int nex_type; // # of entries in type exclusion list
int maxex_type; // max # in type list
int *ex1_type,*ex2_type; // pairs of types to exclude
int **ex_type; // 2d array of excluded type pairs
int nex_group; // # of entries in group exclusion list
int maxex_group; // max # in group list
int *ex1_group,*ex2_group; // pairs of group #'s to exclude
int *ex1_bit,*ex2_bit; // pairs of group bits to exclude
int nex_mol; // # of entries in molecule exclusion list
int maxex_mol; // max # in molecule list
int *ex_mol_group; // molecule group #'s to exclude
int *ex_mol_bit; // molecule group bits to exclude
int nblist,nglist,nslist; // # of pairwise neigh lists of various kinds
int *blist; // lists to build every reneighboring
int *glist; // lists to grow atom arrays every reneigh
int *slist; // lists to grow stencil arrays every reneigh
void bin_atoms(); // bin all atoms
double bin_distance(int, int, int); // distance between binx
int coord2bin(double *); // mapping atom coord to a bin
int coord2bin(double *, int &, int &, int&); // ditto
- int exclusion(int, int, int, int, int *, int *) const; // test for pair exclusion
+ int exclusion(int, int, int,
+ int, int *, int *) const; // test for pair exclusion
+
virtual void choose_build(int, class NeighRequest *);
void choose_stencil(int, class NeighRequest *);
// pairwise build functions
typedef void (Neighbor::*PairPtr)(class NeighList *);
PairPtr *pair_build;
void half_nsq_no_newton(class NeighList *);
void half_nsq_newton(class NeighList *);
void half_bin_no_newton(class NeighList *);
void half_bin_newton(class NeighList *);
void half_bin_newton_tri(class NeighList *);
void half_multi_no_newton(class NeighList *);
void half_multi_newton(class NeighList *);
void half_multi_newton_tri(class NeighList *);
void full_nsq(class NeighList *);
void full_nsq_ghost(class NeighList *);
void full_bin(class NeighList *);
void full_bin_ghost(class NeighList *);
void full_multi(class NeighList *);
void half_from_full_no_newton(class NeighList *);
void half_from_full_newton(class NeighList *);
void skip_from(class NeighList *);
void skip_from_granular(class NeighList *);
void skip_from_respa(class NeighList *);
void copy_from(class NeighList *);
void granular_nsq_no_newton(class NeighList *);
void granular_nsq_newton(class NeighList *);
void granular_bin_no_newton(class NeighList *);
void granular_bin_newton(class NeighList *);
void granular_bin_newton_tri(class NeighList *);
void respa_nsq_no_newton(class NeighList *);
void respa_nsq_newton(class NeighList *);
void respa_bin_no_newton(class NeighList *);
void respa_bin_newton(class NeighList *);
void respa_bin_newton_tri(class NeighList *);
+ // OpenMP multi-threaded neighbor list build versions
+
+#include "accelerator_omp.h"
+
// pairwise stencil creation functions
typedef void (Neighbor::*StencilPtr)(class NeighList *, int, int, int);
StencilPtr *stencil_create;
void stencil_half_bin_2d_no_newton(class NeighList *, int, int, int);
void stencil_half_bin_3d_no_newton(class NeighList *, int, int, int);
void stencil_half_bin_2d_newton(class NeighList *, int, int, int);
void stencil_half_bin_3d_newton(class NeighList *, int, int, int);
void stencil_half_bin_2d_newton_tri(class NeighList *, int, int, int);
void stencil_half_bin_3d_newton_tri(class NeighList *, int, int, int);
void stencil_half_multi_2d_no_newton(class NeighList *, int, int, int);
void stencil_half_multi_3d_no_newton(class NeighList *, int, int, int);
void stencil_half_multi_2d_newton(class NeighList *, int, int, int);
void stencil_half_multi_3d_newton(class NeighList *, int, int, int);
void stencil_half_multi_2d_newton_tri(class NeighList *, int, int, int);
void stencil_half_multi_3d_newton_tri(class NeighList *, int, int, int);
void stencil_full_bin_2d(class NeighList *, int, int, int);
void stencil_full_ghost_bin_2d(class NeighList *, int, int, int);
void stencil_full_bin_3d(class NeighList *, int, int, int);
void stencil_full_ghost_bin_3d(class NeighList *, int, int, int);
void stencil_full_multi_2d(class NeighList *, int, int, int);
void stencil_full_multi_3d(class NeighList *, int, int, int);
// topology build functions
typedef void (Neighbor::*BondPtr)(); // ptrs to topology build functions
BondPtr bond_build; // ptr to bond list functions
void bond_all(); // bond list with all bonds
void bond_partial(); // exclude certain bonds
BondPtr angle_build; // ptr to angle list functions
void angle_all(); // angle list with all angles
void angle_partial(); // exclude certain angles
BondPtr dihedral_build; // ptr to dihedral list functions
void dihedral_all(); // dihedral list with all dihedrals
void dihedral_partial(); // exclude certain dihedrals
BondPtr improper_build; // ptr to improper list functions
void improper_all(); // improper list with all impropers
void improper_partial(); // exclude certain impropers
// find_special: determine if atom j is in special list of atom i
// if it is not, return 0
// if it is and special flag is 0 (both coeffs are 0.0), return -1
// if it is and special flag is 1 (both coeffs are 1.0), return 0
// if it is and special flag is 2 (otherwise), return 1,2,3
// for which neighbor it is (and which coeff it maps to)
inline int find_special(const int *list, const int *nspecial,
const int tag) const {
const int n1 = nspecial[0];
const int n2 = nspecial[1];
const int n3 = nspecial[2];
for (int i = 0; i < n3; i++) {
if (list[i] == tag) {
if (i < n1) {
if (special_flag[1] == 0) return -1;
else if (special_flag[1] == 1) return 0;
else return 1;
} else if (i < n2) {
if (special_flag[2] == 0) return -1;
else if (special_flag[2] == 1) return 0;
else return 2;
} else {
if (special_flag[3] == 0) return -1;
else if (special_flag[3] == 1) return 0;
else return 3;
}
}
}
return 0;
};
};
}
#endif
diff --git a/src/pair.cpp b/src/pair.cpp
index 88e938aea..3f60f9492 100644
--- a/src/pair.cpp
+++ b/src/pair.cpp
@@ -1,1158 +1,1160 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "float.h"
#include "limits.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair.h"
#include "atom.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "update.h"
#include "accelerator_cuda.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER};
enum{R,RSQ,BMP};
/* ---------------------------------------------------------------------- */
Pair::Pair(LAMMPS *lmp) : Pointers(lmp)
{
THIRD = 1.0/3.0;
eng_vdwl = eng_coul = 0.0;
comm_forward = comm_reverse = 0;
single_enable = 1;
restartinfo = 1;
respa_enable = 0;
one_coeff = 0;
no_virial_fdotr_compute = 0;
ghostneigh = 0;
nextra = 0;
pvector = NULL;
+ single_extra = 0;
+ svector = NULL;
// pair_modify settings
offset_flag = 0;
mix_flag = GEOMETRIC;
tail_flag = 0;
etail = ptail = etail_ij = ptail_ij = 0.0;
ncoultablebits = 12;
tabinner = sqrt(2.0);
allocated = 0;
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Pair::~Pair()
{
memory->destroy(eatom);
memory->destroy(vatom);
}
/* ----------------------------------------------------------------------
modify parameters of the pair style
pair_hybrid has its own version of this routine for its sub-styles
------------------------------------------------------------------------- */
void Pair::modify_params(int narg, char **arg)
{
if (narg == 0) error->all(FLERR,"Illegal pair_modify command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"mix") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
if (strcmp(arg[iarg+1],"geometric") == 0) mix_flag = GEOMETRIC;
else if (strcmp(arg[iarg+1],"arithmetic") == 0) mix_flag = ARITHMETIC;
else if (strcmp(arg[iarg+1],"sixthpower") == 0) mix_flag = SIXTHPOWER;
else error->all(FLERR,"Illegal pair_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"shift") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) offset_flag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) offset_flag = 0;
else error->all(FLERR,"Illegal pair_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"table") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
ncoultablebits = atoi(arg[iarg+1]);
if (ncoultablebits > sizeof(float)*CHAR_BIT)
error->all(FLERR,"Too many total bits for bitmapped lookup table");
iarg += 2;
} else if (strcmp(arg[iarg],"tabinner") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
tabinner = atof(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"tail") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal pair_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) tail_flag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) tail_flag = 0;
else error->all(FLERR,"Illegal pair_modify command");
iarg += 2;
} else error->all(FLERR,"Illegal pair_modify command");
}
}
/* ---------------------------------------------------------------------- */
void Pair::init()
{
int i,j;
if (offset_flag && tail_flag)
error->all(FLERR,"Cannot have both pair_modify shift and tail set to yes");
if (tail_flag && domain->dimension == 2)
error->all(FLERR,"Cannot use pair tail corrections with 2d simulations");
if (tail_flag && domain->nonperiodic && comm->me == 0)
error->warning(FLERR,"Using pair tail corrections with nonperiodic system");
if (!allocated) error->all(FLERR,"All pair coeffs are not set");
// I,I coeffs must be set
// init_one() will check if I,J is set explicitly or inferred by mixing
for (i = 1; i <= atom->ntypes; i++)
if (setflag[i][i] == 0) error->all(FLERR,"All pair coeffs are not set");
// style-specific initialization
init_style();
// call init_one() for each I,J
// set cutsq for each I,J, used to neighbor
// cutforce = max of all I,J cutoffs
cutforce = 0.0;
etail = ptail = 0.0;
double cut;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
cut = init_one(i,j);
cutsq[i][j] = cutsq[j][i] = cut*cut;
cutforce = MAX(cutforce,cut);
if (tail_flag) {
etail += etail_ij;
ptail += ptail_ij;
if (i != j) {
etail += etail_ij;
ptail += ptail_ij;
}
}
}
}
/* ----------------------------------------------------------------------
reset all type-based params by invoking init_one() for each I,J
called by fix adapt after it changes one or more params
------------------------------------------------------------------------- */
void Pair::reinit()
{
int i,j;
double tmp;
etail = ptail = 0.0;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
tmp = init_one(i,j);
if (tail_flag) {
etail += etail_ij;
ptail += ptail_ij;
if (i != j) {
etail += etail_ij;
ptail += ptail_ij;
}
}
}
}
/* ----------------------------------------------------------------------
init specific to a pair style
specific pair style can override this function
if needs its own error checks
if needs another kind of neighbor list
request default neighbor list = half list
------------------------------------------------------------------------- */
void Pair::init_style()
{
neighbor->request(this);
}
/* ----------------------------------------------------------------------
neighbor callback to inform pair style of neighbor list to use
specific pair style can override this function
------------------------------------------------------------------------- */
void Pair::init_list(int which, NeighList *ptr)
{
list = ptr;
}
/* ----------------------------------------------------------------------
mixing of pair potential prefactors (epsilon)
------------------------------------------------------------------------- */
double Pair::mix_energy(double eps1, double eps2, double sig1, double sig2)
{
double value;
if (mix_flag == GEOMETRIC)
value = sqrt(eps1*eps2);
else if (mix_flag == ARITHMETIC)
value = sqrt(eps1*eps2);
else if (mix_flag == SIXTHPOWER)
value = 2.0 * sqrt(eps1*eps2) *
pow(sig1,3.0) * pow(sig2,3.0) / (pow(sig1,6.0) + pow(sig2,6.0));
return value;
}
/* ----------------------------------------------------------------------
mixing of pair potential distances (sigma, cutoff)
------------------------------------------------------------------------- */
double Pair::mix_distance(double sig1, double sig2)
{
double value;
if (mix_flag == GEOMETRIC)
value = sqrt(sig1*sig2);
else if (mix_flag == ARITHMETIC)
value = 0.5 * (sig1+sig2);
else if (mix_flag == SIXTHPOWER)
value = pow((0.5 * (pow(sig1,6.0) + pow(sig2,6.0))),1.0/6.0);
return value;
}
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Pair::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->destroy(eatom);
memory->create(eatom,comm->nthreads*maxeatom,"pair:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy(vatom);
memory->create(vatom,comm->nthreads*maxvatom,6,"pair:vatom");
}
// zero accumulators
// use force->newton instead of newton_pair
// b/c some bonds/dihedrals call pair::ev_tally with pairwise info
if (eflag_global) eng_vdwl = eng_coul = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
// if vflag_global = 2 and pair::compute() calls virial_fdotr_compute()
// compute global virial via (F dot r) instead of via pairwise summation
// unset other flags as appropriate
if (vflag_global == 2 && no_virial_fdotr_compute == 0) {
vflag_fdotr = 1;
vflag_global = 0;
if (vflag_atom == 0) vflag_either = 0;
if (vflag_either == 0 && eflag_either == 0) evflag = 0;
} else vflag_fdotr = 0;
if (lmp->cuda) lmp->cuda->evsetup_eatom_vatom(eflag_atom,vflag_atom);
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
need i < nlocal test since called by bond_quartic and dihedral_charmm
------------------------------------------------------------------------- */
void Pair::ev_tally(int i, int j, int nlocal, int newton_pair,
double evdwl, double ecoul, double fpair,
double delx, double dely, double delz)
{
double evdwlhalf,ecoulhalf,epairhalf,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_pair) {
eng_vdwl += evdwl;
eng_coul += ecoul;
} else {
evdwlhalf = 0.5*evdwl;
ecoulhalf = 0.5*ecoul;
if (i < nlocal) {
eng_vdwl += evdwlhalf;
eng_coul += ecoulhalf;
}
if (j < nlocal) {
eng_vdwl += evdwlhalf;
eng_coul += ecoulhalf;
}
}
}
if (eflag_atom) {
epairhalf = 0.5 * (evdwl + ecoul);
if (newton_pair || i < nlocal) eatom[i] += epairhalf;
if (newton_pair || j < nlocal) eatom[j] += epairhalf;
}
}
if (vflag_either) {
v[0] = delx*delx*fpair;
v[1] = dely*dely*fpair;
v[2] = delz*delz*fpair;
v[3] = delx*dely*fpair;
v[4] = delx*delz*fpair;
v[5] = dely*delz*fpair;
if (vflag_global) {
if (newton_pair) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_pair || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_pair || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
can use this version with full neighbor lists
------------------------------------------------------------------------- */
void Pair::ev_tally_full(int i, double evdwl, double ecoul, double fpair,
double delx, double dely, double delz)
{
double v[6];
if (eflag_either) {
if (eflag_global) {
eng_vdwl += 0.5*evdwl;
eng_coul += 0.5*ecoul;
}
if (eflag_atom) eatom[i] += 0.5 * (evdwl + ecoul);
}
if (vflag_either) {
v[0] = 0.5*delx*delx*fpair;
v[1] = 0.5*dely*dely*fpair;
v[2] = 0.5*delz*delz*fpair;
v[3] = 0.5*delx*dely*fpair;
v[4] = 0.5*delx*delz*fpair;
v[5] = 0.5*dely*delz*fpair;
if (vflag_global) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
}
if (vflag_atom) {
vatom[i][0] += v[0];
vatom[i][1] += v[1];
vatom[i][2] += v[2];
vatom[i][3] += v[3];
vatom[i][4] += v[4];
vatom[i][5] += v[5];
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
for virial, have delx,dely,delz and fx,fy,fz
------------------------------------------------------------------------- */
void Pair::ev_tally_xyz(int i, int j, int nlocal, int newton_pair,
double evdwl, double ecoul,
double fx, double fy, double fz,
double delx, double dely, double delz)
{
double evdwlhalf,ecoulhalf,epairhalf,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_pair) {
eng_vdwl += evdwl;
eng_coul += ecoul;
} else {
evdwlhalf = 0.5*evdwl;
ecoulhalf = 0.5*ecoul;
if (i < nlocal) {
eng_vdwl += evdwlhalf;
eng_coul += ecoulhalf;
}
if (j < nlocal) {
eng_vdwl += evdwlhalf;
eng_coul += ecoulhalf;
}
}
}
if (eflag_atom) {
epairhalf = 0.5 * (evdwl + ecoul);
if (newton_pair || i < nlocal) eatom[i] += epairhalf;
if (newton_pair || j < nlocal) eatom[j] += epairhalf;
}
}
if (vflag_either) {
v[0] = delx*fx;
v[1] = dely*fy;
v[2] = delz*fz;
v[3] = delx*fy;
v[4] = delx*fz;
v[5] = dely*fz;
if (vflag_global) {
if (newton_pair) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_pair || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_pair || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
for virial, have delx,dely,delz and fx,fy,fz
called when using full neighbor lists
------------------------------------------------------------------------- */
void Pair::ev_tally_xyz_full(int i, double evdwl, double ecoul,
double fx, double fy, double fz,
double delx, double dely, double delz)
{
double evdwlhalf,ecoulhalf,epairhalf,v[6];
if (eflag_either) {
if (eflag_global) {
evdwlhalf = 0.5*evdwl;
ecoulhalf = 0.5*ecoul;
eng_vdwl += evdwlhalf;
eng_coul += ecoulhalf;
}
if (eflag_atom) {
epairhalf = 0.5 * (evdwl + ecoul);
eatom[i] += epairhalf;
}
}
if (vflag_either) {
v[0] = 0.5*delx*fx;
v[1] = 0.5*dely*fy;
v[2] = 0.5*delz*fz;
v[3] = 0.5*delx*fy;
v[4] = 0.5*delx*fz;
v[5] = 0.5*dely*fz;
if (vflag_global) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
}
if (vflag_atom) {
vatom[i][0] += v[0];
vatom[i][1] += v[1];
vatom[i][2] += v[2];
vatom[i][3] += v[3];
vatom[i][4] += v[4];
vatom[i][5] += v[5];
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
called by SW and hbond potentials, newton_pair is always on
virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk
------------------------------------------------------------------------- */
void Pair::ev_tally3(int i, int j, int k, double evdwl, double ecoul,
double *fj, double *fk, double *drji, double *drki)
{
double epairthird,v[6];
if (eflag_either) {
if (eflag_global) {
eng_vdwl += evdwl;
eng_coul += ecoul;
}
if (eflag_atom) {
epairthird = THIRD * (evdwl + ecoul);
eatom[i] += epairthird;
eatom[j] += epairthird;
eatom[k] += epairthird;
}
}
if (vflag_either) {
v[0] = drji[0]*fj[0] + drki[0]*fk[0];
v[1] = drji[1]*fj[1] + drki[1]*fk[1];
v[2] = drji[2]*fj[2] + drki[2]*fk[2];
v[3] = drji[0]*fj[1] + drki[0]*fk[1];
v[4] = drji[0]*fj[2] + drki[0]*fk[2];
v[5] = drji[1]*fj[2] + drki[1]*fk[2];
if (vflag_global) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
}
if (vflag_atom) {
vatom[i][0] += THIRD*v[0]; vatom[i][1] += THIRD*v[1];
vatom[i][2] += THIRD*v[2]; vatom[i][3] += THIRD*v[3];
vatom[i][4] += THIRD*v[4]; vatom[i][5] += THIRD*v[5];
vatom[j][0] += THIRD*v[0]; vatom[j][1] += THIRD*v[1];
vatom[j][2] += THIRD*v[2]; vatom[j][3] += THIRD*v[3];
vatom[j][4] += THIRD*v[4]; vatom[j][5] += THIRD*v[5];
vatom[k][0] += THIRD*v[0]; vatom[k][1] += THIRD*v[1];
vatom[k][2] += THIRD*v[2]; vatom[k][3] += THIRD*v[3];
vatom[k][4] += THIRD*v[4]; vatom[k][5] += THIRD*v[5];
}
}
}
/* ----------------------------------------------------------------------
tally eng_vdwl and virial into global and per-atom accumulators
called by AIREBO potential, newton_pair is always on
------------------------------------------------------------------------- */
void Pair::ev_tally4(int i, int j, int k, int m, double evdwl,
double *fi, double *fj, double *fk,
double *drim, double *drjm, double *drkm)
{
double epairfourth,v[6];
if (eflag_either) {
if (eflag_global) eng_vdwl += evdwl;
if (eflag_atom) {
epairfourth = 0.25 * evdwl;
eatom[i] += epairfourth;
eatom[j] += epairfourth;
eatom[k] += epairfourth;
eatom[m] += epairfourth;
}
}
if (vflag_atom) {
v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2];
vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5];
vatom[j][0] += v[0]; vatom[j][1] += v[1]; vatom[j][2] += v[2];
vatom[j][3] += v[3]; vatom[j][4] += v[4]; vatom[j][5] += v[5];
vatom[k][0] += v[0]; vatom[k][1] += v[1]; vatom[k][2] += v[2];
vatom[k][3] += v[3]; vatom[k][4] += v[4]; vatom[k][5] += v[5];
vatom[m][0] += v[0]; vatom[m][1] += v[1]; vatom[m][2] += v[2];
vatom[m][3] += v[3]; vatom[m][4] += v[4]; vatom[m][5] += v[5];
}
}
/* ----------------------------------------------------------------------
tally ecoul and virial into each of n atoms in list
called by TIP4P potential, newton_pair is always on
changes v values by dividing by n
------------------------------------------------------------------------- */
void Pair::ev_tally_list(int n, int *list, double ecoul, double *v)
{
int i,j;
if (eflag_either) {
if (eflag_global) eng_coul += ecoul;
if (eflag_atom) {
double epairatom = ecoul/n;
for (i = 0; i < n; i++) eatom[list[i]] += epairatom;
}
}
if (vflag_either) {
if (vflag_global) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
}
if (vflag_atom) {
v[0] /= n;
v[1] /= n;
v[2] /= n;
v[3] /= n;
v[4] /= n;
v[5] /= n;
for (i = 0; i < n; i++) {
j = list[i];
vatom[j][0] += v[0];
vatom[j][1] += v[1];
vatom[j][2] += v[2];
vatom[j][3] += v[3];
vatom[j][4] += v[4];
vatom[j][5] += v[5];
}
}
}
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by REAX/C potential, newton_pair is always on
fi is magnitude of force on atom i
------------------------------------------------------------------------- */
void Pair::v_tally(int i, double *fi)
{
double v[6];
double **x = atom->x;
v[0] = x[i][0]*fi[0];
v[1] = x[i][1]*fi[1];
v[2] = x[i][2]*fi[2];
v[3] = x[i][0]*fi[1];
v[4] = x[i][0]*fi[1];
v[5] = x[i][1]*fi[2];
vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2];
vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5];
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO potential, newton_pair is always on
fpair is magnitude of force on atom I
------------------------------------------------------------------------- */
void Pair::v_tally2(int i, int j, double fpair, double *drij)
{
double v[6];
v[0] = 0.5 * drij[0]*drij[0]*fpair;
v[1] = 0.5 * drij[1]*drij[1]*fpair;
v[2] = 0.5 * drij[2]*drij[2]*fpair;
v[3] = 0.5 * drij[0]*drij[1]*fpair;
v[4] = 0.5 * drij[0]*drij[2]*fpair;
v[5] = 0.5 * drij[1]*drij[2]*fpair;
vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2];
vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5];
vatom[j][0] += v[0]; vatom[j][1] += v[1]; vatom[j][2] += v[2];
vatom[j][3] += v[3]; vatom[j][4] += v[4]; vatom[j][5] += v[5];
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO and Tersoff potential, newton_pair is always on
------------------------------------------------------------------------- */
void Pair::v_tally3(int i, int j, int k,
double *fi, double *fj, double *drik, double *drjk)
{
double v[6];
v[0] = THIRD * (drik[0]*fi[0] + drjk[0]*fj[0]);
v[1] = THIRD * (drik[1]*fi[1] + drjk[1]*fj[1]);
v[2] = THIRD * (drik[2]*fi[2] + drjk[2]*fj[2]);
v[3] = THIRD * (drik[0]*fi[1] + drjk[0]*fj[1]);
v[4] = THIRD * (drik[0]*fi[2] + drjk[0]*fj[2]);
v[5] = THIRD * (drik[1]*fi[2] + drjk[1]*fj[2]);
vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2];
vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5];
vatom[j][0] += v[0]; vatom[j][1] += v[1]; vatom[j][2] += v[2];
vatom[j][3] += v[3]; vatom[j][4] += v[4]; vatom[j][5] += v[5];
vatom[k][0] += v[0]; vatom[k][1] += v[1]; vatom[k][2] += v[2];
vatom[k][3] += v[3]; vatom[k][4] += v[4]; vatom[k][5] += v[5];
}
/* ----------------------------------------------------------------------
tally virial into per-atom accumulators
called by AIREBO potential, newton_pair is always on
------------------------------------------------------------------------- */
void Pair::v_tally4(int i, int j, int k, int m,
double *fi, double *fj, double *fk,
double *drim, double *drjm, double *drkm)
{
double v[6];
v[0] = 0.25 * (drim[0]*fi[0] + drjm[0]*fj[0] + drkm[0]*fk[0]);
v[1] = 0.25 * (drim[1]*fi[1] + drjm[1]*fj[1] + drkm[1]*fk[1]);
v[2] = 0.25 * (drim[2]*fi[2] + drjm[2]*fj[2] + drkm[2]*fk[2]);
v[3] = 0.25 * (drim[0]*fi[1] + drjm[0]*fj[1] + drkm[0]*fk[1]);
v[4] = 0.25 * (drim[0]*fi[2] + drjm[0]*fj[2] + drkm[0]*fk[2]);
v[5] = 0.25 * (drim[1]*fi[2] + drjm[1]*fj[2] + drkm[1]*fk[2]);
vatom[i][0] += v[0]; vatom[i][1] += v[1]; vatom[i][2] += v[2];
vatom[i][3] += v[3]; vatom[i][4] += v[4]; vatom[i][5] += v[5];
vatom[j][0] += v[0]; vatom[j][1] += v[1]; vatom[j][2] += v[2];
vatom[j][3] += v[3]; vatom[j][4] += v[4]; vatom[j][5] += v[5];
vatom[k][0] += v[0]; vatom[k][1] += v[1]; vatom[k][2] += v[2];
vatom[k][3] += v[3]; vatom[k][4] += v[4]; vatom[k][5] += v[5];
vatom[m][0] += v[0]; vatom[m][1] += v[1]; vatom[m][2] += v[2];
vatom[m][3] += v[3]; vatom[m][4] += v[4]; vatom[m][5] += v[5];
}
/* ----------------------------------------------------------------------
tally virial into global and per-atom accumulators
called by pair lubricate potential with 6 tensor components
------------------------------------------------------------------------- */
void Pair::v_tally_tensor(int i, int j, int nlocal, int newton_pair,
double vxx, double vyy, double vzz,
double vxy, double vxz, double vyz)
{
double v[6];
v[0] = vxx;
v[1] = vyy;
v[2] = vzz;
v[3] = vxy;
v[4] = vxz;
v[5] = vyz;
if (vflag_global) {
if (newton_pair) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_pair || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_pair || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
/* ----------------------------------------------------------------------
compute global pair virial via summing F dot r over own & ghost atoms
at this point, only pairwise forces have been accumulated in atom->f
------------------------------------------------------------------------- */
void Pair::virial_fdotr_compute()
{
double **x = atom->x;
double **f = atom->f;
// sum over force on all particles including ghosts
if (neighbor->includegroup == 0) {
int nall = atom->nlocal + atom->nghost;
for (int i = 0; i < nall; i++) {
virial[0] += f[i][0]*x[i][0];
virial[1] += f[i][1]*x[i][1];
virial[2] += f[i][2]*x[i][2];
virial[3] += f[i][1]*x[i][0];
virial[4] += f[i][2]*x[i][0];
virial[5] += f[i][2]*x[i][1];
}
// neighbor includegroup flag is set
// sum over force on initial nfirst particles and ghosts
} else {
int nall = atom->nfirst;
for (int i = 0; i < nall; i++) {
virial[0] += f[i][0]*x[i][0];
virial[1] += f[i][1]*x[i][1];
virial[2] += f[i][2]*x[i][2];
virial[3] += f[i][1]*x[i][0];
virial[4] += f[i][2]*x[i][0];
virial[5] += f[i][2]*x[i][1];
}
nall = atom->nlocal + atom->nghost;
for (int i = atom->nlocal; i < nall; i++) {
virial[0] += f[i][0]*x[i][0];
virial[1] += f[i][1]*x[i][1];
virial[2] += f[i][2]*x[i][2];
virial[3] += f[i][1]*x[i][0];
virial[4] += f[i][2]*x[i][0];
virial[5] += f[i][2]*x[i][1];
}
}
}
/* ----------------------------------------------------------------------
write a table of pair potential energy/force vs distance to a file
------------------------------------------------------------------------- */
void Pair::write_file(int narg, char **arg)
{
if (narg < 8) error->all(FLERR,"Illegal pair_write command");
if (single_enable == 0) error->all(FLERR,"Pair style does not support pair_write");
// parse arguments
int itype = atoi(arg[0]);
int jtype = atoi(arg[1]);
if (itype < 1 || itype > atom->ntypes || jtype < 1 || jtype > atom->ntypes)
error->all(FLERR,"Invalid atom types in pair_write command");
int n = atoi(arg[2]);
int style;
if (strcmp(arg[3],"r") == 0) style = R;
else if (strcmp(arg[3],"rsq") == 0) style = RSQ;
else if (strcmp(arg[3],"bitmap") == 0) style = BMP;
else error->all(FLERR,"Invalid style in pair_write command");
double inner = atof(arg[4]);
double outer = atof(arg[5]);
if (inner <= 0.0 || inner >= outer)
error->all(FLERR,"Invalid cutoffs in pair_write command");
// open file in append mode
// print header in format used by pair_style table
int me;
MPI_Comm_rank(world,&me);
FILE *fp;
if (me == 0) {
fp = fopen(arg[6],"a");
if (fp == NULL) error->one(FLERR,"Cannot open pair_write file");
fprintf(fp,"# Pair potential %s for atom types %d %d: i,r,energy,force\n",
force->pair_style,itype,jtype);
if (style == R)
fprintf(fp,"\n%s\nN %d R %g %g\n\n",arg[7],n,inner,outer);
if (style == RSQ)
fprintf(fp,"\n%s\nN %d RSQ %g %g\n\n",arg[7],n,inner,outer);
}
// initialize potentials before evaluating pair potential
// insures all pair coeffs are set and force constants
force->init();
// if pair style = any of EAM, swap in dummy fp vector
double eamfp[2];
eamfp[0] = eamfp[1] = 0.0;
double *eamfp_hold;
Pair *epair = force->pair_match("eam",0);
if (epair) epair->swap_eam(eamfp,&eamfp_hold);
// if atom style defines charge, swap in dummy q vec
double q[2];
q[0] = q[1] = 1.0;
if (narg == 10) {
q[0] = atof(arg[8]);
q[1] = atof(arg[9]);
}
double *q_hold;
if (atom->q) {
q_hold = atom->q;
atom->q = q;
}
// evaluate energy and force at each of N distances
int masklo,maskhi,nmask,nshiftbits;
if (style == BMP) {
init_bitmap(inner,outer,n,masklo,maskhi,nmask,nshiftbits);
int ntable = 1 << n;
if (me == 0)
fprintf(fp,"\n%s\nN %d BITMAP %g %g\n\n",arg[7],ntable,inner,outer);
n = ntable;
}
double r,e,f,rsq;
union_int_float_t rsq_lookup;
for (int i = 0; i < n; i++) {
if (style == R) {
r = inner + (outer-inner) * i/(n-1);
rsq = r*r;
} else if (style == RSQ) {
rsq = inner*inner + (outer*outer - inner*inner) * i/(n-1);
r = sqrt(rsq);
} else if (style == BMP) {
rsq_lookup.i = i << nshiftbits;
rsq_lookup.i |= masklo;
if (rsq_lookup.f < inner*inner) {
rsq_lookup.i = i << nshiftbits;
rsq_lookup.i |= maskhi;
}
rsq = rsq_lookup.f;
r = sqrt(rsq);
}
if (rsq < cutsq[itype][jtype]) {
e = single(0,1,itype,jtype,rsq,1.0,1.0,f);
f *= r;
} else e = f = 0.0;
if (me == 0) fprintf(fp,"%d %g %g %g\n",i+1,r,e,f);
}
// restore original vecs that were swapped in for
double *tmp;
if (epair) epair->swap_eam(eamfp_hold,&tmp);
if (atom->q) atom->q = q_hold;
if (me == 0) fclose(fp);
}
/* ----------------------------------------------------------------------
define bitmap parameters based on inner and outer cutoffs
------------------------------------------------------------------------- */
void Pair::init_bitmap(double inner, double outer, int ntablebits,
int &masklo, int &maskhi, int &nmask, int &nshiftbits)
{
if (sizeof(int) != sizeof(float))
error->all(FLERR,"Bitmapped lookup tables require int/float be same size");
if (ntablebits > sizeof(float)*CHAR_BIT)
error->all(FLERR,"Too many total bits for bitmapped lookup table");
if (inner >= outer) error->warning(FLERR,"Table inner cutoff >= outer cutoff");
int nlowermin = 1;
while (!((pow(double(2),nlowermin) <= inner*inner) &&
(pow(double(2),nlowermin+1) > inner*inner))) {
if (pow(double(2),nlowermin) <= inner*inner) nlowermin++;
else nlowermin--;
}
int nexpbits = 0;
double required_range = outer*outer / pow(double(2),nlowermin);
double available_range = 2.0;
while (available_range < required_range) {
nexpbits++;
available_range = pow(double(2),pow(double(2),nexpbits));
}
int nmantbits = ntablebits - nexpbits;
if (nexpbits > sizeof(float)*CHAR_BIT - FLT_MANT_DIG)
error->all(FLERR,"Too many exponent bits for lookup table");
if (nmantbits+1 > FLT_MANT_DIG)
error->all(FLERR,"Too many mantissa bits for lookup table");
if (nmantbits < 3) error->all(FLERR,"Too few bits for lookup table");
nshiftbits = FLT_MANT_DIG - (nmantbits+1);
nmask = 1;
for (int j = 0; j < ntablebits+nshiftbits; j++) nmask *= 2;
nmask -= 1;
union_int_float_t rsq_lookup;
rsq_lookup.f = outer*outer;
maskhi = rsq_lookup.i & ~(nmask);
rsq_lookup.f = inner*inner;
masklo = rsq_lookup.i & ~(nmask);
}
/* ---------------------------------------------------------------------- */
double Pair::memory_usage()
{
double bytes = comm->nthreads*maxeatom * sizeof(double);
bytes += comm->nthreads*maxvatom*6 * sizeof(double);
return bytes;
}
diff --git a/src/pair.h b/src/pair.h
index 6a88af5e0..ed64c43e4 100644
--- a/src/pair.h
+++ b/src/pair.h
@@ -1,167 +1,172 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_PAIR_H
#define LMP_PAIR_H
#include "pointers.h"
namespace LAMMPS_NS {
class Pair : protected Pointers {
+ friend class AngleSDK;
+ friend class AngleSDKOMP;
friend class BondQuartic;
friend class BondQuarticOMP;
friend class DihedralCharmm;
friend class DihedralCharmmOMP;
friend class FixGPU;
friend class ThrOMP;
public:
double eng_vdwl,eng_coul; // accumulated energies
double virial[6]; // accumulated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
double cutforce; // max cutoff for all atom pairs
double **cutsq; // cutoff sq for each atom pair
int **setflag; // 0/1 = whether each i,j has been set
int comm_forward; // size of forward communication (0 if none)
int comm_reverse; // size of reverse communication (0 if none)
int single_enable; // 1 if single() routine exists
int restartinfo; // 1 if pair style writes restart info
int respa_enable; // 1 if inner/middle/outer rRESPA routines
int one_coeff; // 1 if allows only one coeff * * call
int no_virial_fdotr_compute; // 1 if does not invoke virial_fdotr_compute()
int ghostneigh; // 1 if pair style needs neighbors of ghosts
double **cutghost; // cutoff for each ghost pair
int tail_flag; // pair_modify flag for LJ tail correction
double etail,ptail; // energy/pressure tail corrections
double etail_ij,ptail_ij;
int nextra; // # of extra quantities pair style calculates
double *pvector; // vector of extra pair quantities
+ int single_extra; // number of extra single values calculated
+ double *svector; // vector of extra single quantities
+
class NeighList *list; // standard neighbor list used by most pairs
class NeighList *listhalf; // half list used by some pairs
class NeighList *listfull; // full list used by some pairs
class NeighList *listgranhistory; // granular history list used by some pairs
class NeighList *listinner; // rRESPA lists used by some pairs
class NeighList *listmiddle;
class NeighList *listouter;
Pair(class LAMMPS *);
virtual ~Pair();
// top-level Pair methods
void init();
void reinit();
double mix_energy(double, double, double, double);
double mix_distance(double, double);
void write_file(int, char **);
void init_bitmap(double, double, int, int &, int &, int &, int &);
virtual void modify_params(int, char **);
// need to be public, so can be called by pair_style reaxc
void v_tally(int, double *);
void ev_tally(int, int, int, int, double, double, double,
double, double, double);
void ev_tally3(int, int, int, double, double,
double *, double *, double *, double *);
void v_tally3(int, int, int, double *, double *, double *, double *);
void v_tally4(int, int, int, int, double *, double *, double *,
double *, double *, double *);
// general child-class methods
virtual void compute(int, int) = 0;
virtual void compute_inner() {}
virtual void compute_middle() {}
virtual void compute_outer(int, int) {}
virtual double single(int, int, int, int,
double, double, double, double &) {return 0.0;}
virtual void settings(int, char **) = 0;
virtual void coeff(int, char **) = 0;
virtual void init_style();
virtual void init_list(int, class NeighList *);
virtual double init_one(int, int) {return 0.0;}
virtual void write_restart(FILE *) {}
virtual void read_restart(FILE *) {}
virtual void write_restart_settings(FILE *) {}
virtual void read_restart_settings(FILE *) {}
virtual int pack_comm(int, int *, double *, int, int *) {return 0;}
virtual void unpack_comm(int, int, double *) {}
virtual int pack_reverse_comm(int, int, double *) {return 0;}
virtual void unpack_reverse_comm(int, int *, double *) {}
virtual double memory_usage();
// specific child-class methods for certain Pair styles
virtual void *extract(char *, int &) {return NULL;}
virtual void swap_eam(double *, double **) {}
virtual void reset_dt() {}
virtual void min_xf_pointers(int, double **, double **) {}
virtual void min_xf_get(int) {}
virtual void min_x_set(int) {}
protected:
int allocated; // 0/1 = whether arrays are allocated
// pair_modify settings
int offset_flag,mix_flag; // flags for offset and mixing
int ncoultablebits; // size of Coulomb table
double tabinner; // inner cutoff for Coulomb table
// custom data type for accessing Coulomb tables
typedef union {int i; float f;} union_int_float_t;
double THIRD;
int evflag; // energy,virial settings
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int vflag_fdotr;
int maxeatom,maxvatom;
virtual void ev_setup(int, int);
void ev_tally_full(int, double, double, double, double, double, double);
void ev_tally_xyz(int, int, int, int, double, double,
double, double, double, double, double, double);
void ev_tally_xyz_full(int, double, double,
double, double, double, double, double, double);
void ev_tally4(int, int, int, int, double,
double *, double *, double *, double *, double *, double *);
void ev_tally_list(int, int *, double, double *);
void v_tally2(int, int, double, double *);
void v_tally_tensor(int, int, int, int,
double, double, double, double, double, double);
void virial_fdotr_compute();
inline int sbmask(int j) {
return j >> SBBITS & 3;
}
};
}
#endif
diff --git a/src/pair_born_coul_wolf.cpp b/src/pair_born_coul_wolf.cpp
new file mode 100644
index 000000000..647c6bdaf
--- /dev/null
+++ b/src/pair_born_coul_wolf.cpp
@@ -0,0 +1,470 @@
+/* ----------------------------------------------------------------------
+ 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: Yongfeng Zhang (INL), yongfeng.zhang@inl.gov
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_born_coul_wolf.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+/* ---------------------------------------------------------------------- */
+
+PairBornCoulWolf::PairBornCoulWolf(LAMMPS *lmp) : Pair(lmp) {}
+
+/* ---------------------------------------------------------------------- */
+
+PairBornCoulWolf::~PairBornCoulWolf()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut_lj);
+ memory->destroy(cut_ljsq);
+ memory->destroy(a);
+ memory->destroy(rho);
+ memory->destroy(sigma);
+ memory->destroy(c);
+ memory->destroy(d);
+ memory->destroy(rhoinv);
+ memory->destroy(born1);
+ memory->destroy(born2);
+ memory->destroy(born3);
+ memory->destroy(offset);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBornCoulWolf::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
+ double rsq,r2inv,r6inv,forcecoul,forceborn,factor_coul,factor_lj;
+ double prefactor;
+ double r,rexp;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double erfcc,erfcd,v_sh,dvdrr,e_self,qisq;
+
+ evdwl = ecoul = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ double *special_coul = force->special_coul;
+ double *special_lj = force->special_lj;
+ int newton_pair = force->newton_pair;
+ double qqrd2e = force->qqrd2e;
+
+ // self and shifted coulombic energy
+
+ e_self = v_sh = 0.0;
+ e_shift = erfc(alf*cut_coul)/cut_coul;
+ f_shift = -(e_shift+ 2.0*alf/MY_PIS * exp(-alf*alf*cut_coul*cut_coul)) /
+ cut_coul;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ qisq = qtmp*qtmp;
+ e_self = -(e_shift/2.0 + alf/MY_PIS) * qisq*qqrd2e;
+ if (evflag) ev_tally(i,i,nlocal,0,0.0,e_self,0.0,0.0,0.0,0.0);
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+
+ if (j < nall) factor_coul = factor_lj = 1.0;
+ else {
+ factor_coul = special_coul[j/nall];
+ factor_lj = special_lj[j/nall];
+ j %= nall;
+ }
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ r2inv = 1.0/rsq;
+
+ if (rsq < cut_coulsq) {
+ r = sqrt(rsq);
+ prefactor = qqrd2e*qtmp*q[j]/r;
+ erfcc = erfc(alf*r);
+ erfcd = exp(-alf*alf*r*r);
+ v_sh = (erfcc - e_shift*r) * prefactor;
+ dvdrr = (erfcc/rsq + 2.0*alf/MY_PIS * erfcd/r) + f_shift;
+ forcecoul = dvdrr*rsq*prefactor;
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ r = sqrt(rsq);
+ rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
+ forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ + born3[itype][jtype]*r2inv*r6inv;
+ } else forceborn = 0.0;
+
+ fpair = (forcecoul + factor_lj*forceborn) * r2inv;
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (eflag) {
+ if (rsq < cut_coulsq) {
+ ecoul = v_sh;
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+ if (rsq < cut_ljsq[itype][jtype]) {
+ evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv +
+ d[itype][jtype]*r6inv*r2inv - offset[itype][jtype];
+ evdwl *= factor_lj;
+ } else evdwl = 0.0;
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ evdwl,ecoul,fpair,delx,dely,delz);
+ }
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+
+ memory->create(cut_lj,n+1,n+1,"pair:cut_lj");
+ memory->create(cut_ljsq,n+1,n+1,"pair:cut_ljsq");
+ memory->create(a,n+1,n+1,"pair:a");
+ memory->create(rho,n+1,n+1,"pair:rho");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(c,n+1,n+1,"pair:c");
+ memory->create(d,n+1,n+1,"pair:d");
+ memory->create(rhoinv,n+1,n+1,"pair:rhoinv");
+ memory->create(born1,n+1,n+1,"pair:born1");
+ memory->create(born2,n+1,n+1,"pair:born2");
+ memory->create(born3,n+1,n+1,"pair:born3");
+ memory->create(offset,n+1,n+1,"pair:offset");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::settings(int narg, char **arg)
+{
+ if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command");
+
+ alf = force->numeric(arg[0]);
+ cut_lj_global = force->numeric(arg[1]);
+ if (narg == 2) cut_coul = cut_lj_global;
+ else cut_coul = force->numeric(arg[2]);
+
+ if (allocated) {
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i+1; j <= atom->ntypes; j++)
+ if (setflag[i][j]) cut_lj[i][j] = cut_lj_global;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::coeff(int narg, char **arg)
+{
+ if (narg < 7 || narg > 8)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ double a_one = force->numeric(arg[2]);
+ double rho_one = force->numeric(arg[3]);
+ double sigma_one = force->numeric(arg[4]);
+ if (rho_one <= 0) error->all(FLERR,"Incorrect args for pair coefficients");
+ double c_one = force->numeric(arg[5]);
+ double d_one = force->numeric(arg[6]);
+
+ double cut_lj_one = cut_lj_global;
+ if (narg == 8) cut_lj_one = force->numeric(arg[7]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ a[i][j] = a_one;
+ rho[i][j] = rho_one;
+ sigma[i][j] = sigma_one;
+ c[i][j] = c_one;
+ d[i][j] = d_one;
+ cut_lj[i][j] = cut_lj_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::init_style()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Pair style born/coul/Wolf requires atom attribute q");
+
+ int irequest = neighbor->request(this);
+
+ cut_coulsq = cut_coul * cut_coul;
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairBornCoulWolf::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ double cut = MAX(cut_lj[i][j],cut_coul);
+ cut_ljsq[i][j] = cut_lj[i][j] * cut_lj[i][j];
+
+ rhoinv[i][j] = 1.0/rho[i][j];
+ born1[i][j] = a[i][j]/rho[i][j];
+ born2[i][j] = 6.0*c[i][j];
+ born3[i][j] = 8.0*d[i][j];
+
+ if (offset_flag) {
+ double rexp = exp(-cut_lj[i][j]/rho[i][j]);
+ offset[i][j] = a[i][j]*rexp - c[i][j]/pow(cut_lj[i][j],6.0)
+ + d[i][j]/pow(cut_lj[i][j],8.0);
+ } else offset[i][j] = 0.0;
+
+ cut_ljsq[j][i] = cut_ljsq[i][j];
+ a[j][i] = a[i][j];
+ c[j][i] = c[i][j];
+ d[j][i] = d[i][j];
+ rhoinv[j][i] = rhoinv[i][j];
+ sigma[j][i] = sigma[i][j];
+ born1[j][i] = born1[i][j];
+ born2[j][i] = born2[i][j];
+ born3[j][i] = born3[i][j];
+ offset[j][i] = offset[i][j];
+
+ return cut;
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&a[i][j],sizeof(double),1,fp);
+ fwrite(&rho[i][j],sizeof(double),1,fp);
+ fwrite(&sigma[i][j],sizeof(double),1,fp);
+ fwrite(&c[i][j],sizeof(double),1,fp);
+ fwrite(&d[i][j],sizeof(double),1,fp);
+ fwrite(&cut_lj[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+ MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+ if (setflag[i][j]) {
+ if (me == 0) {
+ fread(&a[i][j],sizeof(double),1,fp);
+ fread(&rho[i][j],sizeof(double),1,fp);
+ fread(&sigma[i][j],sizeof(double),1,fp);
+ fread(&c[i][j],sizeof(double),1,fp);
+ fread(&d[i][j],sizeof(double),1,fp);
+ fread(&cut_lj[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&a[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rho[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&c[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&d[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_lj[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::write_restart_settings(FILE *fp)
+{
+ fwrite(&alf,sizeof(double),1,fp);
+ fwrite(&cut_lj_global,sizeof(double),1,fp);
+ fwrite(&cut_coul,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairBornCoulWolf::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&alf,sizeof(double),1,fp);
+ fread(&cut_lj_global,sizeof(double),1,fp);
+ fread(&cut_coul,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&alf,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ----------------------------------------------------------------------
+ only the pair part is calculated here
+------------------------------------------------------------------------- */
+
+double PairBornCoulWolf::single(int i, int j, int itype, int jtype,
+ double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double r2inv,r6inv,r,prefactor,rexp;
+ double forcecoul,forceborn,phicoul,phiborn;
+ double e_shift,f_shift,dvdrr,erfcc,erfcd;
+
+ r2inv = 1.0/rsq;
+ e_shift = erfc(alf*cut_coul) / cut_coul;
+ f_shift = -(e_shift+2*alf/MY_PIS * exp(-alf*alf*cut_coul*cut_coul)) /
+ cut_coul;
+
+ if (rsq < cut_coulsq) {
+ r = sqrt(rsq);
+ prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r;
+ erfcc = erfc(alf*r);
+ erfcd = exp(-alf*alf*r*r);
+ dvdrr = (erfcc/rsq + 2.0*alf/MY_PIS * erfcd/r) + f_shift;
+ forcecoul = dvdrr*rsq*prefactor;
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else forcecoul = 0.0;
+
+ if (rsq < cut_ljsq[itype][jtype]) {
+ r6inv = r2inv*r2inv*r2inv;
+ r = sqrt(rsq);
+ rexp = exp(-r*rhoinv[itype][jtype]);
+ forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
+ + born3[itype][jtype]*r2inv*r6inv;
+ } else forceborn = 0.0;
+
+ fforce = (forcecoul + factor_lj*forceborn) * r2inv;
+
+ double eng = 0.0;
+ if (rsq < cut_coulsq) {
+ phicoul = prefactor * (erfcc-e_shift*r);
+ if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor;
+ eng += phicoul;
+ }
+ if (rsq < cut_ljsq[itype][jtype]) {
+ phiborn = a[itype][jtype]*rexp - c[itype][jtype]*r6inv
+ + d[itype][jtype]*r2inv*r6inv - offset[itype][jtype];
+ eng += factor_lj*phiborn;
+ }
+ return eng;
+}
diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/pair_born_coul_wolf.h
similarity index 59%
copy from src/GRANULAR/pair_gran_hooke_history.h
copy to src/pair_born_coul_wolf.h
index e645c12bf..d643a6e99 100644
--- a/src/GRANULAR/pair_gran_hooke_history.h
+++ b/src/pair_born_coul_wolf.h
@@ -1,64 +1,56 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(gran/hooke/history,PairGranHookeHistory)
+PairStyle(born/coul/wolf,PairBornCoulWolf)
#else
-#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_H
-#define LMP_PAIR_GRAN_HOOKE_HISTORY_H
+#ifndef LMP_PAIR_BORN_COUL_WOLF_H
+#define LMP_PAIR_BORN_COUL_WOLF_H
#include "pair.h"
namespace LAMMPS_NS {
-class PairGranHookeHistory : public Pair {
+class PairBornCoulWolf : public Pair {
public:
- PairGranHookeHistory(class LAMMPS *);
- virtual ~PairGranHookeHistory();
- virtual void compute(int, int);
- virtual void settings(int, char **);
+ PairBornCoulWolf(class LAMMPS *);
+ ~PairBornCoulWolf();
+ void compute(int, int);
+ void settings(int, char **);
void coeff(int, char **);
void init_style();
- void init_list(int, class NeighList *);
double init_one(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
- void reset_dt();
-
- protected:
- double kn,kt,gamman,gammat,xmu;
- int dampflag;
- double dt;
- int freeze_group_bit;
- int history;
-
- bigint laststep;
- class FixShearHistory *fix_history;
-
- char *suffix;
-
- double *onerad_dynamic,*onerad_frozen;
- double *maxrad_dynamic,*maxrad_frozen;
+ double single(int, int, int, int, double, double, double, double &);
+
+ private:
+ double cut_lj_global;
+ double **cut_lj,**cut_ljsq;
+ double cut_coul,cut_coulsq;
+ double **a,**rho,**sigma,**c,**d;
+ double **rhoinv,**born1,**born2,**born3,**offset;
+ double alf,e_shift,f_shift;
void allocate();
};
}
#endif
#endif
diff --git a/src/pair_coul_wolf.cpp b/src/pair_coul_wolf.cpp
new file mode 100644
index 000000000..d44a24542
--- /dev/null
+++ b/src/pair_coul_wolf.cpp
@@ -0,0 +1,328 @@
+/* ----------------------------------------------------------------------
+ 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: Yongfeng Zhang (INL), yongfeng.zhang@inl.gov
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_coul_wolf.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "math_const.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace MathConst;
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulWolf::PairCoulWolf(LAMMPS *lmp) : Pair(lmp) {}
+
+/* ---------------------------------------------------------------------- */
+
+PairCoulWolf::~PairCoulWolf()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairCoulWolf::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,ecoul,fpair;
+ double rsq,forcecoul,factor_coul;
+ double prefactor;
+ double r,rexp;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double erfcc,erfcd,v_sh,dvdrr,e_self,qisq;
+
+ ecoul = 0.0;
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double **f = atom->f;
+ double *q = atom->q;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ double *special_coul = force->special_coul;
+ int newton_pair = force->newton_pair;
+ double qqrd2e = force->qqrd2e;
+
+ // self and shifted coulombic energy
+
+ e_self = v_sh = 0.0;
+ e_shift = erfc(alf*cut_coul)/cut_coul;
+ f_shift = -(e_shift+ 2.0*alf/MY_PIS * exp(-alf*alf*cut_coul*cut_coul)) /
+ cut_coul;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ qtmp = q[i];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ qisq = qtmp*qtmp;
+ e_self = -(e_shift/2.0 + alf/MY_PIS) * qisq*qqrd2e;
+ if (evflag) ev_tally(i,i,nlocal,0,0.0,e_self,0.0,0.0,0.0,0.0);
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+
+ if (j < nall) factor_coul = 1.0;
+ else {
+ factor_coul = special_coul[j/nall];
+ j %= nall;
+ }
+
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ jtype = type[j];
+
+ if (rsq < cut_coulsq) {
+ r = sqrt(rsq);
+ prefactor = qqrd2e*qtmp*q[j]/r;
+ erfcc = erfc(alf*r);
+ erfcd = exp(-alf*alf*r*r);
+ v_sh = (erfcc - e_shift*r) * prefactor;
+ dvdrr = (erfcc/rsq + 2.0*alf/MY_PIS * erfcd/r) + f_shift;
+ forcecoul = dvdrr*rsq*prefactor;
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ fpair = forcecoul / rsq;
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ }
+
+ if (eflag) {
+ if (rsq < cut_coulsq) {
+ ecoul = v_sh;
+ if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+ } else ecoul = 0.0;
+ }
+
+ if (evflag) ev_tally(i,j,nlocal,newton_pair,
+ 0.0,ecoul,fpair,delx,dely,delz);
+ }
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+ unlike other pair styles,
+ there are no individual pair settings that these override
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::settings(int narg, char **arg)
+{
+ if (narg != 2) error->all(FLERR,"Illegal pair_style command");
+
+ alf = force->numeric(arg[0]);
+ cut_coul = force->numeric(arg[1]);
+}
+
+/* ----------------------------------------------------------------------
+ set cutoffs for one or more type pairs, optional
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::coeff(int narg, char **arg)
+{
+ if (narg != 2) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::init_style()
+{
+ if (!atom->q_flag)
+ error->all(FLERR,"Pair coul/wolf requires atom attribute q");
+
+ int irequest = neighbor->request(this);
+
+ cut_coulsq = cut_coul*cut_coul;
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairCoulWolf::init_one(int i, int j)
+{
+ return cut_coul;
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ int i,j;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++)
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+ allocate();
+
+ int i,j;
+ int me = comm->me;
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = i; j <= atom->ntypes; j++) {
+ if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+ MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::write_restart_settings(FILE *fp)
+{
+ fwrite(&alf,sizeof(double),1,fp);
+ fwrite(&cut_coul,sizeof(double),1,fp);
+ fwrite(&offset_flag,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairCoulWolf::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&alf,sizeof(double),1,fp);
+ fread(&cut_coul,sizeof(double),1,fp);
+ fread(&offset_flag,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&alf,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ----------------------------------------------------------------------
+ only the pair part is calculated here
+------------------------------------------------------------------------- */
+
+double PairCoulWolf::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_lj,
+ double &fforce)
+{
+ double r6inv,r,prefactor,rexp;
+ double forcecoul,forceborn,phicoul;
+ double e_shift,f_shift,dvdrr,erfcc,erfcd;
+
+ e_shift = erfc(alf*cut_coul) / cut_coul;
+ f_shift = -(e_shift+ 2.0*alf/MY_PIS * exp(-alf*alf*cut_coul*cut_coul)) /
+ cut_coul;
+
+ if (rsq < cut_coulsq) {
+ r = sqrt(rsq);
+ prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r;
+ erfcc = erfc(alf*r);
+ erfcd = exp(-alf*alf*r*r);
+ dvdrr = (erfcc/rsq + 2.0*alf/MY_PIS * erfcd/r) + f_shift;
+ forcecoul = dvdrr*rsq*prefactor;
+ if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
+ } else forcecoul = 0.0;
+ fforce = forcecoul / rsq;
+
+ double eng = 0.0;
+ if (rsq < cut_coulsq) {
+ phicoul = prefactor * (erfcc-e_shift*r);
+ if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor;
+ eng += phicoul;
+ }
+ return eng;
+}
diff --git a/src/GPU/pair_cg_cmm_coul_msm.h b/src/pair_coul_wolf.h
similarity index 66%
rename from src/GPU/pair_cg_cmm_coul_msm.h
rename to src/pair_coul_wolf.h
index 91fd9c17a..acdcb5f18 100644
--- a/src/GPU/pair_cg_cmm_coul_msm.h
+++ b/src/pair_coul_wolf.h
@@ -1,53 +1,52 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
-PairStyle(cg/cmm/coul/msm,PairCGCMMCoulMSM)
+PairStyle(coul/wolf,PairCoulWolf)
#else
-#ifndef LMP_PAIR_CG_CMM_COUL_MSM_H
-#define LMP_PAIR_CG_CMM_COUL_MSM_H
+#ifndef LMP_PAIR_COUL_WOLF_H
+#define LMP_PAIR_COUL_WOLF_H
-#include "pair_cmm_common.h"
+#include "pair.h"
namespace LAMMPS_NS {
-class PairCGCMMCoulMSM : public PairCMMCommon {
+class PairCoulWolf : public Pair {
public:
- PairCGCMMCoulMSM(class LAMMPS *);
- ~PairCGCMMCoulMSM();
-
+ PairCoulWolf(class LAMMPS *);
+ ~PairCoulWolf();
void compute(int, int);
void settings(int, char **);
+ void coeff(int, char **);
void init_style();
double init_one(int, int);
-
void write_restart(FILE *);
void read_restart(FILE *);
+ void write_restart_settings(FILE *);
+ void read_restart_settings(FILE *);
+ double single(int, int, int, int, double, double, double, double &);
- double memory_usage();
-
- void *extract(char *str);
+ private:
+ double cut_coul,cut_coulsq;
+ double alf,e_shift,f_shift;
- protected:
void allocate();
- double _ia, _ia2, _ia3;
- int _smooth;
};
}
#endif
#endif
diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp
index 206782be2..71a136600 100644
--- a/src/pair_hybrid.cpp
+++ b/src/pair_hybrid.cpp
@@ -1,695 +1,718 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "ctype.h"
#include "pair_hybrid.h"
#include "atom.h"
#include "force.h"
#include "pair.h"
#include "neighbor.h"
#include "neigh_request.h"
#include "update.h"
#include "comm.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp)
{
nstyles = 0;
}
/* ---------------------------------------------------------------------- */
PairHybrid::~PairHybrid()
{
if (nstyles) {
for (int m = 0; m < nstyles; m++) delete styles[m];
delete [] styles;
for (int m = 0; m < nstyles; m++) delete [] keywords[m];
delete [] keywords;
}
+ delete [] svector;
+
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cutghost);
memory->destroy(nmap);
memory->destroy(map);
}
}
/* ----------------------------------------------------------------------
call each sub-style's compute function
accumulate sub-style global/peratom energy/virial in hybrid
for global vflag = 1:
each sub-style computes own virial[6]
sum sub-style virial[6] to hybrid's virial[6]
for global vflag = 2:
call sub-style with adjusted vflag to prevent it calling
virial_fdotr_compute()
hybrid calls virial_fdotr_compute() on final accumulated f
------------------------------------------------------------------------- */
void PairHybrid::compute(int eflag, int vflag)
{
int i,j,m,n;
// if no_virial_fdotr_compute is set and global component of
// incoming vflag = 2, then
// reset vflag as if global component were 1
// necessary since one or more sub-styles cannot compute virial as F dot r
if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = eflag_global = vflag_global =
eflag_atom = vflag_atom = 0;
// check if global component of incoming vflag = 2
// if so, reset vflag passed to substyle as if it were 0
// necessary so substyle will not invoke virial_fdotr_compute()
int vflag_substyle;
if (vflag % 4 == 2) vflag_substyle = vflag/4 * 4;
else vflag_substyle = vflag;
for (m = 0; m < nstyles; m++) {
styles[m]->compute(eflag,vflag_substyle);
if (eflag_global) {
eng_vdwl += styles[m]->eng_vdwl;
eng_coul += styles[m]->eng_coul;
}
if (vflag_global) {
for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
}
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_pair) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_pair) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
}
}
if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
void PairHybrid::compute_inner()
{
for (int m = 0; m < nstyles; m++)
if (styles[m]->respa_enable) styles[m]->compute_inner();
}
/* ---------------------------------------------------------------------- */
void PairHybrid::compute_middle()
{
for (int m = 0; m < nstyles; m++)
if (styles[m]->respa_enable) styles[m]->compute_middle();
}
/* ---------------------------------------------------------------------- */
void PairHybrid::compute_outer(int eflag, int vflag)
{
for (int m = 0; m < nstyles; m++)
if (styles[m]->respa_enable) styles[m]->compute_outer(eflag,vflag);
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairHybrid::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cutghost,n+1,n+1,"pair:cutghost");
memory->create(nmap,n+1,n+1,"pair:nmap");
memory->create(map,n+1,n+1,nstyles,"pair:map");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
nmap[i][j] = 0;
}
/* ----------------------------------------------------------------------
create one pair style for each arg in list
------------------------------------------------------------------------- */
void PairHybrid::settings(int narg, char **arg)
{
int i,m,istyle;
if (narg < 1) error->all(FLERR,"Illegal pair_style command");
// delete old lists, since cannot just change settings
if (nstyles) {
for (m = 0; m < nstyles; m++) delete styles[m];
delete [] styles;
for (m = 0; m < nstyles; m++) delete [] keywords[m];
delete [] keywords;
}
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cutghost);
memory->destroy(nmap);
memory->destroy(map);
}
allocated = 0;
// count sub-styles by skipping numeric args
// exception is 1st arg of table style, which is non-numeric word
// exception is 1st two args of lj/coul style, which are non-numeric
// exception is 1st two args of buck/coul, which are non-numeric
// exception is 1st arg of reax/c style, which is non-numeric
// execption is 1st 6 args of gran styles, which can have NULLs
// need a better way to skip these exceptions
nstyles = 0;
i = 0;
while (i < narg) {
if (strcmp(arg[i],"table") == 0) i++;
if (strcmp(arg[i],"lj/coul") == 0) i += 2;
if (strcmp(arg[i],"buck/coul") == 0) i += 2;
if (strcmp(arg[i],"reax/c") == 0) i++;
if (strstr(arg[i],"gran/hooke")) i += 6;
if (strstr(arg[i],"gran/hertz")) i += 6;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
nstyles++;
}
// allocate list of sub-styles
styles = new Pair*[nstyles];
keywords = new char*[nstyles];
// allocate each sub-style and call its settings() with subset of args
// define subset of args for a sub-style by skipping numeric args
// exception is 1st arg of table style, which is non-numeric word
// exception is 1st two args of lj/coul style, which are non-numeric
// exception is 1st two args of buck/coul, which are non-numeric
// exception is 1st arg of reax/c style, which is non-numeric
// execption is 1st 6 args of gran styles, which can have NULLs
// need a better way to skip these exceptions
int dummy;
nstyles = 0;
i = 0;
while (i < narg) {
for (m = 0; m < nstyles; m++)
if (strcmp(arg[i],keywords[m]) == 0)
error->all(FLERR,"Pair style hybrid cannot use same pair style twice");
if (strcmp(arg[i],"hybrid") == 0)
error->all(FLERR,"Pair style hybrid cannot have hybrid as an argument");
if (strcmp(arg[i],"none") == 0)
error->all(FLERR,"Pair style hybrid cannot have none as an argument");
styles[nstyles] = force->new_pair(arg[i],lmp->suffix,dummy);
keywords[nstyles] = new char[strlen(arg[i])+1];
strcpy(keywords[nstyles],arg[i]);
istyle = i;
if (strcmp(arg[i],"table") == 0) i++;
if (strcmp(arg[i],"lj/coul") == 0) i += 2;
if (strcmp(arg[i],"buck/coul") == 0) i += 2;
if (strcmp(arg[i],"reax/c") == 0) i++;
if (strstr(arg[i],"gran/hooke")) i += 6;
if (strstr(arg[i],"gran/hertz")) i += 6;
i++;
while (i < narg && !isalpha(arg[i][0])) i++;
styles[nstyles]->settings(i-istyle-1,&arg[istyle+1]);
nstyles++;
}
// set comm_forward, comm_reverse to max of any sub-style
for (m = 0; m < nstyles; m++) {
if (styles[m]) comm_forward = MAX(comm_forward,styles[m]->comm_forward);
if (styles[m]) comm_reverse = MAX(comm_reverse,styles[m]->comm_reverse);
}
- // single_enable = 0 if any sub-style = 0
+ // single_enable = 1 if any sub-style is set
// respa_enable = 1 if any sub-style is set
// no_virial_fdotr_compute = 1 if any sub-style is set
// ghostneigh = 1 if any sub-style is set
+ single_enable = 0;
for (m = 0; m < nstyles; m++)
- if (styles[m]->single_enable == 0) single_enable = 0;
+ if (styles[m]->single_enable) single_enable = 1;
for (m = 0; m < nstyles; m++)
if (styles[m]->respa_enable) respa_enable = 1;
for (m = 0; m < nstyles; m++)
if (styles[m]->no_virial_fdotr_compute) no_virial_fdotr_compute = 1;
for (m = 0; m < nstyles; m++)
if (styles[m]->ghostneigh) ghostneigh = 1;
+
+ // single_extra = min of all sub-style single_extra
+ // allocate svector
+
+ single_extra = styles[0]->single_extra;
+ for (m = 1; m < nstyles; m++)
+ single_extra = MIN(single_extra,styles[m]->single_extra);
+
+ if (single_extra) {
+ delete [] svector;
+ svector = new double[single_extra];
+ }
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairHybrid::coeff(int narg, char **arg)
{
if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
// 3rd arg = pair sub-style name
// allow for "none" as valid sub-style name
int m;
for (m = 0; m < nstyles; m++)
if (strcmp(arg[2],keywords[m]) == 0) break;
int none = 0;
if (m == nstyles) {
if (strcmp(arg[2],"none") == 0) none = 1;
else error->all(FLERR,"Pair coeff for hybrid has invalid style");
}
// move 1st/2nd args to 2nd/3rd args
// just copy ptrs, since arg[] points into original input line
arg[2] = arg[1];
arg[1] = arg[0];
// invoke sub-style coeff() starting with 1st arg
if (!none) styles[m]->coeff(narg-1,&arg[1]);
// if sub-style only allows one pair coeff call (with * * and type mapping)
// then unset setflag/map assigned to that style before setting it below
// in case pair coeff for this sub-style is being called for 2nd time
if (!none && styles[m]->one_coeff)
for (int i = 1; i <= atom->ntypes; i++)
for (int j = i; j <= atom->ntypes; j++)
if (nmap[i][j] && map[i][j][0] == m) {
setflag[i][j] = 0;
nmap[i][j] = 0;
}
// set setflag and which type pairs map to which sub-style
// if sub-style is none: set hybrid setflag, wipe out map
// else: set hybrid setflag & map only if substyle setflag is set
// previous mappings are wiped out
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
if (none) {
setflag[i][j] = 1;
nmap[i][j] = 0;
count++;
} else if (styles[m]->setflag[i][j]) {
setflag[i][j] = 1;
nmap[i][j] = 1;
map[i][j][0] = m;
count++;
}
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairHybrid::init_style()
{
int i,m,itype,jtype,used,istyle,skip;
// error if a sub-style is not used
int ntypes = atom->ntypes;
for (istyle = 0; istyle < nstyles; istyle++) {
used = 0;
for (itype = 1; itype <= ntypes; itype++)
for (jtype = itype; jtype <= ntypes; jtype++)
for (m = 0; m < nmap[itype][jtype]; m++)
if (map[itype][jtype][m] == istyle) used = 1;
if (used == 0) error->all(FLERR,"Pair hybrid sub-style is not used");
}
// each sub-style makes its neighbor list request(s)
for (istyle = 0; istyle < nstyles; istyle++) styles[istyle]->init_style();
// create skip lists for each pair neigh request
// any kind of list can have its skip flag set at this stage
for (i = 0; i < neighbor->nrequest; i++) {
if (!neighbor->requests[i]->pair) continue;
// istyle = associated sub-style
for (istyle = 0; istyle < nstyles; istyle++)
if (styles[istyle] == neighbor->requests[i]->requestor) break;
// allocate iskip and ijskip
// initialize so as to skip all pair types
// set ijskip = 0 if type pair matches any entry in sub-style map
// set ijskip = 0 if mixing will assign type pair to this sub-style
// will occur if type pair is currently unassigned
// and both I,I and J,J are assigned to single sub-style
// and sub-style for both I,I and J,J match istyle
// set iskip = 1 only if all ijskip for itype are 1
int *iskip = new int[ntypes+1];
int **ijskip;
memory->create(ijskip,ntypes+1,ntypes+1,"pair_hybrid:ijskip");
for (itype = 1; itype <= ntypes; itype++)
for (jtype = 1; jtype <= ntypes; jtype++)
ijskip[itype][jtype] = 1;
for (itype = 1; itype <= ntypes; itype++)
for (jtype = itype; jtype <= ntypes; jtype++) {
for (m = 0; m < nmap[itype][jtype]; m++)
if (map[itype][jtype][m] == istyle)
ijskip[itype][jtype] = ijskip[jtype][itype] = 0;
if (nmap[itype][jtype] == 0 &&
nmap[itype][itype] == 1 && map[itype][itype][0] == istyle &&
nmap[jtype][jtype] == 1 && map[jtype][jtype][0] == istyle)
ijskip[itype][jtype] = ijskip[jtype][itype] = 0;
}
for (itype = 1; itype <= ntypes; itype++) {
iskip[itype] = 1;
for (jtype = 1; jtype <= ntypes; jtype++)
if (ijskip[itype][jtype] == 0) iskip[itype] = 0;
}
// if any skipping occurs
// set request->skip and copy iskip and ijskip into request
// else delete iskip and ijskip
skip = 0;
for (itype = 1; itype <= ntypes; itype++)
for (jtype = 1; jtype <= ntypes; jtype++)
if (ijskip[itype][jtype] == 1) skip = 1;
if (skip) {
neighbor->requests[i]->skip = 1;
neighbor->requests[i]->iskip = iskip;
neighbor->requests[i]->ijskip = ijskip;
} else {
delete [] iskip;
memory->destroy(ijskip);
}
}
// combine sub-style neigh list requests and create new ones if needed
modify_requests();
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairHybrid::init_one(int i, int j)
{
// if I,J is not set explicitly:
// perform mixing only if I,I sub-style = J,J sub-style
// also require I,I and J,J are both assigned to single sub-style
if (setflag[i][j] == 0) {
if (nmap[i][i] != 1 || nmap[j][j] != 1 || map[i][i][0] != map[j][j][0])
error->one(FLERR,"All pair coeffs are not set");
nmap[i][j] = 1;
map[i][j][0] = map[i][i][0];
}
// call init/mixing for all sub-styles of I,J
// set cutsq in sub-style just as Pair::init() does via call to init_one()
// set cutghost for I,J and J,I just as sub-style does
// sum tail corrections for I,J
// return max cutoff of all sub-styles assigned to I,J
// if no sub-styles assigned to I,J (pair_coeff none), cutmax = 0.0 returned
double cutmax = 0.0;
cutghost[i][j] = cutghost[j][i] = 0.0;
if (tail_flag) etail_ij = ptail_ij = 0.0;
nmap[j][i] = nmap[i][j];
for (int k = 0; k < nmap[i][j]; k++) {
map[j][i][k] = map[i][j][k];
double cut = styles[map[i][j][k]]->init_one(i,j);
styles[map[i][j][k]]->cutsq[i][j] =
styles[map[i][j][k]]->cutsq[j][i] = cut*cut;
if (styles[map[i][j][k]]->ghostneigh)
cutghost[i][j] = cutghost[j][i] =
MAX(cutghost[i][j],styles[map[i][j][k]]->cutghost[i][j]);
if (tail_flag) {
etail_ij += styles[map[i][j][k]]->etail_ij;
ptail_ij += styles[map[i][j][k]]->ptail_ij;
}
cutmax = MAX(cutmax,cut);
}
return cutmax;
}
/* ----------------------------------------------------------------------
combine sub-style neigh list requests and create new ones if needed
------------------------------------------------------------------------- */
void PairHybrid::modify_requests()
{
int i,j;
NeighRequest *irq,*jrq;
// loop over pair requests only
// if list is skip list and not copy, look for non-skip list of same kind
// if one exists, point at that one via otherlist
// else make new non-skip request of same kind and point at that one
// don't bother to set ID for new request, since pair hybrid ignores list
// only exception is half_from_full:
// ignore it, turn off skip, since it will derive from its skip parent
// after possible new request creation, unset skip flag and otherlist
// for these derived lists: granhistory, rRESPA inner/middle
// this prevents neighbor from treating them as skip lists
// copy list check is for pair style = hybrid/overlay
// which invokes this routine
for (i = 0; i < neighbor->nrequest; i++) {
if (!neighbor->requests[i]->pair) continue;
irq = neighbor->requests[i];
if (irq->skip == 0 || irq->copy) continue;
if (irq->half_from_full) {
irq->skip = 0;
continue;
}
for (j = 0; j < neighbor->nrequest; j++) {
if (!neighbor->requests[j]->pair) continue;
jrq = neighbor->requests[j];
if (irq->same_kind(jrq) && jrq->skip == 0) break;
}
if (j < neighbor->nrequest) irq->otherlist = j;
else {
int newrequest = neighbor->request(this);
neighbor->requests[newrequest]->copy_request(irq);
irq->otherlist = newrequest;
}
if (irq->granhistory || irq->respainner || irq->respamiddle) {
irq->skip = 0;
irq->otherlist = -1;
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairHybrid::write_restart(FILE *fp)
{
fwrite(&nstyles,sizeof(int),1,fp);
// each sub-style writes its settings, but no coeff info
int n;
for (int m = 0; m < nstyles; m++) {
n = strlen(keywords[m]) + 1;
fwrite(&n,sizeof(int),1,fp);
fwrite(keywords[m],sizeof(char),n,fp);
styles[m]->write_restart_settings(fp);
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairHybrid::read_restart(FILE *fp)
{
int me = comm->me;
if (me == 0) fread(&nstyles,sizeof(int),1,fp);
MPI_Bcast(&nstyles,1,MPI_INT,0,world);
styles = new Pair*[nstyles];
keywords = new char*[nstyles];
// each sub-style is created via new_pair()
// each reads its settings, but no coeff info
int n,dummy;
for (int m = 0; m < nstyles; m++) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
keywords[m] = new char[n];
if (me == 0) fread(keywords[m],sizeof(char),n,fp);
MPI_Bcast(keywords[m],n,MPI_CHAR,0,world);
styles[m] = force->new_pair(keywords[m],lmp->suffix,dummy);
styles[m]->read_restart_settings(fp);
}
}
/* ----------------------------------------------------------------------
call sub-style to compute single interaction
error if sub-style does not support single() call
since overlay could have multiple sub-styles, sum results explicitly
------------------------------------------------------------------------- */
double PairHybrid::single(int i, int j, int itype, int jtype,
double rsq, double factor_coul, double factor_lj,
double &fforce)
{
if (nmap[itype][jtype] == 0)
error->one(FLERR,"Invoked pair single on pair style none");
double fone;
fforce = 0.0;
double esum = 0.0;
for (int m = 0; m < nmap[itype][jtype]; m++) {
if (rsq < styles[map[itype][jtype][m]]->cutsq[itype][jtype]) {
if (styles[map[itype][jtype][m]]->single_enable == 0)
- error->all(FLERR,"Pair hybrid sub-style does not support single call");
+ error->one(FLERR,"Pair hybrid sub-style does not support single call");
+
esum += styles[map[itype][jtype][m]]->
single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fone);
fforce += fone;
+
+ // copy substyle extra values into hybrid's svector
+
+ if (single_extra && styles[map[itype][jtype][m]]->single_extra)
+ for (m = 0; m < single_extra; m++)
+ svector[m] = styles[map[itype][jtype][m]]->svector[m];
}
}
return esum;
}
/* ----------------------------------------------------------------------
modify parameters of the pair style
call modify_params of PairHybrid
also pass command args to each sub-style of hybrid
------------------------------------------------------------------------- */
void PairHybrid::modify_params(int narg, char **arg)
{
Pair::modify_params(narg,arg);
for (int m = 0; m < nstyles; m++) styles[m]->modify_params(narg,arg);
}
/* ----------------------------------------------------------------------
memory usage of each sub-style
------------------------------------------------------------------------- */
double PairHybrid::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += styles[m]->memory_usage();
return bytes;
}
/* ----------------------------------------------------------------------
extract a ptr to a particular quantity stored by pair
pass request thru to sub-styles
return first non-NULL result except for cut_coul request
for cut_coul, insure all non-NULL results are equal since required by Kspace
------------------------------------------------------------------------- */
void *PairHybrid::extract(char *str, int &dim)
{
void *cutptr = NULL;
void *ptr;
double cutvalue;
for (int m = 0; m < nstyles; m++) {
ptr = styles[m]->extract(str,dim);
if (ptr && strcmp(str,"cut_coul") == 0) {
double *p_newvalue = (double *) ptr;
double newvalue = *p_newvalue;
if (cutptr && newvalue != cutvalue)
- error->all(FLERR,"Coulomb cutoffs of pair hybrid sub-styles do not match");
+ error->all(FLERR,
+ "Coulomb cutoffs of pair hybrid sub-styles do not match");
cutptr = ptr;
cutvalue = newvalue;
} else if (ptr) return ptr;
}
if (strcmp(str,"cut_coul") == 0) return cutptr;
return NULL;
}
/* ---------------------------------------------------------------------- */
void PairHybrid::reset_dt()
{
for (int m = 0; m < nstyles; m++) styles[m]->reset_dt();
}
/* ----------------------------------------------------------------------
check if itype,jtype maps to sub-style
------------------------------------------------------------------------- */
int PairHybrid::check_ijtype(int itype, int jtype, char *substyle)
{
for (int m = 0; m < nmap[itype][jtype]; m++)
if (strcmp(keywords[map[itype][jtype][m]],substyle) == 0) return 1;
return 0;
}
diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp
index 44d86990d..f5ea2887d 100644
--- a/src/pair_lj_cut.cpp
+++ b/src/pair_lj_cut.cpp
@@ -1,703 +1,704 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_lj_cut.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "update.h"
#include "integrate.h"
#include "respa.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
PairLJCut::PairLJCut(LAMMPS *lmp) : Pair(lmp)
{
respa_enable = 1;
}
/* ---------------------------------------------------------------------- */
PairLJCut::~PairLJCut()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cut);
memory->destroy(epsilon);
memory->destroy(sigma);
memory->destroy(lj1);
memory->destroy(lj2);
memory->destroy(lj3);
memory->destroy(lj4);
memory->destroy(offset);
}
}
/* ---------------------------------------------------------------------- */
void PairLJCut::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
if (eflag) {
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
}
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
}
}
}
if (vflag_fdotr) virial_fdotr_compute();
}
/* ---------------------------------------------------------------------- */
void PairLJCut::compute_inner()
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj,rsw;
int *ilist,*jlist,*numneigh,**firstneigh;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
inum = listinner->inum;
ilist = listinner->ilist;
numneigh = listinner->numneigh;
firstneigh = listinner->firstneigh;
double cut_out_on = cut_respa[0];
double cut_out_off = cut_respa[1];
double cut_out_diff = cut_out_off - cut_out_on;
double cut_out_on_sq = cut_out_on*cut_out_on;
double cut_out_off_sq = cut_out_off*cut_out_off;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cut_out_off_sq) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fpair *= 1.0 - rsw*rsw*(3.0 - 2.0*rsw);
}
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
}
}
}
}
/* ---------------------------------------------------------------------- */
void PairLJCut::compute_middle()
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj,rsw;
int *ilist,*jlist,*numneigh,**firstneigh;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
inum = listmiddle->inum;
ilist = listmiddle->ilist;
numneigh = listmiddle->numneigh;
firstneigh = listmiddle->firstneigh;
double cut_in_off = cut_respa[0];
double cut_in_on = cut_respa[1];
double cut_out_on = cut_respa[2];
double cut_out_off = cut_respa[3];
double cut_in_diff = cut_in_on - cut_in_off;
double cut_out_diff = cut_out_off - cut_out_on;
double cut_in_off_sq = cut_in_off*cut_in_off;
double cut_in_on_sq = cut_in_on*cut_in_on;
double cut_out_on_sq = cut_out_on*cut_out_on;
double cut_out_off_sq = cut_out_off*cut_out_off;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq < cut_out_off_sq && rsq > cut_in_off_sq) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
if (rsq < cut_in_on_sq) {
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fpair *= rsw*rsw*(3.0 - 2.0*rsw);
}
if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fpair *= 1.0 + rsw*rsw*(2.0*rsw - 3.0);
}
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
}
}
}
}
/* ---------------------------------------------------------------------- */
void PairLJCut::compute_outer(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r2inv,r6inv,forcelj,factor_lj,rsw;
int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int *type = atom->type;
int nlocal = atom->nlocal;
double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
inum = listouter->inum;
ilist = listouter->ilist;
numneigh = listouter->numneigh;
firstneigh = listouter->firstneigh;
double cut_in_off = cut_respa[2];
double cut_in_on = cut_respa[3];
double cut_in_diff = cut_in_on - cut_in_off;
double cut_in_off_sq = cut_in_off*cut_in_off;
double cut_in_on_sq = cut_in_on*cut_in_on;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
factor_lj = special_lj[sbmask(j)];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
if (rsq > cut_in_off_sq) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
if (rsq < cut_in_on_sq) {
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fpair *= rsw*rsw*(3.0 - 2.0*rsw);
}
f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) {
f[j][0] -= delx*fpair;
f[j][1] -= dely*fpair;
f[j][2] -= delz*fpair;
}
}
if (eflag) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
evdwl *= factor_lj;
}
if (vflag) {
if (rsq <= cut_in_off_sq) {
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fpair = factor_lj*forcelj*r2inv;
} else if (rsq < cut_in_on_sq)
fpair = factor_lj*forcelj*r2inv;
}
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
}
}
}
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairLJCut::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cut,n+1,n+1,"pair:cut");
memory->create(epsilon,n+1,n+1,"pair:epsilon");
memory->create(sigma,n+1,n+1,"pair:sigma");
memory->create(lj1,n+1,n+1,"pair:lj1");
memory->create(lj2,n+1,n+1,"pair:lj2");
memory->create(lj3,n+1,n+1,"pair:lj3");
memory->create(lj4,n+1,n+1,"pair:lj4");
memory->create(offset,n+1,n+1,"pair:offset");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairLJCut::settings(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal pair_style command");
cut_global = force->numeric(arg[0]);
// reset cutoffs that have been explicitly set
-
+
if (allocated) {
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i+1; j <= atom->ntypes; j++)
if (setflag[i][j]) cut[i][j] = cut_global;
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairLJCut::coeff(int narg, char **arg)
{
- if (narg < 4 || narg > 5) error->all(FLERR,"Incorrect args for pair coefficients");
+ if (narg < 4 || narg > 5)
+ error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
double epsilon_one = force->numeric(arg[2]);
double sigma_one = force->numeric(arg[3]);
double cut_one = cut_global;
if (narg == 5) cut_one = force->numeric(arg[4]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
epsilon[i][j] = epsilon_one;
sigma[i][j] = sigma_one;
cut[i][j] = cut_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairLJCut::init_style()
{
// request regular or rRESPA neighbor lists
int irequest;
if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) {
int respa = 0;
if (((Respa *) update->integrate)->level_inner >= 0) respa = 1;
if (((Respa *) update->integrate)->level_middle >= 0) respa = 2;
if (respa == 0) irequest = neighbor->request(this);
else if (respa == 1) {
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 1;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->respainner = 1;
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 3;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->respaouter = 1;
} else {
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 1;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->respainner = 1;
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 2;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->respamiddle = 1;
irequest = neighbor->request(this);
neighbor->requests[irequest]->id = 3;
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->respaouter = 1;
}
} else irequest = neighbor->request(this);
// set rRESPA cutoffs
if (strstr(update->integrate_style,"respa") &&
((Respa *) update->integrate)->level_inner >= 0)
cut_respa = ((Respa *) update->integrate)->cutoff;
else cut_respa = NULL;
}
/* ----------------------------------------------------------------------
neighbor callback to inform pair style of neighbor list to use
regular or rRESPA
------------------------------------------------------------------------- */
void PairLJCut::init_list(int id, NeighList *ptr)
{
if (id == 0) list = ptr;
else if (id == 1) listinner = ptr;
else if (id == 2) listmiddle = ptr;
else if (id == 3) listouter = ptr;
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairLJCut::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j],
sigma[i][i],sigma[j][j]);
sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]);
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
}
lj1[i][j] = 48.0 * epsilon[i][j] * pow(sigma[i][j],12.0);
lj2[i][j] = 24.0 * epsilon[i][j] * pow(sigma[i][j],6.0);
lj3[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],12.0);
lj4[i][j] = 4.0 * epsilon[i][j] * pow(sigma[i][j],6.0);
if (offset_flag) {
double ratio = sigma[i][j] / cut[i][j];
offset[i][j] = 4.0 * epsilon[i][j] * (pow(ratio,12.0) - pow(ratio,6.0));
} else offset[i][j] = 0.0;
lj1[j][i] = lj1[i][j];
lj2[j][i] = lj2[i][j];
lj3[j][i] = lj3[i][j];
lj4[j][i] = lj4[i][j];
offset[j][i] = offset[i][j];
// check interior rRESPA cutoff
if (cut_respa && cut[i][j] < cut_respa[3])
error->all(FLERR,"Pair cutoff < Respa interior cutoff");
// compute I,J contribution to long-range tail correction
// count total # of atoms of type I and J via Allreduce
if (tail_flag) {
int *type = atom->type;
int nlocal = atom->nlocal;
double count[2],all[2];
count[0] = count[1] = 0.0;
for (int k = 0; k < nlocal; k++) {
if (type[k] == i) count[0] += 1.0;
if (type[k] == j) count[1] += 1.0;
}
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
double sig2 = sigma[i][j]*sigma[i][j];
double sig6 = sig2*sig2*sig2;
double rc3 = cut[i][j]*cut[i][j]*cut[i][j];
double rc6 = rc3*rc3;
double rc9 = rc3*rc6;
etail_ij = 8.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (sig6 - 3.0*rc6) / (9.0*rc9);
ptail_ij = 16.0*MY_PI*all[0]*all[1]*epsilon[i][j] *
sig6 * (2.0*sig6 - 3.0*rc6) / (9.0*rc9);
}
return cut[i][j];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairLJCut::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&epsilon[i][j],sizeof(double),1,fp);
fwrite(&sigma[i][j],sizeof(double),1,fp);
fwrite(&cut[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairLJCut::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&epsilon[i][j],sizeof(double),1,fp);
fread(&sigma[i][j],sizeof(double),1,fp);
fread(&cut[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairLJCut::write_restart_settings(FILE *fp)
{
fwrite(&cut_global,sizeof(double),1,fp);
fwrite(&offset_flag,sizeof(int),1,fp);
fwrite(&mix_flag,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairLJCut::read_restart_settings(FILE *fp)
{
int me = comm->me;
if (me == 0) {
fread(&cut_global,sizeof(double),1,fp);
fread(&offset_flag,sizeof(int),1,fp);
fread(&mix_flag,sizeof(int),1,fp);
}
MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
}
/* ---------------------------------------------------------------------- */
double PairLJCut::single(int i, int j, int itype, int jtype, double rsq,
double factor_coul, double factor_lj,
double &fforce)
{
double r2inv,r6inv,forcelj,philj;
r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = factor_lj*forcelj*r2inv;
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype];
return factor_lj*philj;
}
/* ---------------------------------------------------------------------- */
void *PairLJCut::extract(char *str, int &dim)
{
dim = 2;
if (strcmp(str,"epsilon") == 0) return (void *) epsilon;
return NULL;
}
diff --git a/src/procmap.cpp b/src/procmap.cpp
new file mode 100644
index 000000000..846f4c71b
--- /dev/null
+++ b/src/procmap.cpp
@@ -0,0 +1,681 @@
+/* ----------------------------------------------------------------------
+ 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 (NUMA option) : Mike Brown (ORNL)
+------------------------------------------------------------------------- */
+
+#include "procmap.h"
+#include "universe.h"
+#include "domain.h"
+#include "math_extra.h"
+#include "memory.h"
+#include "error.h"
+
+#include <map>
+#include <string>
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 128
+
+enum{MULTIPLE}; // same as in Comm
+
+/* ---------------------------------------------------------------------- */
+
+ProcMap::ProcMap(LAMMPS *lmp) : Pointers(lmp) {}
+
+/* ----------------------------------------------------------------------
+ create a one-level 3d grid of procs via procs2box()
+------------------------------------------------------------------------- */
+
+int ProcMap::onelevel_grid(int nprocs, int *user_procgrid, int *procgrid,
+ int otherflag, int other_style_caller,
+ int *other_procgrid_caller)
+{
+ other_style = other_style_caller;
+ other_procgrid[0] = other_procgrid_caller[0];
+ other_procgrid[1] = other_procgrid_caller[1];
+ other_procgrid[2] = other_procgrid_caller[2];
+
+ int flag = procs2box(nprocs,user_procgrid,procgrid,1,1,1,otherflag);
+ return flag;
+}
+
+/* ----------------------------------------------------------------------
+ create a two-level 3d grid of procs and cores via procs2box()
+------------------------------------------------------------------------- */
+
+int ProcMap::twolevel_grid(int nprocs, int *user_procgrid, int *procgrid,
+ int ncores, int *user_coregrid, int *coregrid,
+ int otherflag, int other_style_caller,
+ int *other_procgrid_caller)
+{
+ if (nprocs % ncores)
+ error->all(FLERR,"Processors twogrid requres proc count "
+ "be a multiple of core count");
+
+
+
+ error->all(FLERR,
+ "The twolevel option is not yet supported, but will be soon");
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ create a 3d grid of procs that does a 2-level hierarchy within a node
+ auto-detects NUMA sockets within a multi-core node
+ return 1 if successful, 0 if not
+------------------------------------------------------------------------- */
+
+int ProcMap::numa_grid(int nprocs, int *user_procgrid, int *procgrid,
+ int *numagrid)
+{
+ // hardwire this for now
+
+ int numa_nodes = 1;
+
+ // get names of all nodes
+
+ int name_length;
+ char node_name[MPI_MAX_PROCESSOR_NAME];
+ char node_names[MPI_MAX_PROCESSOR_NAME*nprocs];
+ MPI_Get_processor_name(node_name,&name_length);
+ MPI_Allgather(&node_name,MPI_MAX_PROCESSOR_NAME,MPI_CHAR,&node_names,
+ MPI_MAX_PROCESSOR_NAME,MPI_CHAR,world);
+ std::string node_string = std::string(node_name);
+
+ // get number of procs per node
+
+ std::map<std::string,int> name_map;
+ std::map<std::string,int>::iterator np;
+ for (int i = 0; i < nprocs; i++) {
+ std::string i_string = std::string(&node_names[i*MPI_MAX_PROCESSOR_NAME]);
+ np = name_map.find(i_string);
+ if (np == name_map.end()) name_map[i_string] = 1;
+ else np->second++;
+ }
+ procs_per_node = name_map.begin()->second;
+ procs_per_numa = procs_per_node / numa_nodes;
+
+ // error return if any of these conditions met
+
+ if (procs_per_numa < 4 || // less than 4 procs per numa node
+ procs_per_node % numa_nodes || // no-op since numa_nodes = 1 for now
+ nprocs % procs_per_numa || // total procs not a multiple of node
+ nprocs == procs_per_numa || // only 1 node used
+ user_procgrid[0] > 1 || // user specified grid > 1 in any dim
+ user_procgrid[1] > 1 ||
+ user_procgrid[2] > 1)
+ return 0;
+
+ // user settings for the factorization per numa node
+ // currently not user settable
+
+ int user_numagrid[3];
+ user_numagrid[0] = user_numagrid[1] = user_numagrid[2] = 0;
+
+ // if user specifies 1 for a proc grid dimension,
+ // also use 1 for the numa grid dimension
+
+ if (user_procgrid[0] == 1) user_numagrid[0] = 1;
+ if (user_procgrid[1] == 1) user_numagrid[1] = 1;
+ if (user_procgrid[2] == 1) user_numagrid[2] = 1;
+
+ // initial factorization within NUMA node
+
+ procs2box(procs_per_numa,user_numagrid,numagrid,1,1,1,0);
+ if (numagrid[0]*numagrid[1]*numagrid[2] != procs_per_numa)
+ error->all(FLERR,"Bad grid of processors");
+
+ // factorization for the grid of NUMA nodes
+
+ int node_count = nprocs / procs_per_numa;
+ procs2box(node_count,user_procgrid,nodegrid,
+ numagrid[0],numagrid[1],numagrid[2],0);
+ if (procgrid[0]*procgrid[1]*procgrid[2] != node_count)
+ error->all(FLERR,"Bad grid of processors");
+
+ // repeat NUMA node factorization using subdomain sizes
+ // refines the factorization if the user specified the node layout
+
+ procs2box(procs_per_numa,user_numagrid,numagrid,
+ procgrid[0],procgrid[1],procgrid[2],0);
+
+ // assign a unique id to each node
+
+ node_id = 0;
+ int node_num = 0;
+ for (np = name_map.begin(); np != name_map.end(); ++np) {
+ if (np->first == node_string) node_id = node_num;
+ node_num++;
+ }
+
+ // return the proc-level factorization
+
+ procgrid[0] = nodegrid[0] * numagrid[0];
+ procgrid[1] = nodegrid[1] * numagrid[1];
+ procgrid[2] = nodegrid[2] * numagrid[2];
+
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ define a 3d grid from a custom file
+------------------------------------------------------------------------- */
+
+void ProcMap::custom_grid(char *cfile, int nprocs,
+ int *user_procgrid, int *procgrid)
+{
+ FILE *fp;
+ char line[MAXLINE];
+
+ int me;
+ MPI_Comm_rank(world,&me);
+
+ if (me == 0) {
+ FILE *fp = fopen(cfile,"r");
+ if (fp == NULL) error->one(FLERR,"Cannot open custom file");
+
+ // skip header = blank and comment lines
+
+ char *ptr;
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of custom file");
+ while (1) {
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ if (strspn(line," \t\n\r") != strlen(line)) break;
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of custom file");
+ }
+ }
+
+ int n = strlen(line) + 1;
+ MPI_Bcast(&n,1,MPI_INT,0,world);
+ MPI_Bcast(line,n,MPI_CHAR,0,world);
+
+ sscanf(line,"%d %d %d",&procgrid[0],&procgrid[1],&procgrid[2]);
+
+ int flag = 0;
+ if (procgrid[0]*procgrid[1]*procgrid[2] != nprocs) flag = 1;
+ if (user_procgrid[0] && procgrid[0] != user_procgrid[0]) flag = 1;
+ if (user_procgrid[1] && procgrid[1] != user_procgrid[1]) flag = 1;
+ if (user_procgrid[2] && procgrid[2] != user_procgrid[2]) flag = 1;
+ if (flag) error->all(FLERR,"Processors custom grid file is inconsistent");
+
+ // cmap = map of procs to grid
+ // store for use in custom_map()
+
+ memory->create(cmap,nprocs,4,"procmap:cmap");
+ for (int i = 0; i < nprocs; i++) cmap[i][0] = -1;
+
+ if (me == 0) {
+ for (int i = 0; i < nprocs; i++) {
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of custom file");
+ sscanf(line,"%d %d %d %d",
+ &cmap[i][0],&cmap[i][1],&cmap[i][2],&cmap[i][3]);
+ }
+ fclose(fp);
+ }
+
+ MPI_Bcast(&cmap[0][0],nprocs*4,MPI_INT,0,world);
+
+ // error check on cmap values
+
+ flag = 0;
+ for (int i = 0; i < nprocs; i++) {
+ if (cmap[i][0] == -1) flag = 1;
+ else {
+ if (cmap[i][1] <= 0 || cmap[i][1] > procgrid[0]) flag = 1;
+ if (cmap[i][2] <= 0 || cmap[i][2] > procgrid[1]) flag = 1;
+ if (cmap[i][3] <= 0 || cmap[i][3] > procgrid[2]) flag = 1;
+ }
+ }
+ if (flag) error->all(FLERR,"Processors custom grid file is invalid");
+}
+
+/* ----------------------------------------------------------------------
+ assign nprocs to 3d box so as to minimize surface area
+ area = surface area of each of 3 faces of simulation box divided by sx,sy,sz
+ for triclinic, area = cross product of 2 edge vectors stored in h matrix
+ valid assignment will be factorization of nprocs = Px by Py by Pz
+ user_factors = if non-zero, factors are specified by user
+ sx,sy,sz = scale box xyz dimension by dividing by sx,sy,sz
+ other = 1 to enforce compatability with other partition's layout
+ return factors = # of procs assigned to each dimension
+ return 1 if factor successfully, 0 if not
+------------------------------------------------------------------------- */
+
+int ProcMap::procs2box(int nprocs, int *user_factors, int *factors,
+ const int sx, const int sy, const int sz, int other)
+{
+ factors[0] = user_factors[0];
+ factors[1] = user_factors[1];
+ factors[2] = user_factors[2];
+
+ // all 3 proc counts are specified
+
+ if (factors[0] && factors[1] && factors[2]) return 1;
+
+ // 2 out of 3 proc counts are specified
+
+ if (factors[0] > 0 && factors[1] > 0) {
+ factors[2] = nprocs/(factors[0]*factors[1]);
+ return 1;
+ } else if (factors[0] > 0 && factors[2] > 0) {
+ factors[1] = nprocs/(factors[0]*factors[2]);
+ return 1;
+ } else if (factors[1] > 0 && factors[2] > 0) {
+ factors[0] = nprocs/(factors[1]*factors[2]);
+ return 1;
+ }
+
+ // determine cross-sectional areas for orthogonal and triclinic boxes
+ // area[0] = xy, area[1] = xz, area[2] = yz
+
+ double area[3];
+ if (domain->triclinic == 0) {
+ area[0] = domain->xprd * domain->yprd / (sx * sy);
+ area[1] = domain->xprd * domain->zprd / (sx * sz);
+ area[2] = domain->yprd * domain->zprd / (sy * sz);
+ } else {
+ double *h = domain->h;
+ double a[3],b[3],c[3];
+ a[0] = h[0]; a[1] = 0.0; a[2] = 0.0;
+ b[0] = h[5]; b[1] = h[1]; b[2] = 0.0;
+ MathExtra::cross3(a,b,c);
+ area[0] = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]) / (sx * sy);
+ a[0] = h[0]; a[1] = 0.0; a[2] = 0.0;
+ b[0] = h[4]; b[1] = h[3]; b[2] = h[2];
+ MathExtra::cross3(a,b,c);
+ area[1] = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]) / (sx * sz);
+ a[0] = h[5]; a[1] = h[1]; a[2] = 0.0;
+ b[0] = h[4]; b[1] = h[3]; b[2] = h[2];
+ MathExtra::cross3(a,b,c);
+ area[2] = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]) / (sy * sz);
+ }
+
+ double bestsurf = 2.0 * (area[0]+area[1]+area[2]);
+
+ // loop thru all possible factorizations of nprocs
+ // only consider valid cases that match procgrid settings
+ // surf = surface area of a proc sub-domain
+ // only consider cases that match user_factors & other_procgrid settings
+ // success = 1 if valid factoriztion is found
+ // may not be if other constraint is enforced
+
+ int ipx,ipy,ipz,valid;
+ double surf;
+
+ int success = 0;
+ ipx = 1;
+ while (ipx <= nprocs) {
+ valid = 1;
+ if (user_factors[0] && ipx != user_factors[0]) valid = 0;
+ if (other) {
+ if (other_style == MULTIPLE && other_procgrid[0] % ipx) valid = 0;
+ }
+ if (nprocs % ipx) valid = 0;
+
+ if (!valid) {
+ ipx++;
+ continue;
+ }
+
+ ipy = 1;
+ while (ipy <= nprocs/ipx) {
+ valid = 1;
+ if (user_factors[1] && ipy != user_factors[1]) valid = 0;
+ if (other) {
+ if (other_style == MULTIPLE && other_procgrid[1] % ipy) valid = 0;
+ }
+ if ((nprocs/ipx) % ipy) valid = 0;
+ if (!valid) {
+ ipy++;
+ continue;
+ }
+
+ ipz = nprocs/ipx/ipy;
+ valid = 1;
+ if (user_factors[2] && ipz != user_factors[2]) valid = 0;
+ if (other) {
+ if (other_style == MULTIPLE && other_procgrid[2] % ipz) valid = 0;
+ }
+ if (domain->dimension == 2 && ipz != 1) valid = 0;
+ if (!valid) {
+ ipy++;
+ continue;
+ }
+
+ surf = area[0]/ipx/ipy + area[1]/ipx/ipz + area[2]/ipy/ipz;
+ if (surf < bestsurf) {
+ success = 1;
+ bestsurf = surf;
+ factors[0] = ipx;
+ factors[1] = ipy;
+ factors[2] = ipz;
+ }
+ ipy++;
+ }
+
+ ipx++;
+ }
+
+ return success;
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid via MPI_Cart routines
+ MPI may do layout in machine-optimized fashion
+------------------------------------------------------------------------- */
+
+void ProcMap::cart_map(int reorder, int *procgrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+ int periods[3];
+ periods[0] = periods[1] = periods[2] = 1;
+ MPI_Comm cartesian;
+
+ MPI_Cart_create(world,3,procgrid,periods,reorder,&cartesian);
+ MPI_Cart_get(cartesian,3,procgrid,periods,myloc);
+ MPI_Cart_shift(cartesian,0,1,&procneigh[0][0],&procneigh[0][1]);
+ MPI_Cart_shift(cartesian,1,1,&procneigh[1][0],&procneigh[1][1]);
+ MPI_Cart_shift(cartesian,2,1,&procneigh[2][0],&procneigh[2][1]);
+
+ int coords[3];
+ int i,j,k;
+ for (i = 0; i < procgrid[0]; i++)
+ for (j = 0; j < procgrid[1]; j++)
+ for (k = 0; k < procgrid[2]; k++) {
+ coords[0] = i; coords[1] = j; coords[2] = k;
+ MPI_Cart_rank(cartesian,coords,&grid2proc[i][j][k]);
+ }
+
+ MPI_Comm_free(&cartesian);
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid via MPI_Cart routines
+ respect sub-grid of cores within each node
+ MPI may do layout in machine-optimized fashion
+------------------------------------------------------------------------- */
+
+void ProcMap::cart_map(int reorder, int *procgrid, int *coregrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid in XYZ order
+------------------------------------------------------------------------- */
+
+void ProcMap::xyz_map(char *xyz, int *procgrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+ int me;
+ MPI_Comm_rank(world,&me);
+
+ int i,j,k;
+ for (i = 0; i < procgrid[0]; i++)
+ for (j = 0; j < procgrid[1]; j++)
+ for (k = 0; k < procgrid[2]; k++) {
+ grid2proc[i][j][k] = k*procgrid[1]*procgrid[0] + j*procgrid[0] + i;
+ if (xyz[0] == 'x' && xyz[1] == 'y' && xyz[2] == 'z')
+ grid2proc[i][j][k] = k*procgrid[1]*procgrid[0] + j*procgrid[0] + i;
+ else if (xyz[0] == 'x' && xyz[1] == 'z' && xyz[2] == 'y')
+ grid2proc[i][j][k] = j*procgrid[2]*procgrid[0] + k*procgrid[0] + i;
+ else if (xyz[0] == 'y' && xyz[1] == 'x' && xyz[2] == 'z')
+ grid2proc[i][j][k] = k*procgrid[0]*procgrid[1] + i*procgrid[1] + j;
+ else if (xyz[0] == 'y' && xyz[1] == 'z' && xyz[2] == 'x')
+ grid2proc[i][j][k] = i*procgrid[2]*procgrid[1] + k*procgrid[1] + j;
+ else if (xyz[0] == 'z' && xyz[1] == 'x' && xyz[2] == 'y')
+ grid2proc[i][j][k] = j*procgrid[0]*procgrid[2] + i*procgrid[2] + k;
+ else if (xyz[0] == 'z' && xyz[1] == 'y' && xyz[2] == 'x')
+ grid2proc[i][j][k] = i*procgrid[1]*procgrid[2] + j*procgrid[2] + k;
+
+ if (grid2proc[i][j][k] == me) {
+ myloc[0] = i; myloc[1] = j, myloc[2] = k;
+ }
+ }
+
+ int minus,plus;
+ grid_shift(myloc[0],procgrid[0],minus,plus);
+ procneigh[0][0] = grid2proc[minus][myloc[1]][myloc[2]];
+ procneigh[0][1] = grid2proc[plus][myloc[1]][myloc[2]];
+
+ grid_shift(myloc[1],procgrid[1],minus,plus);
+ procneigh[1][0] = grid2proc[myloc[0]][minus][myloc[2]];
+ procneigh[1][1] = grid2proc[myloc[0]][plus][myloc[2]];
+
+ grid_shift(myloc[2],procgrid[2],minus,plus);
+ procneigh[2][0] = grid2proc[myloc[0]][myloc[1]][minus];
+ procneigh[2][1] = grid2proc[myloc[0]][myloc[1]][plus];
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid in XYZ order
+ respect sub-grid of cores within each node
+------------------------------------------------------------------------- */
+
+void ProcMap::xyz_map(char *xyz, int *procgrid, int *coregrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid in 2-level NUMA ordering
+------------------------------------------------------------------------- */
+
+void ProcMap::numa_map(int *numagrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+ // setup a per node communicator and find rank within
+
+ MPI_Comm node_comm;
+ MPI_Comm_split(world,node_id,0,&node_comm);
+ int node_rank;
+ MPI_Comm_rank(node_comm,&node_rank);
+
+ // setup a per numa communicator and find rank within
+
+ MPI_Comm numa_comm;
+ int local_numa = node_rank / procs_per_numa;
+ MPI_Comm_split(node_comm,local_numa,0,&numa_comm);
+ int numa_rank;
+ MPI_Comm_rank(numa_comm,&numa_rank);
+
+ // setup a communicator with the rank 0 procs from each numa node
+
+ MPI_Comm numa_leaders;
+ MPI_Comm_split(world,numa_rank,0,&numa_leaders);
+
+ // use the MPI Cartesian routines to map the nodes to the grid
+ // could implement xyz mapflag as in non-NUMA case?
+
+ int reorder = 0;
+ int periods[3];
+ periods[0] = periods[1] = periods[2] = 1;
+ MPI_Comm cartesian;
+ if (numa_rank == 0) {
+ MPI_Cart_create(numa_leaders,3,nodegrid,periods,reorder,&cartesian);
+ MPI_Cart_get(cartesian,3,nodegrid,periods,myloc);
+ }
+
+ // broadcast numa node location in grid to other procs in numa node
+
+ MPI_Bcast(myloc,3,MPI_INT,0,numa_comm);
+
+ // compute my location within the node grid
+
+ int z_offset = numa_rank / (numagrid[0] * numagrid[1]);
+ int y_offset = (numa_rank % (numagrid[0] * numagrid[1]))/numagrid[0];
+ int x_offset = numa_rank % numagrid[0];
+ myloc[0] = myloc[0] * numagrid[0] + x_offset;
+ myloc[1] = myloc[1] * numagrid[1] + y_offset;
+ myloc[2] = myloc[2] * numagrid[2] + z_offset;
+
+ // allgather of locations to fill grid2proc
+
+ int nprocs;
+ MPI_Comm_size(world,&nprocs);
+
+ int **gridi;
+ memory->create(gridi,nprocs,3,"comm:gridi");
+ MPI_Allgather(&myloc,3,MPI_INT,gridi[0],3,MPI_INT,world);
+ for (int i = 0; i < nprocs; i++)
+ grid2proc[gridi[i][0]][gridi[i][1]][gridi[i][2]] = i;
+ memory->destroy(gridi);
+
+ // proc IDs of neighbors
+
+ int minus,plus;
+ grid_shift(myloc[0],nodegrid[0]*numagrid[0],minus,plus);
+ procneigh[0][0] = grid2proc[minus][myloc[1]][myloc[2]];
+ procneigh[0][1] = grid2proc[plus][myloc[1]][myloc[2]];
+
+ grid_shift(myloc[1],nodegrid[1]*numagrid[1],minus,plus);
+ procneigh[1][0] = grid2proc[myloc[0]][minus][myloc[2]];
+ procneigh[1][1] = grid2proc[myloc[0]][plus][myloc[2]];
+
+ grid_shift(myloc[2],nodegrid[2]*numagrid[2],minus,plus);
+ procneigh[2][0] = grid2proc[myloc[0]][myloc[1]][minus];
+ procneigh[2][1] = grid2proc[myloc[0]][myloc[1]][plus];
+
+ // clean-up
+
+ if (numa_rank == 0) MPI_Comm_free(&cartesian);
+ MPI_Comm_free(&numa_leaders);
+ MPI_Comm_free(&numa_comm);
+ MPI_Comm_free(&node_comm);
+}
+
+/* ----------------------------------------------------------------------
+ map processors to 3d grid in custom ordering
+------------------------------------------------------------------------- */
+
+void ProcMap::custom_map(int *procgrid,
+ int *myloc, int procneigh[3][2], int ***grid2proc)
+{
+ int me,nprocs;
+ MPI_Comm_rank(world,&me);
+ MPI_Comm_size(world,&nprocs);
+
+ for (int i = 0; i < nprocs; i++) {
+ grid2proc[cmap[i][1]-1][cmap[i][2]-1][cmap[i][3]-1] = cmap[i][0];
+ if (cmap[i][0] == me) {
+ myloc[0] = cmap[i][1] - 1;
+ myloc[1] = cmap[i][2] - 1;
+ myloc[2] = cmap[i][3] - 1;
+ }
+ }
+
+ int minus,plus;
+ grid_shift(myloc[0],procgrid[0],minus,plus);
+ procneigh[0][0] = grid2proc[minus][myloc[1]][myloc[2]];
+ procneigh[0][1] = grid2proc[plus][myloc[1]][myloc[2]];
+
+ grid_shift(myloc[1],procgrid[1],minus,plus);
+ procneigh[1][0] = grid2proc[myloc[0]][minus][myloc[2]];
+ procneigh[1][1] = grid2proc[myloc[0]][plus][myloc[2]];
+
+ grid_shift(myloc[2],procgrid[2],minus,plus);
+ procneigh[2][0] = grid2proc[myloc[0]][myloc[1]][minus];
+ procneigh[2][1] = grid2proc[myloc[0]][myloc[1]][plus];
+
+ memory->destroy(cmap);
+}
+
+/* ----------------------------------------------------------------------
+ minus,plus = indices of neighboring processors in a dimension
+------------------------------------------------------------------------- */
+
+void ProcMap::grid_shift(int myloc, int nprocs, int &minus, int &plus)
+{
+ minus = myloc - 1;
+ if (minus < 0) minus = nprocs - 1;
+ plus = myloc + 1;
+ if (plus == nprocs) plus = 0;
+}
+
+/* ----------------------------------------------------------------------
+ output mapping of processors to 3d grid to file
+------------------------------------------------------------------------- */
+
+void ProcMap::output(char *file, int *procgrid, int ***grid2proc)
+{
+ int me,nprocs;
+ MPI_Comm_rank(world,&me);
+ MPI_Comm_size(world,&nprocs);
+
+ FILE *fp;
+ if (me == 0) {
+ fp = fopen(file,"w");
+ if (fp == NULL) error->one(FLERR,"Cannot open processors custom file");
+ fprintf(fp,"LAMMPS mapping of processors to 3d grid\n");
+ fprintf(fp,"partition = %d\n",universe->iworld+1);
+ fprintf(fp,"Px Py Pz = %d %d %d\n",procgrid[0],procgrid[1],procgrid[2]);
+ fprintf(fp,"world-ID universe-ID original-ID: I J K: name\n\n");
+ }
+
+ // find me in the grid
+
+ int ime,jme,kme;
+ for (int i = 0; i < procgrid[0]; i++)
+ for (int j = 0; j < procgrid[1]; j++)
+ for (int k = 0; k < procgrid[2]; k++)
+ if (grid2proc[i][j][k] == me) {
+ ime = i; jme = j; kme = k;
+ }
+
+ // polled comm of grid mapping info from each proc to proc 0
+
+ int tmp;
+ int vec[6];
+ char procname[MPI_MAX_PROCESSOR_NAME+1];
+ MPI_Status status;
+
+ vec[0] = me;
+ vec[1] = universe->me;
+ MPI_Comm_rank(universe->uorig,&vec[2]);
+ vec[3] = ime + 1;
+ vec[4] = jme + 1;
+ vec[5] = kme + 1;
+
+ int len;
+ MPI_Get_processor_name(procname,&len);
+ procname[len] = '\0';
+
+ if (me == 0) {
+ for (int iproc = 0; iproc < nprocs; iproc++) {
+ if (iproc) {
+ MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
+ MPI_Recv(vec,6,MPI_INT,iproc,0,world,&status);
+ MPI_Recv(procname,MPI_MAX_PROCESSOR_NAME+1,MPI_CHAR,
+ iproc,0,world,&status);
+ }
+
+ fprintf(fp,"%d %d %d: %d %d %d: %s\n",
+ vec[0],vec[1],vec[2],vec[3],vec[4],vec[5],procname);
+ }
+
+ } else {
+ MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
+ MPI_Send(vec,6,MPI_INT,0,0,world);
+ MPI_Send(procname,strlen(procname)+1,MPI_CHAR,0,0,world);
+ }
+
+ // close output file
+
+ if (me == 0) fclose(fp);
+}
diff --git a/src/procmap.h b/src/procmap.h
new file mode 100644
index 000000000..80d9b5a0e
--- /dev/null
+++ b/src/procmap.h
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifndef LMP_PROCMAP_H
+#define LMP_PROCMAP_H
+
+#include "pointers.h"
+
+namespace LAMMPS_NS {
+
+class ProcMap : protected Pointers {
+ public:
+ ProcMap(class LAMMPS *);
+ ~ProcMap() {}
+ int onelevel_grid(int, int *, int *, int, int, int *);
+ int twolevel_grid(int, int *, int *, int, int *, int *, int, int, int *);
+ int numa_grid(int, int *, int *, int *);
+ void custom_grid(char *, int, int *, int *);
+ void cart_map(int, int *, int *, int [3][2], int ***);
+ void cart_map(int, int *, int *, int *, int [3][2], int ***);
+ void xyz_map(char *, int *, int *, int [3][2], int ***);
+ void xyz_map(char *, int *, int *, int *, int [3][2], int ***);
+ void numa_map(int *, int *, int [3][2], int ***);
+ void custom_map(int *, int *, int [3][2], int ***);
+ void output(char *, int *, int ***);
+
+ private:
+ int other_style;
+ int other_procgrid[3];
+ int nodegrid[3];
+ int node_id;
+ int procs_per_node;
+ int procs_per_numa;
+ int **cmap;
+
+ int procs2box(int, int *, int *, const int, const int, const int, int);
+ void grid_shift(int, int, int &, int &);
+};
+
+}
+
+#endif
diff --git a/src/random_mars.cpp b/src/random_mars.cpp
index 2430eabd5..0dd599036 100644
--- a/src/random_mars.cpp
+++ b/src/random_mars.cpp
@@ -1,115 +1,115 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
// Marsaglia random number generator
#include "math.h"
#include "random_mars.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
RanMars::RanMars(LAMMPS *lmp, int seed) : Pointers(lmp)
{
int ij,kl,i,j,k,l,ii,jj,m;
double s,t;
if (seed <= 0 || seed > 900000000)
- error->all(FLERR,"Invalid seed for Marsaglia random # generator");
+ error->one(FLERR,"Invalid seed for Marsaglia random # generator");
save = 0;
u = new double[97+1];
ij = (seed-1)/30082;
kl = (seed-1) - 30082*ij;
i = (ij/177) % 177 + 2;
j = ij %177 + 2;
k = (kl/169) % 178 + 1;
l = kl % 169;
for (ii = 1; ii <= 97; ii++) {
s = 0.0;
t = 0.5;
for (jj = 1; jj <= 24; jj++) {
m = ((i*j) % 179)*k % 179;
i = j;
j = k;
k = m;
l = (53*l+1) % 169;
if ((l*m) % 64 >= 32) s = s + t;
t = 0.5*t;
}
u[ii] = s;
}
c = 362436.0 / 16777216.0;
cd = 7654321.0 / 16777216.0;
cm = 16777213.0 / 16777216.0;
i97 = 97;
j97 = 33;
uniform();
}
/* ---------------------------------------------------------------------- */
RanMars::~RanMars()
{
delete [] u;
}
/* ----------------------------------------------------------------------
uniform RN
------------------------------------------------------------------------- */
double RanMars::uniform()
{
double uni = u[i97] - u[j97];
if (uni < 0.0) uni += 1.0;
u[i97] = uni;
i97--;
if (i97 == 0) i97 = 97;
j97--;
if (j97 == 0) j97 = 97;
c -= cd;
if (c < 0.0) c += cm;
uni -= c;
if (uni < 0.0) uni += 1.0;
return uni;
}
/* ----------------------------------------------------------------------
gaussian RN
------------------------------------------------------------------------- */
double RanMars::gaussian()
{
double first,v1,v2,rsq,fac;
if (!save) {
int again = 1;
while (again) {
v1 = 2.0*uniform()-1.0;
v2 = 2.0*uniform()-1.0;
rsq = v1*v1 + v2*v2;
if (rsq < 1.0 && rsq != 0.0) again = 0;
}
fac = sqrt(-2.0*log(rsq)/rsq);
second = v1*fac;
first = v2*fac;
save = 1;
} else {
first = second;
save = 0;
}
return first;
}
diff --git a/src/random_park.cpp b/src/random_park.cpp
index 6867a61a5..3e53aee20 100644
--- a/src/random_park.cpp
+++ b/src/random_park.cpp
@@ -1,145 +1,145 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
// Park/Miller RNG
#include "math.h"
#include "random_park.h"
#include "error.h"
using namespace LAMMPS_NS;
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define IA1 1366
#define IC1 150889
#define IM1 714025
#define IA2 8121
#define IC2 28411
#define IM2 134456
#define IA3 7141
#define IC3 54773
#define IM3 259200
/* ---------------------------------------------------------------------- */
RanPark::RanPark(LAMMPS *lmp, int seed_init) : Pointers(lmp)
{
if (seed_init <= 0)
- error->all(FLERR,"Invalid seed for Park random # generator");
+ error->one(FLERR,"Invalid seed for Park random # generator");
seed = seed_init;
save = 0;
}
/* ----------------------------------------------------------------------
uniform RN
------------------------------------------------------------------------- */
double RanPark::uniform()
{
int k = seed/IQ;
seed = IA*(seed-k*IQ) - IR*k;
if (seed < 0) seed += IM;
double ans = AM*seed;
return ans;
}
/* ----------------------------------------------------------------------
gaussian RN
------------------------------------------------------------------------- */
double RanPark::gaussian()
{
double first,v1,v2,rsq,fac;
if (!save) {
int again = 1;
while (again) {
v1 = 2.0*uniform()-1.0;
v2 = 2.0*uniform()-1.0;
rsq = v1*v1 + v2*v2;
if (rsq < 1.0 && rsq != 0.0) again = 0;
}
fac = sqrt(-2.0*log(rsq)/rsq);
second = v1*fac;
first = v2*fac;
save = 1;
} else {
first = second;
save = 0;
}
return first;
}
/* ---------------------------------------------------------------------- */
void RanPark::reset(int seed_init)
{
if (seed_init <= 0)
error->all(FLERR,"Invalid seed for Park random # generator");
seed = seed_init;
save = 0;
}
/* ----------------------------------------------------------------------
reset the seed based on atom coords and ibase = caller seed
use hash function, treating user seed and coords as sequence of input ints
this is Jenkins One-at-a-time hash, see Wikipedia entry on hash tables
------------------------------------------------------------------------- */
void RanPark::reset(int ibase, double *coord)
{
int i;
char *str = (char *) &ibase;
int n = sizeof(int);
unsigned int hash = 0;
for (i = 0; i < n; i++) {
hash += str[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
str = (char *) coord;
n = 3 * sizeof(double);
for (i = 0; i < n; i++) {
hash += str[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
// keep 31 bits of unsigned int as new seed
seed = hash & 0x7ffffff;
// warm up the RNG
for (i = 0; i < 5; i++) uniform();
save = 0;
}
/* ---------------------------------------------------------------------- */
int RanPark::state()
{
return seed;
}
diff --git a/src/read_data.cpp b/src/read_data.cpp
index a96a566b0..872076b11 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -1,1448 +1,1448 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "math.h"
#include "mpi.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "read_data.h"
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
#include "atom_vec_line.h"
#include "atom_vec_tri.h"
#include "comm.h"
#include "update.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "error.h"
#include "memory.h"
#include "special.h"
using namespace LAMMPS_NS;
#define MAXLINE 256
#define LB_FACTOR 1.1
#define CHUNK 1024
#define DELTA 4 // must be 2 or larger
// customize for new sections
#define NSECTIONS 23 // change when add to header::section_keywords
/* ---------------------------------------------------------------------- */
ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
line = new char[MAXLINE];
keyword = new char[MAXLINE];
buffer = new char[CHUNK*MAXLINE];
narg = maxarg = 0;
arg = NULL;
// customize for new sections
// pointers to atom styles that store extra info
nellipsoids = 0;
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
nlines = 0;
avec_line = (AtomVecLine *) atom->style_match("line");
ntris = 0;
avec_tri = (AtomVecTri *) atom->style_match("tri");
}
/* ---------------------------------------------------------------------- */
ReadData::~ReadData()
{
delete [] line;
delete [] keyword;
delete [] buffer;
memory->sfree(arg);
}
/* ---------------------------------------------------------------------- */
void ReadData::command(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal read_data command");
if (domain->box_exist)
error->all(FLERR,"Cannot read_data after simulation box is defined");
if (domain->dimension == 2 && domain->zperiodic == 0)
error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension");
// scan data file to determine max topology needed per atom
// allocate initial topology arrays
if (atom->molecular) {
if (me == 0) {
if (screen) fprintf(screen,"Scanning data file ...\n");
open(arg[0]);
header(0);
scan(atom->bond_per_atom,atom->angle_per_atom,
atom->dihedral_per_atom,atom->improper_per_atom);
if (compressed) pclose(fp);
else fclose(fp);
atom->bond_per_atom += atom->extra_bond_per_atom;
}
MPI_Bcast(&atom->bond_per_atom,1,MPI_INT,0,world);
MPI_Bcast(&atom->angle_per_atom,1,MPI_INT,0,world);
MPI_Bcast(&atom->dihedral_per_atom,1,MPI_INT,0,world);
MPI_Bcast(&atom->improper_per_atom,1,MPI_INT,0,world);
} else
atom->bond_per_atom = atom->angle_per_atom =
atom->dihedral_per_atom = atom->improper_per_atom = 0;
// read header info
if (me == 0) {
if (screen) fprintf(screen,"Reading data file ...\n");
open(arg[0]);
}
header(1);
domain->box_exist = 1;
// problem setup using info from header
update->ntimestep = 0;
int n;
if (comm->nprocs == 1) n = static_cast<int> (atom->natoms);
else n = static_cast<int> (LB_FACTOR * atom->natoms / comm->nprocs);
atom->allocate_type_arrays();
atom->avec->grow(n);
n = atom->nmax;
domain->print_box(" ");
domain->set_initial_box();
domain->set_global_box();
- comm->set_procs();
+ comm->set_proc_grid();
domain->set_local_box();
// customize for new sections
// read rest of file in free format
int atomflag = 0;
while (strlen(keyword)) {
if (strcmp(keyword,"Atoms") == 0) {
atoms();
atomflag = 1;
} else if (strcmp(keyword,"Velocities") == 0) {
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Velocities");
velocities();
} else if (strcmp(keyword,"Ellipsoids") == 0) {
if (!avec_ellipsoid)
error->all(FLERR,"Invalid data file section: Ellipsoids");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
} else if (strcmp(keyword,"Lines") == 0) {
if (!avec_line)
error->all(FLERR,"Invalid data file section: Lines");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
bonus(nlines,(AtomVec *) avec_line,"lines");
} else if (strcmp(keyword,"Triangles") == 0) {
if (!avec_tri)
error->all(FLERR,"Invalid data file section: Triangles");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
bonus(ntris,(AtomVec *) avec_tri,"triangles");
} else if (strcmp(keyword,"Bonds") == 0) {
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Invalid data file section: Bonds");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds");
bonds();
} else if (strcmp(keyword,"Angles") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: Angles");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles");
angles();
} else if (strcmp(keyword,"Dihedrals") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: Dihedrals");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals");
dihedrals();
} else if (strcmp(keyword,"Impropers") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: Impropers");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers");
impropers();
} else if (strcmp(keyword,"Masses") == 0) {
mass();
} else if (strcmp(keyword,"Pair Coeffs") == 0) {
if (force->pair == NULL)
error->all(FLERR,"Must define pair_style before Pair Coeffs");
paircoeffs();
} else if (strcmp(keyword,"Bond Coeffs") == 0) {
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Invalid data file section: Bond Coeffs");
if (force->bond == NULL)
error->all(FLERR,"Must define bond_style before Bond Coeffs");
bondcoeffs();
} else if (strcmp(keyword,"Angle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: Angle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before Angle Coeffs");
anglecoeffs(0);
} else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: Dihedral Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs");
dihedralcoeffs(0);
} else if (strcmp(keyword,"Improper Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: Improper Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before Improper Coeffs");
impropercoeffs(0);
} else if (strcmp(keyword,"BondBond Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondBond Coeffs");
anglecoeffs(1);
} else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondAngle Coeffs");
anglecoeffs(2);
} else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"MiddleBondTorsion Coeffs");
dihedralcoeffs(1);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before EndBondTorsion Coeffs");
dihedralcoeffs(2);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before AngleTorsion Coeffs");
dihedralcoeffs(3);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"AngleAngleTorsion Coeffs");
dihedralcoeffs(4);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
dihedralcoeffs(5);
} else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before AngleAngle Coeffs");
impropercoeffs(1);
} else {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->all(FLERR,str);
}
parse_keyword(0,1);
}
// close file
if (me == 0) {
if (compressed) pclose(fp);
else fclose(fp);
}
// error if natoms > 0 yet no atoms were read
if (atom->natoms > 0 && atomflag == 0)
error->all(FLERR,"No atoms in data file");
// create bond topology now that system is defined
if (atom->molecular) {
Special special(lmp);
special.build();
}
}
/* ----------------------------------------------------------------------
read free-format header of data file
if flag = 0, only called by proc 0
if flag = 1, called by all procs so bcast lines as read them
1st line and blank lines are skipped
non-blank lines are checked for header keywords and leading value is read
header ends with EOF or non-blank line containing no header keyword
if EOF, line is set to blank line
else line has first keyword line for rest of file
------------------------------------------------------------------------- */
void ReadData::header(int flag)
{
int n;
char *ptr;
// customize for new sections
char *section_keywords[NSECTIONS] =
{"Atoms","Velocities","Ellipsoids","Lines","Triangles",
"Bonds","Angles","Dihedrals","Impropers",
"Masses","Pair Coeffs","Bond Coeffs","Angle Coeffs",
"Dihedral Coeffs","Improper Coeffs",
"BondBond Coeffs","BondAngle Coeffs","MiddleBondTorsion Coeffs",
"EndBondTorsion Coeffs","AngleTorsion Coeffs",
"AngleAngleTorsion Coeffs","BondBond13 Coeffs","AngleAngle Coeffs"};
// skip 1st line of file
if (me == 0) {
char *eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
}
// customize for new header lines
while (1) {
// read a line and bcast length if flag is set
if (me == 0) {
if (fgets(line,MAXLINE,fp) == NULL) n = 0;
else n = strlen(line) + 1;
}
if (flag) MPI_Bcast(&n,1,MPI_INT,0,world);
// if n = 0 then end-of-file so return with blank line
if (n == 0) {
line[0] = '\0';
return;
}
// bcast line if flag is set
if (flag) MPI_Bcast(line,n,MPI_CHAR,0,world);
// trim anything from '#' onward
// if line is blank, continue
if (ptr = strchr(line,'#')) *ptr = '\0';
if (strspn(line," \t\n\r") == strlen(line)) continue;
// search line for header keyword and set corresponding variable
if (strstr(line,"atoms")) sscanf(line,BIGINT_FORMAT,&atom->natoms);
else if (strstr(line,"bonds")) sscanf(line,BIGINT_FORMAT,&atom->nbonds);
else if (strstr(line,"angles")) sscanf(line,BIGINT_FORMAT,&atom->nangles);
else if (strstr(line,"dihedrals")) sscanf(line,BIGINT_FORMAT,
&atom->ndihedrals);
else if (strstr(line,"impropers")) sscanf(line,BIGINT_FORMAT,
&atom->nimpropers);
else if (strstr(line,"atom types")) sscanf(line,"%d",&atom->ntypes);
else if (strstr(line,"bond types")) sscanf(line,"%d",&atom->nbondtypes);
else if (strstr(line,"angle types")) sscanf(line,"%d",&atom->nangletypes);
else if (strstr(line,"dihedral types"))
sscanf(line,"%d",&atom->ndihedraltypes);
else if (strstr(line,"improper types"))
sscanf(line,"%d",&atom->nimpropertypes);
else if (strstr(line,"extra bond per atom"))
sscanf(line,"%d",&atom->extra_bond_per_atom);
else if (strstr(line,"ellipsoids")) {
if (!avec_ellipsoid)
error->all(FLERR,"No ellipsoids allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nellipsoids);
} else if (strstr(line,"lines")) {
if (!avec_line)
error->all(FLERR,"No lines allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nlines);
} else if (strstr(line,"triangles")) {
if (!avec_tri)
error->all(FLERR,"No triangles allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&ntris);
}
else if (strstr(line,"xlo xhi"))
sscanf(line,"%lg %lg",&domain->boxlo[0],&domain->boxhi[0]);
else if (strstr(line,"ylo yhi"))
sscanf(line,"%lg %lg",&domain->boxlo[1],&domain->boxhi[1]);
else if (strstr(line,"zlo zhi"))
sscanf(line,"%lg %lg",&domain->boxlo[2],&domain->boxhi[2]);
else if (strstr(line,"xy xz yz")) {
domain->triclinic = 1;
sscanf(line,"%lg %lg %lg",&domain->xy,&domain->xz,&domain->yz);
} else break;
}
// error check on total system size
if (atom->natoms < 0 || atom->natoms > MAXBIGINT ||
atom->nbonds < 0 || atom->nbonds > MAXBIGINT ||
atom->nangles < 0 || atom->nangles > MAXBIGINT ||
atom->ndihedrals < 0 || atom->ndihedrals > MAXBIGINT ||
atom->nimpropers < 0 || atom->nimpropers > MAXBIGINT) {
if (flag == 0) error->one(FLERR,"System in data file is too big");
else error->all(FLERR,"System in data file is too big");
}
// check that exiting string is a valid section keyword
parse_keyword(1,flag);
for (n = 0; n < NSECTIONS; n++)
if (strcmp(keyword,section_keywords[n]) == 0) break;
if (n == NSECTIONS) {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->all(FLERR,str);
}
// error check on consistency of header values
if ((atom->nbonds || atom->nbondtypes) &&
atom->avec->bonds_allow == 0)
error->one(FLERR,"No bonds allowed with this atom style");
if ((atom->nangles || atom->nangletypes) &&
atom->avec->angles_allow == 0)
error->one(FLERR,"No angles allowed with this atom style");
if ((atom->ndihedrals || atom->ndihedraltypes) &&
atom->avec->dihedrals_allow == 0)
error->one(FLERR,"No dihedrals allowed with this atom style");
if ((atom->nimpropers || atom->nimpropertypes) &&
atom->avec->impropers_allow == 0)
error->one(FLERR,"No impropers allowed with this atom style");
if (atom->nbonds > 0 && atom->nbondtypes <= 0)
error->one(FLERR,"Bonds defined but no bond types");
if (atom->nangles > 0 && atom->nangletypes <= 0)
error->one(FLERR,"Angles defined but no angle types");
if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0)
error->one(FLERR,"Dihedrals defined but no dihedral types");
if (atom->nimpropers > 0 && atom->nimpropertypes <= 0)
error->one(FLERR,"Impropers defined but no improper types");
}
/* ----------------------------------------------------------------------
read all atoms
------------------------------------------------------------------------- */
void ReadData::atoms()
{
int i,m,nchunk;
bigint nread = 0;
bigint natoms = atom->natoms;
while (nread < natoms) {
if (natoms-nread > CHUNK) nchunk = CHUNK;
else nchunk = natoms-nread;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_atoms(nchunk,buffer);
nread += nchunk;
}
// check that all atoms were assigned correctly
bigint tmp = atom->nlocal;
MPI_Allreduce(&tmp,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
if (natoms != atom->natoms)
error->all(FLERR,"Did not assign all atoms correctly");
// if any atom ID < 0, error
// if all atom IDs = 0, tag_enable = 0
// if any atom ID > 0, error if any atom ID == 0
// not checking if atom IDs > natoms or are unique
int nlocal = atom->nlocal;
int *tag = atom->tag;
int flag = 0;
for (int i = 0; i < nlocal; i++)
if (tag[i] < 0) flag = 1;
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all)
error->all(FLERR,"Invalid atom ID in Atoms section of data file");
flag = 0;
for (int i = 0; i < nlocal; i++)
if (tag[i] > 0) flag = 1;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
if (flag_all == 0) atom->tag_enable = 0;
if (atom->tag_enable) {
flag = 0;
for (int i = 0; i < nlocal; i++)
if (tag[i] == 0) flag = 1;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all)
error->all(FLERR,"Invalid atom ID in Atoms section of data file");
}
// create global mapping
if (atom->map_style) {
atom->map_init();
atom->map_set();
}
}
/* ----------------------------------------------------------------------
read all velocities
to find atoms, must build atom map if not a molecular system
------------------------------------------------------------------------- */
void ReadData::velocities()
{
int i,m,nchunk;
int mapflag = 0;
if (atom->map_style == 0) {
mapflag = 1;
atom->map_style = 1;
atom->map_init();
atom->map_set();
}
bigint nread = 0;
bigint natoms = atom->natoms;
while (nread < natoms) {
if (natoms-nread > CHUNK) nchunk = CHUNK;
else nchunk = natoms-nread;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_vels(nchunk,buffer);
nread += nchunk;
}
if (mapflag) {
atom->map_delete();
atom->map_style = 0;
}
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " velocities\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " velocities\n",natoms);
}
}
/* ----------------------------------------------------------------------
read all bonus data
to find atoms, must build atom map if not a molecular system
------------------------------------------------------------------------- */
void ReadData::bonus(bigint nbonus, AtomVec *ptr, char *type)
{
int i,m,nchunk;
int mapflag = 0;
if (atom->map_style == 0) {
mapflag = 1;
atom->map_style = 1;
atom->map_init();
atom->map_set();
}
bigint nread = 0;
bigint natoms = nbonus;
while (nread < natoms) {
if (natoms-nread > CHUNK) nchunk = CHUNK;
else nchunk = natoms-nread;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_bonus(nchunk,buffer,ptr);
nread += nchunk;
}
if (mapflag) {
atom->map_delete();
atom->map_style = 0;
}
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type);
}
}
/* ---------------------------------------------------------------------- */
void ReadData::bonds()
{
int i,m,nchunk;
bigint nread = 0;
bigint nbonds = atom->nbonds;
while (nread < nbonds) {
nchunk = MIN(nbonds-nread,CHUNK);
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_bonds(nchunk,buffer);
nread += nchunk;
}
// check that bonds were assigned correctly
int nlocal = atom->nlocal;
bigint sum;
bigint n = 0;
for (i = 0; i < nlocal; i++) n += atom->num_bond[i];
MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 2;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor);
}
if (sum != factor*atom->nbonds)
error->all(FLERR,"Bonds assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
void ReadData::angles()
{
int i,m,nchunk;
bigint nread = 0;
bigint nangles = atom->nangles;
while (nread < nangles) {
nchunk = MIN(nangles-nread,CHUNK);
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_angles(nchunk,buffer);
nread += nchunk;
}
// check that ang
int nlocal = atom->nlocal;
bigint sum;
bigint n = 0;
for (i = 0; i < nlocal; i++) n += atom->num_angle[i];
MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 3;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor);
}
if (sum != factor*atom->nangles)
error->all(FLERR,"Angles assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
void ReadData::dihedrals()
{
int i,m,nchunk;
bigint nread = 0;
bigint ndihedrals = atom->ndihedrals;
while (nread < ndihedrals) {
nchunk = MIN(ndihedrals-nread,CHUNK);
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_dihedrals(nchunk,buffer);
nread += nchunk;
}
// check that dihedrals were assigned correctly
int nlocal = atom->nlocal;
bigint sum;
bigint n = 0;
for (i = 0; i < nlocal; i++) n += atom->num_dihedral[i];
MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 4;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",sum/factor);
}
if (sum != factor*atom->ndihedrals)
error->all(FLERR,"Dihedrals assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
void ReadData::impropers()
{
int i,m,nchunk;
bigint nread = 0;
bigint nimpropers = atom->nimpropers;
while (nread < nimpropers) {
nchunk = MIN(nimpropers-nread,CHUNK);
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < nchunk; i++) {
eof = fgets(&buffer[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_impropers(nchunk,buffer);
nread += nchunk;
}
// check that impropers were assigned correctly
int nlocal = atom->nlocal;
bigint sum;
bigint n = 0;
for (i = 0; i < nlocal; i++) n += atom->num_improper[i];
MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 4;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",sum/factor);
}
if (sum != factor*atom->nimpropers)
error->all(FLERR,"Impropers assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
void ReadData::mass()
{
int i,m;
char *buf = new char[atom->ntypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->ntypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->ntypes; i++) {
atom->set_mass(buf);
buf += strlen(buf) + 1;
}
delete [] original;
}
/* ---------------------------------------------------------------------- */
void ReadData::paircoeffs()
{
int i,m;
char *buf = new char[atom->ntypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->ntypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->ntypes; i++) {
m = strlen(buf) + 1;
parse_coeffs(buf,NULL,1);
force->pair->coeff(narg,arg);
buf += m;
}
delete [] original;
}
/* ---------------------------------------------------------------------- */
void ReadData::bondcoeffs()
{
int i,m;
char *buf = new char[atom->nbondtypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->nbondtypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->nbondtypes; i++) {
m = strlen(buf) + 1;
parse_coeffs(buf,NULL,0);
force->bond->coeff(narg,arg);
buf += m;
}
delete [] original;
}
/* ---------------------------------------------------------------------- */
void ReadData::anglecoeffs(int which)
{
int i,m;
char *buf = new char[atom->nangletypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->nangletypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->nangletypes; i++) {
m = strlen(buf) + 1;
if (which == 0) parse_coeffs(buf,NULL,0);
else if (which == 1) parse_coeffs(buf,"bb",0);
else if (which == 2) parse_coeffs(buf,"ba",0);
force->angle->coeff(narg,arg);
buf += m;
}
delete [] original;
}
/* ---------------------------------------------------------------------- */
void ReadData::dihedralcoeffs(int which)
{
int i,m;
char *buf = new char[atom->ndihedraltypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->ndihedraltypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->ndihedraltypes; i++) {
m = strlen(buf) + 1;
if (which == 0) parse_coeffs(buf,NULL,0);
else if (which == 1) parse_coeffs(buf,"mbt",0);
else if (which == 2) parse_coeffs(buf,"ebt",0);
else if (which == 3) parse_coeffs(buf,"at",0);
else if (which == 4) parse_coeffs(buf,"aat",0);
else if (which == 5) parse_coeffs(buf,"bb13",0);
force->dihedral->coeff(narg,arg);
buf += m;
}
delete [] original;
}
/* ---------------------------------------------------------------------- */
void ReadData::impropercoeffs(int which)
{
int i,m;
char *buf = new char[atom->nimpropertypes*MAXLINE];
char *original = buf;
if (me == 0) {
char *eof;
m = 0;
for (i = 0; i < atom->nimpropertypes; i++) {
eof = fgets(&buf[m],MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
m += strlen(&buf[m]);
buf[m-1] = '\0';
}
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buf,m,MPI_CHAR,0,world);
for (i = 0; i < atom->nimpropertypes; i++) {
m = strlen(buf) + 1;
if (which == 0) parse_coeffs(buf,NULL,0);
else if (which == 1) parse_coeffs(buf,"aa",0);
force->improper->coeff(narg,arg);
buf += m;
}
delete [] original;
}
/* ----------------------------------------------------------------------
proc 0 scans the data file for topology maximums
------------------------------------------------------------------------- */
void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
int &dihedral_per_atom, int &improper_per_atom)
{
int i,tmp1,tmp2,atom1,atom2,atom3,atom4;
char *eof;
if (atom->natoms > MAXSMALLINT)
error->all(FLERR,"Molecular data file has too many atoms");
// customize for new sections
int natoms = static_cast<int> (atom->natoms);
bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
int ellipsoid_flag = 0;
int line_flag = 0;
int tri_flag = 0;
// customize for new sections
// allocate topology counting vector
// initially, array length = 1 to natoms
// will grow via reallocate() if atom IDs > natoms
int cmax = natoms + 1;
int *count;
memory->create(count,cmax,"read_data:count");
while (strlen(keyword)) {
if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes);
else if (strcmp(keyword,"Atoms") == 0) skip_lines(natoms);
else if (strcmp(keyword,"Velocities") == 0) skip_lines(natoms);
else if (strcmp(keyword,"Ellipsoids") == 0) {
if (!avec_ellipsoid)
error->all(FLERR,"Invalid data file section: Ellipsoids");
ellipsoid_flag = 1;
skip_lines(nellipsoids);
} else if (strcmp(keyword,"Lines") == 0) {
if (!avec_line) error->all(FLERR,"Invalid data file section: Lines");
line_flag = 1;
skip_lines(nlines);
} else if (strcmp(keyword,"Triangles") == 0) {
if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles");
tri_flag = 1;
skip_lines(ntris);
} else if (strcmp(keyword,"Pair Coeffs") == 0) {
if (force->pair == NULL)
error->all(FLERR,"Must define pair_style before Pair Coeffs");
skip_lines(atom->ntypes);
} else if (strcmp(keyword,"Bond Coeffs") == 0) {
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Invalid data file section: Bond Coeffs");
if (force->bond == NULL)
error->all(FLERR,"Must define bond_style before Bond Coeffs");
skip_lines(atom->nbondtypes);
} else if (strcmp(keyword,"Angle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: Angle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before Angle Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
skip_lines(atom->ndihedraltypes);
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: Dihedral Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs");
} else if (strcmp(keyword,"Improper Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: Improper Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before Improper Coeffs");
skip_lines(atom->nimpropertypes);
} else if (strcmp(keyword,"BondBond Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondBond Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondAngle Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"MiddleBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before EndBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before AngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"AngleAngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before AngleAngle Coeffs");
skip_lines(atom->nimpropertypes);
} else if (strcmp(keyword,"Bonds") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nbonds; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1);
count[atom1]++;
}
else
for (i = 0; i < atom->nbonds; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
int amax = MAX(atom1,atom2);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
}
for (i = 1; i < cmax; i++) bond_per_atom = MAX(bond_per_atom,count[i]);
if (screen) fprintf(screen," %d = max bonds/atom\n",bond_per_atom);
if (logfile) fprintf(logfile," %d = max bonds/atom\n",bond_per_atom);
} else if (strcmp(keyword,"Angles") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nangles; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->nangles; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
}
for (i = 1; i < cmax; i++) angle_per_atom = MAX(angle_per_atom,count[i]);
if (screen) fprintf(screen," %d = max angles/atom\n",angle_per_atom);
if (logfile) fprintf(logfile," %d = max angles/atom\n",angle_per_atom);
} else if (strcmp(keyword,"Dihedrals") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->ndihedrals; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->ndihedrals; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
amax = MAX(amax,atom4);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
count[atom4]++;
}
for (i = 1; i < cmax; i++)
dihedral_per_atom = MAX(dihedral_per_atom,count[i]);
if (screen)
fprintf(screen," %d = max dihedrals/atom\n",dihedral_per_atom);
if (logfile)
fprintf(logfile," %d = max dihedrals/atom\n",dihedral_per_atom);
} else if (strcmp(keyword,"Impropers") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nimpropers; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->nimpropers; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
amax = MAX(amax,atom4);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
count[atom4]++;
}
for (i = 1; i < cmax; i++)
improper_per_atom = MAX(improper_per_atom,count[i]);
if (screen)
fprintf(screen," %d = max impropers/atom\n",improper_per_atom);
if (logfile)
fprintf(logfile," %d = max impropers/atom\n",improper_per_atom);
} else {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->one(FLERR,str);
}
parse_keyword(0,0);
}
// free topology counting vector
memory->destroy(count);
// error check that topology was specified in file
if ((atom->nbonds && !bond_per_atom) ||
(atom->nangles && !angle_per_atom) ||
(atom->ndihedrals && !dihedral_per_atom) ||
(atom->nimpropers && !improper_per_atom))
error->one(FLERR,"Needed topology not in data file");
// customize for new sections
// error check that Bonus sections were speficied in file
if (nellipsoids && !ellipsoid_flag)
error->one(FLERR,"Needed bonus data not in data file");
if (nlines && !line_flag)
error->one(FLERR,"Needed bonus data not in data file");
if (ntris && !tri_flag)
error->one(FLERR,"Needed bonus data not in data file");
}
/* ----------------------------------------------------------------------
reallocate the count vector from cmax to amax+1 and return new length
zero new locations
------------------------------------------------------------------------- */
int ReadData::reallocate(int **pcount, int cmax, int amax)
{
int *count = *pcount;
memory->grow(count,amax+1,"read_data:count");
for (int i = cmax; i <= amax; i++) count[i] = 0;
*pcount = count;
return amax+1;
}
/* ----------------------------------------------------------------------
proc 0 opens data file
test if gzipped
------------------------------------------------------------------------- */
void ReadData::open(char *file)
{
compressed = 0;
char *suffix = file + strlen(file) - 3;
if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
if (!compressed) fp = fopen(file,"r");
else {
#ifdef LAMMPS_GZIP
char gunzip[128];
sprintf(gunzip,"gunzip -c %s",file);
fp = popen(gunzip,"r");
#else
error->one(FLERR,"Cannot open gzipped file");
#endif
}
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
}
/* ----------------------------------------------------------------------
grab next keyword
read lines until one is non-blank
keyword is all text on line w/out leading & trailing white space
read one additional line (assumed blank)
if any read hits EOF, set keyword to empty
if first = 1, line variable holds non-blank line that ended header
if flag = 0, only proc 0 is calling so no bcast
else flag = 1, bcast keyword line to all procs
------------------------------------------------------------------------- */
void ReadData::parse_keyword(int first, int flag)
{
int eof = 0;
// proc 0 reads upto non-blank line plus 1 following line
// eof is set to 1 if any read hits end-of-file
if (me == 0) {
if (!first) {
if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
}
while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) {
if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
}
if (fgets(buffer,MAXLINE,fp) == NULL) eof = 1;
}
// if eof, set keyword empty and return
if (flag) MPI_Bcast(&eof,1,MPI_INT,0,world);
if (eof) {
keyword[0] = '\0';
return;
}
// bcast keyword line to all procs
if (flag) {
int n;
if (me == 0) n = strlen(line) + 1;
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(line,n,MPI_CHAR,0,world);
}
// copy non-whitespace portion of line into keyword
int start = strspn(line," \t\n\r");
int stop = strlen(line) - 1;
while (line[stop] == ' ' || line[stop] == '\t'
|| line[stop] == '\n' || line[stop] == '\r') stop--;
line[stop+1] = '\0';
strcpy(keyword,&line[start]);
}
/* ----------------------------------------------------------------------
proc 0 reads N lines from file
------------------------------------------------------------------------- */
void ReadData::skip_lines(int n)
{
char *eof;
for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
}
/* ----------------------------------------------------------------------
parse a line of coeffs into words, storing them in narg,arg
trim anything from '#' onward
word strings remain in line, are not copied
if addstr != NULL, add addstr as extra arg for class2 angle/dihedral/improper
if 2nd word starts with letter, then is hybrid style, add addstr after it
else add addstr before 2nd word
if dupflag, duplicate 1st word, so pair_coeff "2" becomes "2 2"
------------------------------------------------------------------------- */
void ReadData::parse_coeffs(char *line, char *addstr, int dupflag)
{
char *ptr;
if (ptr = strchr(line,'#')) *ptr = '\0';
narg = 0;
char *word = strtok(line," \t\n\r\f");
while (word) {
if (narg == maxarg) {
maxarg += DELTA;
arg = (char **)
memory->srealloc(arg,maxarg*sizeof(char *),"read_data:arg");
}
if (addstr && narg == 1 && !islower(word[0])) arg[narg++] = addstr;
arg[narg++] = word;
if (addstr && narg == 2 && islower(word[0])) arg[narg++] = addstr;
if (dupflag && narg == 1) arg[narg++] = word;
word = strtok(NULL," \t\n\r\f");
}
}
diff --git a/src/read_restart.cpp b/src/read_restart.cpp
index dadc29b64..02e313a8d 100644
--- a/src/read_restart.cpp
+++ b/src/read_restart.cpp
@@ -1,847 +1,847 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "string.h"
#include "stdlib.h"
//#include "sys/types.h"
#include "dirent.h"
#include "read_restart.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "comm.h"
#include "irregular.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_read_restart.h"
#include "group.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "special.h"
#include "universe.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
// same as write_restart.cpp
enum{VERSION,SMALLINT,TAGINT,BIGINT,
UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
ATOM_STYLE,NATOMS,NTYPES,
NBONDS,NBONDTYPES,BOND_PER_ATOM,
NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
XY,XZ,YZ};
enum{MASS};
enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
#define LB_FACTOR 1.1
/* ---------------------------------------------------------------------- */
ReadRestart::ReadRestart(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void ReadRestart::command(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal read_restart command");
if (domain->box_exist)
error->all(FLERR,"Cannot read_restart after simulation box is defined");
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
// if filename contains "*", search dir for latest restart file
char *file = new char[strlen(arg[0]) + 16];
if (strchr(arg[0],'*')) {
int n;
if (me == 0) {
file_search(arg[0],file);
n = strlen(file) + 1;
}
MPI_Bcast(&n,1,MPI_INT,0,world);
MPI_Bcast(file,n,MPI_CHAR,0,world);
} else strcpy(file,arg[0]);
// check if filename contains "%"
int multiproc;
if (strchr(file,'%')) multiproc = 1;
else multiproc = 0;
// open single restart file or base file for multiproc case
if (me == 0) {
if (screen) fprintf(screen,"Reading restart file ...\n");
char *hfile;
if (multiproc) {
hfile = new char[strlen(file) + 16];
char *ptr = strchr(file,'%');
*ptr = '\0';
sprintf(hfile,"%s%s%s",file,"base",ptr+1);
*ptr = '%';
} else hfile = file;
fp = fopen(hfile,"rb");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open restart file %s",hfile);
error->one(FLERR,str);
}
if (multiproc) delete [] hfile;
}
// read header info and create atom style and simulation box
header();
domain->box_exist = 1;
// problem setup using info from header
int n;
if (nprocs == 1) n = static_cast<int> (atom->natoms);
else n = static_cast<int> (LB_FACTOR * atom->natoms / nprocs);
atom->allocate_type_arrays();
atom->avec->grow(n);
n = atom->nmax;
domain->print_box(" ");
domain->set_initial_box();
domain->set_global_box();
- comm->set_procs();
+ comm->set_proc_grid();
domain->set_local_box();
// read groups, ntype-length arrays, force field, fix info from file
// nextra = max # of extra quantities stored with each atom
group->read_restart(fp);
type_arrays();
force_fields();
int nextra = modify->read_restart(fp);
atom->nextra_store = nextra;
memory->create(atom->extra,n,nextra,"atom:extra");
// single file:
// nprocs_file = # of chunks in file
// proc 0 reads chunks one at a time and bcasts it to other procs
// each proc unpacks the atoms, saving ones in it's sub-domain
// check for atom in sub-domain differs for orthogonal vs triclinic box
// close restart file when done
AtomVec *avec = atom->avec;
int maxbuf = 0;
double *buf = NULL;
int m;
if (multiproc == 0) {
int triclinic = domain->triclinic;
double *x,lamda[3];
double *coord,*sublo,*subhi;
if (triclinic == 0) {
sublo = domain->sublo;
subhi = domain->subhi;
} else {
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
}
for (int iproc = 0; iproc < nprocs_file; iproc++) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
if (n > 0) {
if (me == 0) fread(buf,sizeof(double),n,fp);
MPI_Bcast(buf,n,MPI_DOUBLE,0,world);
}
m = 0;
while (m < n) {
x = &buf[m+1];
if (triclinic) {
domain->x2lamda(x,lamda);
coord = lamda;
} else coord = x;
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2]) {
m += avec->unpack_restart(&buf[m]);
}
else m += static_cast<int> (buf[m]);
}
}
if (me == 0) fclose(fp);
// one file per proc:
// nprocs_file = # of files
// each proc reads 1/P fraction of files, keeping all atoms in the files
// perform irregular comm to migrate atoms to correct procs
// close restart file when done
} else {
if (me == 0) fclose(fp);
char *perproc = new char[strlen(file) + 16];
char *ptr = strchr(file,'%');
for (int iproc = me; iproc < nprocs_file; iproc += nprocs) {
*ptr = '\0';
sprintf(perproc,"%s%d%s",file,iproc,ptr+1);
*ptr = '%';
fp = fopen(perproc,"rb");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open restart file %s",perproc);
error->one(FLERR,str);
}
fread(&n,sizeof(int),1,fp);
if (n > maxbuf) {
maxbuf = n;
memory->destroy(buf);
memory->create(buf,maxbuf,"read_restart:buf");
}
if (n > 0) fread(buf,sizeof(double),n,fp);
m = 0;
while (m < n) m += avec->unpack_restart(&buf[m]);
fclose(fp);
}
delete [] perproc;
// create a temporary fix to hold and migrate extra atom info
// necessary b/c irregular will migrate atoms
if (nextra) {
char cextra[8],fixextra[8];
sprintf(cextra,"%d",nextra);
sprintf(fixextra,"%d",modify->nfix_restart_peratom);
char **newarg = new char*[5];
newarg[0] = (char *) "_read_restart";
newarg[1] = (char *) "all";
newarg[2] = (char *) "READ_RESTART";
newarg[3] = cextra;
newarg[4] = fixextra;
modify->add_fix(5,newarg);
delete [] newarg;
}
// move atoms to new processors via irregular()
// in case read by different proc than wrote restart file
// first do map_init() since irregular->migrate_atoms() will do map_clear()
if (atom->map_style) atom->map_init();
if (domain->triclinic) domain->x2lamda(atom->nlocal);
Irregular *irregular = new Irregular(lmp);
irregular->migrate_atoms();
delete irregular;
if (domain->triclinic) domain->lamda2x(atom->nlocal);
// put extra atom info held by fix back into atom->extra
// destroy temporary fix
if (nextra) {
memory->destroy(atom->extra);
memory->create(atom->extra,atom->nmax,nextra,"atom:extra");
int ifix = modify->find_fix("_read_restart");
FixReadRestart *fix = (FixReadRestart *) modify->fix[ifix];
int *count = fix->count;
double **extra = fix->extra;
double **atom_extra = atom->extra;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
for (int j = 0; j < count[i]; j++)
atom_extra[i][j] = extra[i][j];
modify->delete_fix("_read_restart");
}
}
// clean-up memory
delete [] file;
memory->destroy(buf);
// check that all atoms were assigned to procs
bigint natoms;
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
if (natoms != atom->natoms)
error->all(FLERR,"Did not assign all atoms correctly");
if (me == 0) {
if (atom->nbonds) {
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",atom->nbonds);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",atom->nbonds);
}
if (atom->nangles) {
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",
atom->nangles);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",
atom->nangles);
}
if (atom->ndihedrals) {
if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
}
if (atom->nimpropers) {
if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",
atom->nimpropers);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",
atom->nimpropers);
}
}
// check if tags are being used
// create global mapping and bond topology now that system is defined
int flag = 0;
for (int i = 0; i < atom->nlocal; i++)
if (atom->tag[i] > 0) flag = 1;
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
if (flag_all == 0) atom->tag_enable = 0;
if (atom->map_style) {
atom->map_init();
atom->map_set();
}
if (atom->molecular) {
Special special(lmp);
special.build();
}
}
/* ----------------------------------------------------------------------
infile contains a "*"
search for all files which match the infile pattern
replace "*" with latest timestep value to create outfile name
search dir referenced by initial pathname of file
if infile also contains "%", use "base" when searching directory
only called by proc 0
------------------------------------------------------------------------- */
void ReadRestart::file_search(char *infile, char *outfile)
{
char *ptr;
// separate infile into dir + filename
char *dirname = new char[strlen(infile) + 1];
char *filename = new char[strlen(infile) + 1];
if (strchr(infile,'/')) {
ptr = strrchr(infile,'/');
*ptr = '\0';
strcpy(dirname,infile);
strcpy(filename,ptr+1);
*ptr = '/';
} else {
strcpy(dirname,"./");
strcpy(filename,infile);
}
// if filename contains "%" replace "%" with "base"
char *pattern = new char[strlen(filename) + 16];
if (ptr = strchr(filename,'%')) {
*ptr = '\0';
sprintf(pattern,"%s%s%s",filename,"base",ptr+1);
*ptr = '%';
} else strcpy(pattern,filename);
// scan all files in directory, searching for files that match pattern
// maxnum = largest int that matches "*"
int n = strlen(pattern) + 16;
char *begin = new char[n];
char *middle = new char[n];
char *end = new char[n];
ptr = strchr(pattern,'*');
*ptr = '\0';
strcpy(begin,pattern);
strcpy(end,ptr+1);
int nbegin = strlen(begin);
bigint maxnum = -1;
struct dirent *ep;
DIR *dp = opendir(dirname);
if (dp == NULL)
error->one(FLERR,"Cannot open dir to search for restart file");
while (ep = readdir(dp)) {
if (strstr(ep->d_name,begin) != ep->d_name) continue;
if ((ptr = strstr(&ep->d_name[nbegin],end)) == NULL) continue;
if (strlen(end) == 0) ptr = ep->d_name + strlen(ep->d_name);
*ptr = '\0';
if (strlen(&ep->d_name[nbegin]) < n) {
strcpy(middle,&ep->d_name[nbegin]);
if (ATOBIGINT(middle) > maxnum) maxnum = ATOBIGINT(middle);
}
}
closedir(dp);
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
// create outfile with maxint substituted for "*"
// use original infile, not pattern, since need to retain "%" in filename
ptr = strchr(infile,'*');
*ptr = '\0';
sprintf(outfile,"%s" BIGINT_FORMAT "%s",infile,maxnum,ptr+1);
*ptr = '*';
// clean up
delete [] dirname;
delete [] filename;
delete [] pattern;
delete [] begin;
delete [] middle;
delete [] end;
}
/* ----------------------------------------------------------------------
read header of restart file
------------------------------------------------------------------------- */
void ReadRestart::header()
{
int px,py,pz;
int xperiodic,yperiodic,zperiodic;
int boundary[3][2];
// read flags and values until flag = -1
int flag = read_int();
while (flag >= 0) {
// check restart file version, warn if different
if (flag == VERSION) {
char *version = read_char();
if (strcmp(version,universe->version) != 0 && me == 0) {
error->warning(FLERR,"Restart file version does not match LAMMPS version");
if (screen) fprintf(screen," restart file = %s, LAMMPS = %s\n",
version,universe->version);
}
delete [] version;
// check lmptype.h sizes, error if different
} else if (flag == SMALLINT) {
int size = read_int();
if (size != sizeof(smallint))
error->all(FLERR,"Smallint setting in lmptype.h is not compatible");
} else if (flag == TAGINT) {
int size = read_int();
if (size != sizeof(tagint))
error->all(FLERR,"Tagint setting in lmptype.h is not compatible");
} else if (flag == BIGINT) {
int size = read_int();
if (size != sizeof(bigint))
error->all(FLERR,"Bigint setting in lmptype.h is not compatible");
// reset unit_style only if different
// so that timestep,neighbor-skin are not changed
} else if (flag == UNITS) {
char *style = read_char();
if (strcmp(style,update->unit_style) != 0) update->set_units(style);
delete [] style;
} else if (flag == NTIMESTEP) {
update->ntimestep = read_bigint();
// set dimension from restart file
} else if (flag == DIMENSION) {
int dimension = read_int();
domain->dimension = dimension;
if (domain->dimension == 2 && domain->zperiodic == 0)
error->all(FLERR,
"Cannot run 2d simulation with nonperiodic Z dimension");
// read nprocs from restart file, warn if different
} else if (flag == NPROCS) {
nprocs_file = read_int();
if (nprocs_file != comm->nprocs && me == 0)
error->warning(FLERR,"Restart file used different # of processors");
// don't set procgrid, warn if different
} else if (flag == PROCGRID_0) {
px = read_int();
} else if (flag == PROCGRID_1) {
py = read_int();
} else if (flag == PROCGRID_2) {
pz = read_int();
if (comm->user_procgrid[0] != 0 &&
(px != comm->user_procgrid[0] || py != comm->user_procgrid[1] ||
pz != comm->user_procgrid[2]) && me == 0)
error->warning(FLERR,"Restart file used different 3d processor grid");
// don't set newton_pair, leave input script value unchanged
// set newton_bond from restart file
// warn if different and input script settings are not default
} else if (flag == NEWTON_PAIR) {
int newton_pair_file = read_int();
if (force->newton_pair != 1) {
if (newton_pair_file != force->newton_pair && me == 0)
error->warning(FLERR,
"Restart file used different newton pair setting, "
"using input script value");
}
} else if (flag == NEWTON_BOND) {
int newton_bond_file = read_int();
if (force->newton_bond != 1) {
if (newton_bond_file != force->newton_bond && me == 0)
error->warning(FLERR,
"Restart file used different newton bond setting, "
"using restart file value");
}
force->newton_bond = newton_bond_file;
if (force->newton_pair || force->newton_bond) force->newton = 1;
else force->newton = 0;
// set boundary settings from restart file
// warn if different and input script settings are not default
} else if (flag == XPERIODIC) {
xperiodic = read_int();
} else if (flag == YPERIODIC) {
yperiodic = read_int();
} else if (flag == ZPERIODIC) {
zperiodic = read_int();
} else if (flag == BOUNDARY_00) {
boundary[0][0] = read_int();
} else if (flag == BOUNDARY_01) {
boundary[0][1] = read_int();
} else if (flag == BOUNDARY_10) {
boundary[1][0] = read_int();
} else if (flag == BOUNDARY_11) {
boundary[1][1] = read_int();
} else if (flag == BOUNDARY_20) {
boundary[2][0] = read_int();
} else if (flag == BOUNDARY_21) {
boundary[2][1] = read_int();
if (domain->boundary[0][0] || domain->boundary[0][1] ||
domain->boundary[1][0] || domain->boundary[1][1] ||
domain->boundary[2][0] || domain->boundary[2][1]) {
if (boundary[0][0] != domain->boundary[0][0] ||
boundary[0][1] != domain->boundary[0][1] ||
boundary[1][0] != domain->boundary[1][0] ||
boundary[1][1] != domain->boundary[1][1] ||
boundary[2][0] != domain->boundary[2][0] ||
boundary[2][1] != domain->boundary[2][1]) {
if (me == 0)
error->warning(FLERR,"Restart file used different boundary settings, "
"using restart file values");
}
}
domain->boundary[0][0] = boundary[0][0];
domain->boundary[0][1] = boundary[0][1];
domain->boundary[1][0] = boundary[1][0];
domain->boundary[1][1] = boundary[1][1];
domain->boundary[2][0] = boundary[2][0];
domain->boundary[2][1] = boundary[2][1];
domain->periodicity[0] = domain->xperiodic = xperiodic;
domain->periodicity[1] = domain->yperiodic = yperiodic;
domain->periodicity[2] = domain->zperiodic = zperiodic;
domain->nonperiodic = 0;
if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
domain->nonperiodic = 1;
if (boundary[0][0] >= 2 || boundary[0][1] >= 2 ||
boundary[1][0] >= 2 || boundary[1][1] >= 2 ||
boundary[2][0] >= 2 || boundary[2][1] >= 2)
domain->nonperiodic = 2;
}
// create new AtomVec class
// if style = hybrid, read additional sub-class arguments
} else if (flag == ATOM_STYLE) {
char *style = read_char();
int nwords = 0;
char **words = NULL;
if (strcmp(style,"hybrid") == 0) {
nwords = read_int();
words = new char*[nwords];
for (int i = 0; i < nwords; i++) words[i] = read_char();
}
atom->create_avec(style,nwords,words);
for (int i = 0; i < nwords; i++) delete [] words[i];
delete [] words;
delete [] style;
} else if (flag == NATOMS) {
atom->natoms = read_bigint();
} else if (flag == NTYPES) {
atom->ntypes = read_int();
} else if (flag == NBONDS) {
atom->nbonds = read_bigint();
} else if (flag == NBONDTYPES) {
atom->nbondtypes = read_int();
} else if (flag == BOND_PER_ATOM) {
atom->bond_per_atom = read_int();
} else if (flag == NANGLES) {
atom->nangles = read_bigint();
} else if (flag == NANGLETYPES) {
atom->nangletypes = read_int();
} else if (flag == ANGLE_PER_ATOM) {
atom->angle_per_atom = read_int();
} else if (flag == NDIHEDRALS) {
atom->ndihedrals = read_bigint();
} else if (flag == NDIHEDRALTYPES) {
atom->ndihedraltypes = read_int();
} else if (flag == DIHEDRAL_PER_ATOM) {
atom->dihedral_per_atom = read_int();
} else if (flag == NIMPROPERS) {
atom->nimpropers = read_bigint();
} else if (flag == NIMPROPERTYPES) {
atom->nimpropertypes = read_int();
} else if (flag == IMPROPER_PER_ATOM) {
atom->improper_per_atom = read_int();
} else if (flag == BOXLO_0) {
domain->boxlo[0] = read_double();
} else if (flag == BOXHI_0) {
domain->boxhi[0] = read_double();
} else if (flag == BOXLO_1) {
domain->boxlo[1] = read_double();
} else if (flag == BOXHI_1) {
domain->boxhi[1] = read_double();
} else if (flag == BOXLO_2) {
domain->boxlo[2] = read_double();
} else if (flag == BOXHI_2) {
domain->boxhi[2] = read_double();
} else if (flag == SPECIAL_LJ_1) {
force->special_lj[1] = read_double();
} else if (flag == SPECIAL_LJ_2) {
force->special_lj[2] = read_double();
} else if (flag == SPECIAL_LJ_3) {
force->special_lj[3] = read_double();
} else if (flag == SPECIAL_COUL_1) {
force->special_coul[1] = read_double();
} else if (flag == SPECIAL_COUL_2) {
force->special_coul[2] = read_double();
} else if (flag == SPECIAL_COUL_3) {
force->special_coul[3] = read_double();
} else if (flag == XY) {
domain->triclinic = 1;
domain->xy = read_double();
} else if (flag == XZ) {
domain->triclinic = 1;
domain->xz = read_double();
} else if (flag == YZ) {
domain->triclinic = 1;
domain->yz = read_double();
} else error->all(FLERR,"Invalid flag in header section of restart file");
flag = read_int();
}
}
/* ---------------------------------------------------------------------- */
void ReadRestart::type_arrays()
{
int flag = read_int();
while (flag >= 0) {
if (flag == MASS) {
double *mass = new double[atom->ntypes+1];
if (me == 0) fread(&mass[1],sizeof(double),atom->ntypes,fp);
MPI_Bcast(&mass[1],atom->ntypes,MPI_DOUBLE,0,world);
atom->set_mass(mass);
delete [] mass;
} else error->all(FLERR,
"Invalid flag in type arrays section of restart file");
flag = read_int();
}
}
/* ---------------------------------------------------------------------- */
void ReadRestart::force_fields()
{
int n;
char *style;
int flag = read_int();
while (flag >= 0) {
if (flag == PAIR) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
style = new char[n];
if (me == 0) fread(style,sizeof(char),n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
force->create_pair(style);
delete [] style;
if (force->pair->restartinfo) force->pair->read_restart(fp);
else {
delete force->pair;
force->pair = NULL;
}
} else if (flag == BOND) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
style = new char[n];
if (me == 0) fread(style,sizeof(char),n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
force->create_bond(style);
delete [] style;
force->bond->read_restart(fp);
} else if (flag == ANGLE) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
style = new char[n];
if (me == 0) fread(style,sizeof(char),n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
force->create_angle(style);
delete [] style;
force->angle->read_restart(fp);
} else if (flag == DIHEDRAL) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
style = new char[n];
if (me == 0) fread(style,sizeof(char),n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
force->create_dihedral(style);
delete [] style;
force->dihedral->read_restart(fp);
} else if (flag == IMPROPER) {
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
style = new char[n];
if (me == 0) fread(style,sizeof(char),n,fp);
MPI_Bcast(style,n,MPI_CHAR,0,world);
force->create_improper(style);
delete [] style;
force->improper->read_restart(fp);
} else error->all(FLERR,
"Invalid flag in force field section of restart file");
flag = read_int();
}
}
/* ----------------------------------------------------------------------
read an int from restart file and bcast it
------------------------------------------------------------------------- */
int ReadRestart::read_int()
{
int value;
if (me == 0) fread(&value,sizeof(int),1,fp);
MPI_Bcast(&value,1,MPI_INT,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a double from restart file and bcast it
------------------------------------------------------------------------- */
double ReadRestart::read_double()
{
double value;
if (me == 0) fread(&value,sizeof(double),1,fp);
MPI_Bcast(&value,1,MPI_DOUBLE,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a char str from restart file and bcast it
str is allocated here, ptr is returned, caller must deallocate
------------------------------------------------------------------------- */
char *ReadRestart::read_char()
{
int n;
if (me == 0) fread(&n,sizeof(int),1,fp);
MPI_Bcast(&n,1,MPI_INT,0,world);
char *value = new char[n];
if (me == 0) fread(value,sizeof(char),n,fp);
MPI_Bcast(value,n,MPI_CHAR,0,world);
return value;
}
/* ----------------------------------------------------------------------
read a bigint from restart file and bcast it
------------------------------------------------------------------------- */
bigint ReadRestart::read_bigint()
{
bigint value;
if (me == 0) fread(&value,sizeof(bigint),1,fp);
MPI_Bcast(&value,1,MPI_LMP_BIGINT,0,world);
return value;
}
diff --git a/src/replicate.cpp b/src/replicate.cpp
index da6a66206..ce53825f3 100644
--- a/src/replicate.cpp
+++ b/src/replicate.cpp
@@ -1,394 +1,394 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "stdlib.h"
#include "string.h"
#include "replicate.h"
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_hybrid.h"
#include "force.h"
#include "domain.h"
#include "comm.h"
#include "special.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define LB_FACTOR 1.1
#define EPSILON 1.0e-6
/* ---------------------------------------------------------------------- */
Replicate::Replicate(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void Replicate::command(int narg, char **arg)
{
int i,j,m,n;
if (domain->box_exist == 0)
error->all(FLERR,"Replicate command before simulation box is defined");
if (narg != 3) error->all(FLERR,"Illegal replicate command");
int me = comm->me;
int nprocs = comm->nprocs;
if (me == 0 && screen) fprintf(screen,"Replicating atoms ...\n");
// nrep = total # of replications
int nx = atoi(arg[0]);
int ny = atoi(arg[1]);
int nz = atoi(arg[2]);
int nrep = nx*ny*nz;
// error and warning checks
if (nx <= 0 || ny <= 0 || nz <= 0) error->all(FLERR,"Illegal replicate command");
if (domain->dimension == 2 && nz != 1)
error->all(FLERR,"Cannot replicate 2d simulation in z dimension");
if ((nx > 1 && domain->xperiodic == 0) ||
(ny > 1 && domain->yperiodic == 0) ||
(nz > 1 && domain->zperiodic == 0))
error->warning(FLERR,"Replicating in a non-periodic dimension");
if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store)
error->all(FLERR,"Cannot replicate with fixes that store atom quantities");
// maxtag = largest atom tag across all existing atoms
int maxtag = 0;
for (i = 0; i < atom->nlocal; i++) maxtag = MAX(atom->tag[i],maxtag);
int maxtag_all;
MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_INT,MPI_MAX,world);
maxtag = maxtag_all;
// maxmol = largest molecule tag across all existing atoms
int maxmol = 0;
if (atom->molecular) {
for (i = 0; i < atom->nlocal; i++) maxmol = MAX(atom->molecule[i],maxmol);
int maxmol_all;
MPI_Allreduce(&maxmol,&maxmol_all,1,MPI_INT,MPI_MAX,world);
maxmol = maxmol_all;
}
// unmap existing atoms via image flags
for (i = 0; i < atom->nlocal; i++)
domain->unmap(atom->x[i],atom->image[i]);
// communication buffer for all my atom's info
// max_size = largest buffer needed by any proc
// must do before new Atom class created,
// since size_restart() uses atom->nlocal
int max_size;
int send_size = atom->avec->size_restart();
MPI_Allreduce(&send_size,&max_size,1,MPI_INT,MPI_MAX,world);
double *buf;
memory->create(buf,max_size,"replicate:buf");
// old = original atom class
// atom = new replicated atom class
// if old atom style was hybrid, pass sub-style names to create_avec
Atom *old = atom;
atom = new Atom(lmp);
atom->settings(old);
int nstyles = 0;
char **keywords = NULL;
if (strcmp(old->atom_style,"hybrid") == 0) {
AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) old->avec;
nstyles = avec_hybrid->nstyles;
keywords = avec_hybrid->keywords;
}
atom->create_avec(old->atom_style,nstyles,keywords);
// check that new system will not be too large
// if molecular and N > MAXTAGINT, error
// if atomic and new N > MAXTAGINT, turn off tags for existing and new atoms
// new system cannot exceed MAXBIGINT
if (atom->molecular && (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT))
error->all(FLERR,"Replicated molecular system atom IDs are too big");
if (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT)
atom->tag_enable = 0;
if (atom->tag_enable == 0)
for (int i = 0; i < atom->nlocal; i++)
atom->tag[i] = 0;
if (nrep*old->natoms < 0 || nrep*old->natoms > MAXBIGINT ||
nrep*old->nbonds < 0 || nrep*old->nbonds > MAXBIGINT ||
nrep*old->nangles < 0 || nrep*old->nangles > MAXBIGINT ||
nrep*old->ndihedrals < 0 || nrep*old->ndihedrals > MAXBIGINT ||
nrep*old->nimpropers < 0 || nrep*old->nimpropers > MAXBIGINT)
error->all(FLERR,"Replicated system is too big");
// assign atom and topology counts in new class from old one
atom->natoms = old->natoms * nrep;
atom->nbonds = old->nbonds * nrep;
atom->nangles = old->nangles * nrep;
atom->ndihedrals = old->ndihedrals * nrep;
atom->nimpropers = old->nimpropers * nrep;
atom->ntypes = old->ntypes;
atom->nbondtypes = old->nbondtypes;
atom->nangletypes = old->nangletypes;
atom->ndihedraltypes = old->ndihedraltypes;
atom->nimpropertypes = old->nimpropertypes;
atom->bond_per_atom = old->bond_per_atom;
atom->angle_per_atom = old->angle_per_atom;
atom->dihedral_per_atom = old->dihedral_per_atom;
atom->improper_per_atom = old->improper_per_atom;
// store old simulation box
int triclinic = domain->triclinic;
double old_xprd = domain->xprd;
double old_yprd = domain->yprd;
double old_zprd = domain->zprd;
double old_xy = domain->xy;
double old_xz = domain->xz;
double old_yz = domain->yz;
// setup new simulation box
domain->boxhi[0] = domain->boxlo[0] + nx*old_xprd;
domain->boxhi[1] = domain->boxlo[1] + ny*old_yprd;
domain->boxhi[2] = domain->boxlo[2] + nz*old_zprd;
if (triclinic) {
domain->xy *= ny;
domain->xz *= nz;
domain->yz *= nz;
}
// new problem setup using new box boundaries
if (nprocs == 1) n = static_cast<int> (atom->natoms);
else n = static_cast<int> (LB_FACTOR * atom->natoms / nprocs);
atom->allocate_type_arrays();
atom->avec->grow(n);
n = atom->nmax;
domain->print_box(" ");
domain->set_initial_box();
domain->set_global_box();
- comm->set_procs();
+ comm->set_proc_grid();
domain->set_local_box();
// copy type arrays to new atom class
if (atom->mass) {
for (int itype = 1; itype <= atom->ntypes; itype++) {
atom->mass_setflag[itype] = old->mass_setflag[itype];
if (atom->mass_setflag[itype]) atom->mass[itype] = old->mass[itype];
}
}
// set bounds for my proc
// if periodic and I am lo/hi proc, adjust bounds by EPSILON
// insures all replicated atoms will be owned even with round-off
double sublo[3],subhi[3];
if (triclinic == 0) {
sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
} else {
sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
}
if (domain->xperiodic) {
if (comm->myloc[0] == 0) sublo[0] -= EPSILON;
if (comm->myloc[0] == comm->procgrid[0]-1) subhi[0] += EPSILON;
}
if (domain->yperiodic) {
if (comm->myloc[1] == 0) sublo[1] -= EPSILON;
if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] += EPSILON;
}
if (domain->zperiodic) {
if (comm->myloc[2] == 0) sublo[2] -= EPSILON;
if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] += EPSILON;
}
// loop over all procs
// if this iteration of loop is me:
// pack my unmapped atom data into buf
// bcast it to all other procs
// performs 3d replicate loop with while loop over atoms in buf
// x = new replicated position, remapped into simulation box
// unpack atom into new atom class from buf if I own it
// adjust tag, mol #, coord, topology info as needed
AtomVec *old_avec = old->avec;
AtomVec *avec = atom->avec;
int ix,iy,iz,image,atom_offset,mol_offset;
double x[3],lamda[3];
double *coord;
int tag_enable = atom->tag_enable;
for (int iproc = 0; iproc < nprocs; iproc++) {
if (me == iproc) {
n = 0;
for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]);
}
MPI_Bcast(&n,1,MPI_INT,iproc,world);
MPI_Bcast(buf,n,MPI_DOUBLE,iproc,world);
for (ix = 0; ix < nx; ix++) {
for (iy = 0; iy < ny; iy++) {
for (iz = 0; iz < nz; iz++) {
// while loop over one proc's atom list
m = 0;
while (m < n) {
image = (512 << 20) | (512 << 10) | 512;
if (triclinic == 0) {
x[0] = buf[m+1] + ix*old_xprd;
x[1] = buf[m+2] + iy*old_yprd;
x[2] = buf[m+3] + iz*old_zprd;
} else {
x[0] = buf[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz;
x[1] = buf[m+2] + iy*old_yprd + iz*old_yz;
x[2] = buf[m+3] + iz*old_zprd;
}
domain->remap(x,image);
if (triclinic) {
domain->x2lamda(x,lamda);
coord = lamda;
} else coord = x;
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2]) {
m += avec->unpack_restart(&buf[m]);
i = atom->nlocal - 1;
if (tag_enable)
atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag;
else atom_offset = 0;
mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol;
atom->x[i][0] = x[0];
atom->x[i][1] = x[1];
atom->x[i][2] = x[2];
atom->tag[i] += atom_offset;
atom->image[i] = image;
if (atom->molecular) {
if (atom->molecule[i] > 0)
atom->molecule[i] += mol_offset;
if (atom->avec->bonds_allow)
for (j = 0; j < atom->num_bond[i]; j++)
atom->bond_atom[i][j] += atom_offset;
if (atom->avec->angles_allow)
for (j = 0; j < atom->num_angle[i]; j++) {
atom->angle_atom1[i][j] += atom_offset;
atom->angle_atom2[i][j] += atom_offset;
atom->angle_atom3[i][j] += atom_offset;
}
if (atom->avec->dihedrals_allow)
for (j = 0; j < atom->num_dihedral[i]; j++) {
atom->dihedral_atom1[i][j] += atom_offset;
atom->dihedral_atom2[i][j] += atom_offset;
atom->dihedral_atom3[i][j] += atom_offset;
atom->dihedral_atom4[i][j] += atom_offset;
}
if (atom->avec->impropers_allow)
for (j = 0; j < atom->num_improper[i]; j++) {
atom->improper_atom1[i][j] += atom_offset;
atom->improper_atom2[i][j] += atom_offset;
atom->improper_atom3[i][j] += atom_offset;
atom->improper_atom4[i][j] += atom_offset;
}
}
} else m += static_cast<int> (buf[m]);
}
}
}
}
} // end of proc loop
// free communication buffer and old atom class
memory->destroy(buf);
delete old;
// check that all atoms were assigned to procs
bigint natoms;
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
if (natoms != atom->natoms)
error->all(FLERR,"Replicate did not assign all atoms correctly");
if (me == 0) {
if (atom->nbonds) {
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",atom->nbonds);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",atom->nbonds);
}
if (atom->nangles) {
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",
atom->nangles);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",
atom->nangles);
}
if (atom->ndihedrals) {
if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
}
if (atom->nimpropers) {
if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",
atom->nimpropers);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",
atom->nimpropers);
}
}
// create global mapping and bond topology now that system is defined
if (atom->map_style) {
atom->nghost = 0;
atom->map_init();
atom->map_set();
}
if (atom->molecular) {
Special special(lmp);
special.build();
}
}
diff --git a/src/run.cpp b/src/run.cpp
index 1f413072a..001320f6f 100644
--- a/src/run.cpp
+++ b/src/run.cpp
@@ -1,248 +1,244 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "stdlib.h"
#include "string.h"
#include "run.h"
#include "domain.h"
#include "update.h"
#include "integrate.h"
#include "modify.h"
#include "output.h"
#include "finish.h"
#include "input.h"
#include "timer.h"
#include "error.h"
using namespace LAMMPS_NS;
#define MAXLINE 2048
/* ---------------------------------------------------------------------- */
Run::Run(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void Run::command(int narg, char **arg)
{
if (narg < 1) error->all(FLERR,"Illegal run command");
if (domain->box_exist == 0)
error->all(FLERR,"Run command before simulation box is defined");
bigint nsteps_input = ATOBIGINT(arg[0]);
// parse optional args
int uptoflag = 0;
int startflag = 0;
int stopflag = 0;
bigint start,stop;
int preflag = 1;
int postflag = 1;
int nevery = 0;
int ncommands = 0;
int first,last;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"upto") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal run command");
uptoflag = 1;
iarg += 1;
} else if (strcmp(arg[iarg],"start") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal run command");
startflag = 1;
start = ATOBIGINT(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"stop") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal run command");
stopflag = 1;
stop = ATOBIGINT(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"pre") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal run command");
if (strcmp(arg[iarg+1],"no") == 0) preflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) preflag = 1;
else error->all(FLERR,"Illegal run command");
iarg += 2;
} else if (strcmp(arg[iarg],"post") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal run command");
if (strcmp(arg[iarg+1],"no") == 0) postflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) postflag = 1;
else error->all(FLERR,"Illegal run command");
iarg += 2;
// all remaining args are commands
// first,last = arg index of first/last commands
// set ncommands = 0 if single command and it is NULL
} else if (strcmp(arg[iarg],"every") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal run command");
nevery = atoi(arg[iarg+1]);
if (nevery <= 0) error->all(FLERR,"Illegal run command");
first = iarg+2;
last = narg-1;
ncommands = last-first + 1;
if (ncommands == 1 && strcmp(arg[first],"NULL") == 0) ncommands = 0;
iarg = narg;
} else error->all(FLERR,"Illegal run command");
}
// set nsteps as integer, using upto value if specified
int nsteps;
if (!uptoflag) {
if (nsteps_input < 0 || nsteps_input > MAXSMALLINT)
error->all(FLERR,"Invalid run command N value");
nsteps = static_cast<int> (nsteps_input);
} else {
bigint delta = nsteps_input - update->ntimestep;
if (delta < 0 || delta > MAXSMALLINT)
error->all(FLERR,"Invalid run command upto value");
nsteps = static_cast<int> (delta);
}
// error check
if (startflag) {
if (start < 0 || start > MAXBIGINT)
error->all(FLERR,"Invalid run command start/stop value");
if (start > update->ntimestep)
error->all(FLERR,"Run command start value is after start of run");
}
if (stopflag) {
if (stop < 0 || stop > MAXBIGINT)
error->all(FLERR,"Invalid run command start/stop value");
if (stop < update->ntimestep + nsteps)
error->all(FLERR,"Run command stop value is before end of run");
}
// if nevery, make copies of arg strings that are commands
// required because re-parsing commands via input->one() will wipe out args
char **commands = NULL;
if (nevery && ncommands > 0) {
commands = new char*[ncommands];
ncommands = 0;
for (int i = first; i <= last; i++) {
int n = strlen(arg[i]) + 1;
commands[ncommands] = new char[n];
strcpy(commands[ncommands],arg[i]);
ncommands++;
}
}
// perform a single run
// use start/stop to set begin/end step
// if pre or 1st run, do System init/setup,
// else just init timer and setup output
// if post, do full Finish, else just print time
update->whichflag = 1;
if (nevery == 0) {
update->nsteps = nsteps;
update->firststep = update->ntimestep;
update->laststep = update->ntimestep + nsteps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
if (startflag) update->beginstep = start;
else update->beginstep = update->firststep;
if (stopflag) update->endstep = stop;
else update->endstep = update->laststep;
if (preflag || update->first_update == 0) {
lmp->init();
update->integrate->setup();
- } else {
- timer->init();
- output->setup(0);
- }
+ } else output->setup(0);
+ timer->init();
timer->barrier_start(TIME_LOOP);
update->integrate->run(nsteps);
timer->barrier_stop(TIME_LOOP);
update->integrate->cleanup();
Finish finish(lmp);
finish.end(postflag);
// perform multiple runs optionally interleaved with invocation command(s)
// use start/stop to set begin/end step
// if pre or 1st iteration of multiple runs, do System init/setup,
// else just init timer and setup output
// if post or last iteration, do full Finish, else just print time
} else {
int iter = 0;
int nleft = nsteps;
while (nleft > 0 || iter == 0) {
nsteps = MIN(nleft,nevery);
update->nsteps = nsteps;
update->firststep = update->ntimestep;
update->laststep = update->ntimestep + nsteps;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
if (startflag) update->beginstep = start;
else update->beginstep = update->firststep;
if (stopflag) update->endstep = stop;
else update->endstep = update->laststep;
if (preflag || iter == 0) {
lmp->init();
update->integrate->setup();
- } else {
- timer->init();
- output->setup(0);
- }
+ } else output->setup(0);
+ timer->init();
timer->barrier_start(TIME_LOOP);
update->integrate->run(nsteps);
timer->barrier_stop(TIME_LOOP);
update->integrate->cleanup();
Finish finish(lmp);
if (postflag || nleft <= nsteps) finish.end(1);
else finish.end(0);
// wrap command invocation with clearstep/addstep
// since a command may invoke computes via variables
if (ncommands) {
modify->clearstep_compute();
for (int i = 0; i < ncommands; i++) input->one(commands[i]);
modify->addstep_compute(update->ntimestep + nevery);
}
nleft -= nsteps;
iter++;
}
}
update->whichflag = 0;
update->firststep = update->laststep = 0;
update->beginstep = update->endstep = 0;
if (commands) {
for (int i = 0; i < ncommands; i++) delete [] commands[i];
delete [] commands;
}
}
diff --git a/src/universe.cpp b/src/universe.cpp
index 1c61fe26d..b473c9c79 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -1,100 +1,195 @@
/* ----------------------------------------------------------------------
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 "mpi.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "universe.h"
#include "version.h"
+#include "error.h"
#include "memory.h"
using namespace LAMMPS_NS;
+#define MAXLINE 256
+
/* ----------------------------------------------------------------------
create & initialize the universe of processors in communicator
------------------------------------------------------------------------- */
Universe::Universe(LAMMPS *lmp, MPI_Comm communicator) : Pointers(lmp)
{
version = (char *) LAMMPS_VERSION;
- uworld = communicator;
+ uworld = uorig = communicator;
MPI_Comm_rank(uworld,&me);
MPI_Comm_size(uworld,&nprocs);
uscreen = stdout;
ulogfile = NULL;
existflag = 0;
nworlds = 0;
procs_per_world = NULL;
root_proc = NULL;
+
+ memory->create(uni2orig,nprocs,"universe:uni2orig");
+ for (int i = 0; i < nprocs; i++) uni2orig[i] = i;
}
/* ---------------------------------------------------------------------- */
Universe::~Universe()
{
+ if (uworld != uorig) MPI_Comm_free(&uworld);
memory->destroy(procs_per_world);
memory->destroy(root_proc);
+ memory->destroy(uni2orig);
+}
+
+/* ----------------------------------------------------------------------
+ reorder universe processors
+ create uni2orig as inverse mapping
+ re-create uworld communicator with new ordering via Comm_split()
+ style = "nth", arg = N
+ move every Nth proc to end of rankings
+ style = "custom", arg = filename
+ file has nprocs lines with I J
+ I = universe proc ID in original communicator uorig
+ J = universe proc ID in reordered communicator uworld
+------------------------------------------------------------------------- */
+
+void Universe::reorder(char *style, char *arg)
+{
+ char line[MAXLINE];
+
+ if (uworld != uorig) MPI_Comm_free(&uworld);
+
+ if (strcmp(style,"nth") == 0) {
+ int n = atoi(arg);
+ if (n <= 0)
+ error->universe_all(FLERR,"Invalid -reorder N value");
+ if (nprocs % n)
+ error->universe_all(FLERR,"Nprocs not a multiple of N for -reorder");
+ for (int i = 0; i < nprocs; i++) {
+ if (i < (n-1)*nprocs/n) uni2orig[i] = i/(n-1) * n + (i % (n-1));
+ else uni2orig[i] = (i - (n-1)*nprocs/n) * n + n-1;
+ }
+
+ } else if (strcmp(style,"custom") == 0) {
+
+ if (me == 0) {
+ FILE *fp = fopen(arg,"r");
+ if (fp == NULL) error->universe_one(FLERR,"Cannot open -reorder file");
+
+ // skip header = blank and comment lines
+
+ char *ptr;
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of -reorder file");
+ while (1) {
+ if (ptr = strchr(line,'#')) *ptr = '\0';
+ if (strspn(line," \t\n\r") != strlen(line)) break;
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of -reorder file");
+ }
+
+ // read nprocs lines
+ // uni2orig = inverse mapping
+
+ int me_orig,me_new;
+ sscanf(line,"%d %d",&me_orig,&me_new);
+ if (me_orig < 0 || me_orig >= nprocs ||
+ me_new < 0 || me_new >= nprocs)
+ error->one(FLERR,"Invalid entry in reorder file");
+ uni2orig[me_new] = me_orig;
+
+ for (int i = 1; i < nprocs; i++) {
+ if (!fgets(line,MAXLINE,fp))
+ error->one(FLERR,"Unexpected end of reorder file");
+ sscanf(line,"%d %d",&me_orig,&me_new);
+ if (me_orig < 0 || me_orig >= nprocs ||
+ me_new < 0 || me_new >= nprocs)
+ error->one(FLERR,"Invalid entry in reorder file");
+ uni2orig[me_new] = me_orig;
+ }
+ fclose(fp);
+ }
+
+ // bcast uni2org from proc 0 to all other universe procs
+
+ MPI_Bcast(uni2orig,nprocs,MPI_INT,0,uorig);
+
+ } else error->universe_all(FLERR,"Invalid command-line argument");
+
+ // create new uworld communicator
+
+ int ome,key;
+ MPI_Comm_rank(uorig,&ome);
+ for (int i = 0; i < nprocs; i++)
+ if (uni2orig[i] == ome) key = i;
+
+ MPI_Comm_split(uorig,0,key,&uworld);
+ MPI_Comm_rank(uworld,&me);
+ MPI_Comm_size(uworld,&nprocs);
}
/* ----------------------------------------------------------------------
add 1 or more worlds to universe
str == NULL -> add 1 world with all procs in universe
str = NxM -> add N worlds, each with M procs
str = P -> add 1 world with P procs
------------------------------------------------------------------------- */
void Universe::add_world(char *str)
{
int n,nper;
char *ptr;
if (str == NULL) {
n = 1;
nper = nprocs;
} else if ((ptr = strchr(str,'x')) != NULL) {
*ptr = '\0';
n = atoi(str);
nper = atoi(ptr+1);
} else {
n = 1;
nper = atoi(str);
}
memory->grow(procs_per_world,nworlds+n,"universe:procs_per_world");
memory->grow(root_proc,(nworlds+n),"universe:root_proc");
for (int i = 0; i < n; i++) {
procs_per_world[nworlds] = nper;
if (nworlds == 0) root_proc[nworlds] = 0;
else
root_proc[nworlds] = root_proc[nworlds-1] + procs_per_world[nworlds-1];
if (me >= root_proc[nworlds]) iworld = nworlds;
nworlds++;
}
}
/* ----------------------------------------------------------------------
check if total procs in all worlds = procs in universe
------------------------------------------------------------------------- */
int Universe::consistent()
{
int n = 0;
for (int i = 0; i < nworlds; i++) n += procs_per_world[i];
if (n == nprocs) return 1;
else return 0;
}
diff --git a/src/universe.h b/src/universe.h
index e90984f51..1c24ab727 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -1,46 +1,51 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef LMP_UNIVERSE_H
#define LMP_UNIVERSE_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Universe : protected Pointers {
public:
char *version; // LAMMPS version string = date
MPI_Comm uworld; // communicator for entire universe
int me,nprocs; // my place in universe
FILE *uscreen; // universe screen output
FILE *ulogfile; // universe logfile
int existflag; // 1 if universe exists due to -partition flag
int nworlds; // # of worlds in universe
int iworld; // which world I am in
int *procs_per_world; // # of procs in each world
int *root_proc; // root proc in each world
+ MPI_Comm uorig; // original communicator passed to LAMMPS instance
+ int *uni2orig; // proc I in universe uworld is
+ // proc uni2orig[I] in original communicator
+
Universe(class LAMMPS *, MPI_Comm);
~Universe();
+ void reorder(char *, char *);
void add_world(char *);
int consistent();
};
}
#endif
diff --git a/src/variable.cpp b/src/variable.cpp
index c6f955f75..428e8939f 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -1,3307 +1,3306 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#include "unistd.h"
#include "variable.h"
#include "universe.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "domain.h"
#include "region.h"
#include "modify.h"
#include "compute.h"
#include "fix.h"
#include "output.h"
#include "thermo.h"
#include "random_mars.h"
+#include "math_const.h"
#include "memory.h"
#include "error.h"
-#include "math_const.h"
-
using namespace LAMMPS_NS;
using namespace MathConst;
#define VARDELTA 4
#define MAXLEVEL 4
#define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a)
enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,EQUAL,ATOM};
enum{ARG,OP};
// customize by adding a function
enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY,
NOT,EQ,NE,LT,LE,GT,GE,AND,OR,
SQRT,EXP,LN,LOG,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,
VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY};
// customize by adding a special function
enum{SUM,XMIN,XMAX,AVE,TRAP};
#define INVOKED_SCALAR 1
#define INVOKED_VECTOR 2
#define INVOKED_ARRAY 4
#define INVOKED_PERATOM 8
#define BIG 1.0e20
/* ---------------------------------------------------------------------- */
Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
nvar = maxvar = 0;
names = NULL;
style = NULL;
num = NULL;
which = NULL;
pad = NULL;
data = NULL;
randomequal = NULL;
randomatom = NULL;
precedence[DONE] = 0;
precedence[OR] = 1;
precedence[AND] = 2;
precedence[EQ] = precedence[NE] = 3;
precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 4;
precedence[ADD] = precedence[SUBTRACT] = 5;
precedence[MULTIPLY] = precedence[DIVIDE] = 6;
precedence[CARAT] = 7;
precedence[UNARY] = precedence[NOT] = 8;
}
/* ---------------------------------------------------------------------- */
Variable::~Variable()
{
for (int i = 0; i < nvar; i++) {
delete [] names[i];
if (style[i] == LOOP || style[i] == ULOOP) delete [] data[i][0];
else for (int j = 0; j < num[i]; j++) delete [] data[i][j];
delete [] data[i];
}
memory->sfree(names);
memory->destroy(style);
memory->destroy(num);
memory->destroy(which);
memory->destroy(pad);
memory->sfree(data);
delete randomequal;
delete randomatom;
}
/* ----------------------------------------------------------------------
called by variable command in input script
------------------------------------------------------------------------- */
void Variable::set(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Illegal variable command");
// DELETE
// doesn't matter if variable no longer exists
if (strcmp(arg[1],"delete") == 0) {
if (narg != 2) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) remove(find(arg[0]));
return;
// INDEX
// num = listed args, which = 1st value, data = copied args
} else if (strcmp(arg[1],"index") == 0) {
if (narg < 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) return;
if (nvar == maxvar) extend();
style[nvar] = INDEX;
num[nvar] = narg - 2;
which[nvar] = 0;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(num[nvar],&arg[2],data[nvar]);
// LOOP
// 1 arg + pad: num = N, which = 1st value, data = single string
// 2 args + pad: num = N2, which = N1, data = single string
} else if (strcmp(arg[1],"loop") == 0) {
if (find(arg[0]) >= 0) return;
if (nvar == maxvar) extend();
style[nvar] = LOOP;
int nfirst,nlast;
if (narg == 3 || (narg == 4 && strcmp(arg[3],"pad") == 0)) {
nfirst = 1;
nlast = atoi(arg[2]);
if (nlast <= 0) error->all(FLERR,"Illegal variable command");
if (narg == 4 && strcmp(arg[3],"pad") == 0) {
char digits[12];
sprintf(digits,"%d",nlast);
pad[nvar] = strlen(digits);
} else pad[nvar] = 0;
} else if (narg == 4 || (narg == 5 && strcmp(arg[4],"pad") == 0)) {
nfirst = atoi(arg[2]);
nlast = atoi(arg[3]);
if (nfirst > nlast || nlast <= 0) error->all(FLERR,"Illegal variable command");
if (narg == 5 && strcmp(arg[4],"pad") == 0) {
char digits[12];
sprintf(digits,"%d",nlast);
pad[nvar] = strlen(digits);
} else pad[nvar] = 0;
} else error->all(FLERR,"Illegal variable command");
num[nvar] = nlast;
which[nvar] = nfirst-1;
data[nvar] = new char*[1];
data[nvar][0] = NULL;
// WORLD
// num = listed args, which = partition this proc is in, data = copied args
// error check that num = # of worlds in universe
} else if (strcmp(arg[1],"world") == 0) {
if (narg < 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) return;
if (nvar == maxvar) extend();
style[nvar] = WORLD;
num[nvar] = narg - 2;
if (num[nvar] != universe->nworlds)
error->all(FLERR,"World variable count doesn't match # of partitions");
which[nvar] = universe->iworld;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(num[nvar],&arg[2],data[nvar]);
// UNIVERSE and ULOOP
// for UNIVERSE: num = listed args, data = copied args
// for ULOOP: num = N, data = single string
// which = partition this proc is in
// universe proc 0 creates lock file
// error check that all other universe/uloop variables are same length
} else if (strcmp(arg[1],"universe") == 0 || strcmp(arg[1],"uloop") == 0) {
if (strcmp(arg[1],"universe") == 0) {
if (narg < 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) return;
if (nvar == maxvar) extend();
style[nvar] = UNIVERSE;
num[nvar] = narg - 2;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(num[nvar],&arg[2],data[nvar]);
} else if (strcmp(arg[1],"uloop") == 0) {
if (narg < 3 || narg > 4 || (narg == 4 && strcmp(arg[3],"pad") != 0))
error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) return;
if (nvar == maxvar) extend();
style[nvar] = ULOOP;
num[nvar] = atoi(arg[2]);
data[nvar] = new char*[1];
data[nvar][0] = NULL;
if (narg == 4) {
char digits[12];
sprintf(digits,"%d",num[nvar]);
pad[nvar] = strlen(digits);
} else pad[nvar] = 0;
}
if (num[nvar] < universe->nworlds)
error->all(FLERR,"Universe/uloop variable count < # of partitions");
which[nvar] = universe->iworld;
if (universe->me == 0) {
FILE *fp = fopen("tmp.lammps.variable","w");
fprintf(fp,"%d\n",universe->nworlds);
fclose(fp);
}
for (int jvar = 0; jvar < nvar; jvar++)
if (num[jvar] && (style[jvar] == UNIVERSE || style[jvar] == ULOOP) &&
num[nvar] != num[jvar])
error->all(FLERR,"All universe/uloop variables must have same # of values");
// STRING
// remove pre-existing var if also style STRING (allows it to be reset)
// num = 1, which = 1st value
// data = 1 value, string to eval
} else if (strcmp(arg[1],"string") == 0) {
if (narg != 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) {
if (style[find(arg[0])] != STRING)
error->all(FLERR,"Cannot redefine variable as a different style");
remove(find(arg[0]));
}
if (nvar == maxvar) extend();
style[nvar] = STRING;
num[nvar] = 1;
which[nvar] = 0;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(1,&arg[2],data[nvar]);
// EQUAL
// remove pre-existing var if also style EQUAL (allows it to be reset)
// num = 2, which = 1st value
// data = 2 values, 1st is string to eval, 2nd is filled on retrieval
} else if (strcmp(arg[1],"equal") == 0) {
if (narg != 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) {
if (style[find(arg[0])] != EQUAL)
error->all(FLERR,"Cannot redefine variable as a different style");
remove(find(arg[0]));
}
if (nvar == maxvar) extend();
style[nvar] = EQUAL;
num[nvar] = 2;
which[nvar] = 0;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(1,&arg[2],data[nvar]);
data[nvar][1] = NULL;
// ATOM
// remove pre-existing var if also style ATOM (allows it to be reset)
// num = 1, which = 1st value
// data = 1 value, string to eval
} else if (strcmp(arg[1],"atom") == 0) {
if (narg != 3) error->all(FLERR,"Illegal variable command");
if (find(arg[0]) >= 0) {
if (style[find(arg[0])] != ATOM)
error->all(FLERR,"Cannot redefine variable as a different style");
remove(find(arg[0]));
}
if (nvar == maxvar) extend();
style[nvar] = ATOM;
num[nvar] = 1;
which[nvar] = 0;
pad[nvar] = 0;
data[nvar] = new char*[num[nvar]];
copy(1,&arg[2],data[nvar]);
} else error->all(FLERR,"Illegal variable command");
// set name of variable
// must come at end, since STRING/EQUAL/ATOM reset may have removed name
// name must be all alphanumeric chars or underscores
int n = strlen(arg[0]) + 1;
names[nvar] = new char[n];
strcpy(names[nvar],arg[0]);
for (int i = 0; i < n-1; i++)
if (!isalnum(names[nvar][i]) && names[nvar][i] != '_')
error->all(FLERR,"Variable name must be alphanumeric or "
"underscore characters");
nvar++;
}
/* ----------------------------------------------------------------------
INDEX variable created by command-line argument
make it INDEX rather than STRING so cannot be re-defined in input script
------------------------------------------------------------------------- */
void Variable::set(char *name, int narg, char **arg)
{
char **newarg = new char*[2+narg];
newarg[0] = name;
newarg[1] = (char *) "index";
for (int i = 0; i < narg; i++) newarg[2+i] = arg[i];
set(2+narg,newarg);
delete [] newarg;
}
/* ----------------------------------------------------------------------
increment variable(s)
return 0 if OK if successfully incremented
return 1 if any variable is exhausted, free the variable to allow re-use
------------------------------------------------------------------------- */
int Variable::next(int narg, char **arg)
{
int ivar;
if (narg == 0) error->all(FLERR,"Illegal next command");
// check that variables exist and are all the same style
// exception: UNIVERSE and ULOOP variables can be mixed in same next command
for (int iarg = 0; iarg < narg; iarg++) {
ivar = find(arg[iarg]);
if (ivar == -1) error->all(FLERR,"Invalid variable in next command");
if (style[ivar] == ULOOP && style[find(arg[0])] == UNIVERSE) continue;
else if (style[ivar] == UNIVERSE && style[find(arg[0])] == ULOOP) continue;
else if (style[ivar] != style[find(arg[0])])
error->all(FLERR,"All variables in next command must be same style");
}
// invalid styles STRING or EQUAL or WORLD or ATOM
int istyle = style[find(arg[0])];
if (istyle == STRING || istyle == EQUAL || istyle == WORLD || istyle == ATOM)
error->all(FLERR,"Invalid variable style with next command");
// increment all variables in list
// if any variable is exhausted, set flag = 1 and remove var to allow re-use
int flag = 0;
if (istyle == INDEX || istyle == LOOP) {
for (int iarg = 0; iarg < narg; iarg++) {
ivar = find(arg[iarg]);
which[ivar]++;
if (which[ivar] >= num[ivar]) {
flag = 1;
remove(ivar);
}
}
} else if (istyle == UNIVERSE || istyle == ULOOP) {
// wait until lock file can be created and owned by proc 0 of this world
// read next available index and Bcast it within my world
// set all variables in list to nextindex
int nextindex;
if (me == 0) {
while (1) {
if (!rename("tmp.lammps.variable","tmp.lammps.variable.lock")) break;
usleep(100000);
}
FILE *fp = fopen("tmp.lammps.variable.lock","r");
fscanf(fp,"%d",&nextindex);
fclose(fp);
fp = fopen("tmp.lammps.variable.lock","w");
fprintf(fp,"%d\n",nextindex+1);
fclose(fp);
rename("tmp.lammps.variable.lock","tmp.lammps.variable");
if (universe->uscreen)
fprintf(universe->uscreen,
"Increment via next: value %d on partition %d\n",
nextindex+1,universe->iworld);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Increment via next: value %d on partition %d\n",
nextindex+1,universe->iworld);
}
MPI_Bcast(&nextindex,1,MPI_INT,0,world);
for (int iarg = 0; iarg < narg; iarg++) {
ivar = find(arg[iarg]);
which[ivar] = nextindex;
if (which[ivar] >= num[ivar]) {
flag = 1;
remove(ivar);
}
}
}
return flag;
}
/* ----------------------------------------------------------------------
return ptr to the data text associated with a variable
if INDEX or WORLD or UNIVERSE or STRING var, return ptr to stored string
if LOOP or ULOOP var, write int to data[0] and return ptr to string
if EQUAL var, evaluate variable and put result in str
if ATOM var, return NULL
return NULL if no variable or which is bad, caller must respond
------------------------------------------------------------------------- */
char *Variable::retrieve(char *name)
{
int ivar = find(name);
if (ivar == -1) return NULL;
if (which[ivar] >= num[ivar]) return NULL;
char *str;
if (style[ivar] == INDEX || style[ivar] == WORLD ||
style[ivar] == UNIVERSE || style[ivar] == STRING) {
str = data[ivar][which[ivar]];
} else if (style[ivar] == LOOP || style[ivar] == ULOOP) {
char result[16];
if (pad[ivar] == 0) sprintf(result,"%d",which[ivar]+1);
else {
char padstr[16];
sprintf(padstr,"%%0%dd",pad[ivar]);
sprintf(result,padstr,which[ivar]+1);
}
int n = strlen(result) + 1;
delete [] data[ivar][0];
data[ivar][0] = new char[n];
strcpy(data[ivar][0],result);
str = data[ivar][0];
} else if (style[ivar] == EQUAL) {
char result[32];
double answer = evaluate(data[ivar][0],NULL);
sprintf(result,"%.10g",answer);
int n = strlen(result) + 1;
if (data[ivar][1]) delete [] data[ivar][1];
data[ivar][1] = new char[n];
strcpy(data[ivar][1],result);
str = data[ivar][1];
} else if (style[ivar] == ATOM) return NULL;
return str;
}
/* ----------------------------------------------------------------------
return result of equal-style variable evaluation
------------------------------------------------------------------------- */
double Variable::compute_equal(int ivar)
{
return evaluate(data[ivar][0],NULL);
}
/* ----------------------------------------------------------------------
compute result of atom-style variable evaluation
only computed for atoms in igroup, else result is 0.0
answers are placed every stride locations into result
if sumflag, add variable values to existing result
------------------------------------------------------------------------- */
void Variable::compute_atom(int ivar, int igroup,
double *result, int stride, int sumflag)
{
Tree *tree;
double tmp = evaluate(data[ivar][0],&tree);
tmp = collapse_tree(tree);
int groupbit = group->bitmask[igroup];
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (sumflag == 0) {
int m = 0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) result[m] = eval_tree(tree,i);
else result[m] = 0.0;
m += stride;
}
} else {
int m = 0;
for (int i = 0; i < nlocal; i++) {
if (mask[i] && groupbit) result[m] += eval_tree(tree,i);
m += stride;
}
}
free_tree(tree);
}
/* ----------------------------------------------------------------------
search for name in list of variables names
return index or -1 if not found
------------------------------------------------------------------------- */
int Variable::find(char *name)
{
for (int i = 0; i < nvar; i++)
if (strcmp(name,names[i]) == 0) return i;
return -1;
}
/* ----------------------------------------------------------------------
return 1 if variable is EQUAL style, 0 if not
------------------------------------------------------------------------- */
int Variable::equalstyle(int ivar)
{
if (style[ivar] == EQUAL) return 1;
return 0;
}
/* ----------------------------------------------------------------------
return 1 if variable is ATOM style, 0 if not
------------------------------------------------------------------------- */
int Variable::atomstyle(int ivar)
{
if (style[ivar] == ATOM) return 1;
return 0;
}
/* ----------------------------------------------------------------------
remove Nth variable from list and compact list
------------------------------------------------------------------------- */
void Variable::remove(int n)
{
delete [] names[n];
if (style[n] == LOOP || style[n] == ULOOP) delete [] data[n][0];
else for (int i = 0; i < num[n]; i++) delete [] data[n][i];
delete [] data[n];
for (int i = n+1; i < nvar; i++) {
names[i-1] = names[i];
style[i-1] = style[i];
num[i-1] = num[i];
which[i-1] = which[i];
pad[i-1] = pad[i];
data[i-1] = data[i];
}
nvar--;
}
/* ----------------------------------------------------------------------
make space in arrays for new variable
------------------------------------------------------------------------- */
void Variable::extend()
{
maxvar += VARDELTA;
names = (char **)
memory->srealloc(names,maxvar*sizeof(char *),"var:names");
memory->grow(style,maxvar,"var:style");
memory->grow(num,maxvar,"var:num");
memory->grow(which,maxvar,"var:which");
memory->grow(pad,maxvar,"var:pad");
data = (char ***)
memory->srealloc(data,maxvar*sizeof(char **),"var:data");
}
/* ----------------------------------------------------------------------
copy narg strings from **from to **to, and allocate space for them
------------------------------------------------------------------------- */
void Variable::copy(int narg, char **from, char **to)
{
int n;
for (int i = 0; i < narg; i++) {
n = strlen(from[i]) + 1;
to[i] = new char[n];
strcpy(to[i],from[i]);
}
}
/* ----------------------------------------------------------------------
recursive evaluation of a string str
str is an equal-style or atom-style formula containing one or more items:
number = 0.0, -5.45, 2.8e-4, ...
constant = PI
thermo keyword = ke, vol, atoms, ...
math operation = (),-x,x+y,x-y,x*y,x/y,x^y,
x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y,
sqrt(x),exp(x),ln(x),log(x),
sin(x),cos(x),tan(x),asin(x),atan2(y,x),...
group function = count(group), mass(group), xcm(group,x), ...
special function = sum(x),min(x), ...
atom value = x[i], y[i], vx[i], ...
atom vector = x, y, vx, ...
compute = c_ID, c_ID[i], c_ID[i][j]
fix = f_ID, f_ID[i], f_ID[i][j]
variable = v_name, v_name[i]
equal-style variables passes in tree = NULL:
evaluate the formula, return result as a double
atom-style variable passes in tree = non-NULL:
parse the formula but do not evaluate it
create a parse tree and return it
------------------------------------------------------------------------- */
double Variable::evaluate(char *str, Tree **tree)
{
int op,opprevious;
double value1,value2;
char onechar;
char *ptr;
double argstack[MAXLEVEL];
Tree *treestack[MAXLEVEL];
int opstack[MAXLEVEL];
int nargstack = 0;
int ntreestack = 0;
int nopstack = 0;
int i = 0;
int expect = ARG;
while (1) {
onechar = str[i];
// whitespace: just skip
if (isspace(onechar)) i++;
// ----------------
// parentheses: recursively evaluate contents of parens
// ----------------
else if (onechar == '(') {
if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula");
expect = OP;
char *contents;
i = find_matching_paren(str,i,contents);
i++;
// evaluate contents and push on stack
if (tree) {
Tree *newtree;
evaluate(contents,&newtree);
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = evaluate(contents,NULL);
delete [] contents;
// ----------------
// number: push value onto stack
// ----------------
} else if (isdigit(onechar) || onechar == '.') {
if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula");
expect = OP;
// istop = end of number, including scientific notation
int istart = i;
while (isdigit(str[i]) || str[i] == '.') i++;
if (str[i] == 'e' || str[i] == 'E') {
i++;
if (str[i] == '+' || str[i] == '-') i++;
while (isdigit(str[i])) i++;
}
int istop = i - 1;
int n = istop - istart + 1;
char *number = new char[n+1];
strncpy(number,&str[istart],n);
number[n] = '\0';
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = atof(number);
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = atof(number);
delete [] number;
// ----------------
// letter: c_ID, c_ID[], c_ID[][], f_ID, f_ID[], f_ID[][],
// v_name, v_name[], exp(), xcm(,), x, x[], PI, vol
// ----------------
} else if (isalpha(onechar)) {
if (expect == OP) error->all(FLERR,"Invalid syntax in variable formula");
expect = OP;
// istop = end of word
// word = all alphanumeric or underscore
int istart = i;
while (isalnum(str[i]) || str[i] == '_') i++;
int istop = i-1;
int n = istop - istart + 1;
char *word = new char[n+1];
strncpy(word,&str[istart],n);
word[n] = '\0';
// ----------------
// compute
// ----------------
if (strncmp(word,"c_",2) == 0) {
if (domain->box_exist == 0)
error->all(FLERR,"Variable evaluation before simulation box is defined");
n = strlen(word) - 2 + 1;
char *id = new char[n];
strcpy(id,&word[2]);
int icompute = modify->find_compute(id);
if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula");
Compute *compute = modify->compute[icompute];
delete [] id;
// parse zero or one or two trailing brackets
// point i beyond last bracket
// nbracket = # of bracket pairs
// index1,index2 = int inside each bracket pair
int nbracket,index1,index2;
if (str[i] != '[') nbracket = 0;
else {
nbracket = 1;
ptr = &str[i];
index1 = int_between_brackets(ptr);
i = ptr-str+1;
if (str[i] == '[') {
nbracket = 2;
ptr = &str[i];
index2 = int_between_brackets(ptr);
i = ptr-str+1;
}
}
// c_ID = scalar from global scalar
if (nbracket == 0 && compute->scalar_flag) {
if (update->whichflag == 0) {
if (compute->invoked_scalar != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_SCALAR)) {
compute->compute_scalar();
compute->invoked_flag |= INVOKED_SCALAR;
}
value1 = compute->scalar;
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// c_ID[i] = scalar from global vector
} else if (nbracket == 1 && compute->vector_flag) {
if (index1 > compute->size_vector)
error->all(FLERR,"Variable formula compute vector "
"is accessed out-of-range");
if (update->whichflag == 0) {
if (compute->invoked_vector != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
compute->compute_vector();
compute->invoked_flag |= INVOKED_VECTOR;
}
value1 = compute->vector[index1-1];
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// c_ID[i][j] = scalar from global array
} else if (nbracket == 2 && compute->array_flag) {
if (index1 > compute->size_array_rows)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
if (index2 > compute->size_array_cols)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
if (update->whichflag == 0) {
if (compute->invoked_array != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
compute->compute_array();
compute->invoked_flag |= INVOKED_ARRAY;
}
value1 = compute->array[index1-1][index2-1];
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// c_ID[i] = scalar from per-atom vector
} else if (nbracket == 1 && compute->peratom_flag &&
compute->size_peratom_cols == 0) {
if (update->whichflag == 0) {
if (compute->invoked_peratom != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
compute->compute_peratom();
compute->invoked_flag |= INVOKED_PERATOM;
}
peratom2global(1,NULL,compute->vector_atom,1,index1,
tree,treestack,ntreestack,argstack,nargstack);
// c_ID[i][j] = scalar from per-atom array
} else if (nbracket == 2 && compute->peratom_flag &&
compute->size_peratom_cols > 0) {
if (index2 > compute->size_peratom_cols)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
if (update->whichflag == 0) {
if (compute->invoked_peratom != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
compute->compute_peratom();
compute->invoked_flag |= INVOKED_PERATOM;
}
peratom2global(1,NULL,&compute->array_atom[0][index2-1],
compute->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
// c_ID = vector from per-atom vector
} else if (nbracket == 0 && compute->peratom_flag &&
compute->size_peratom_cols == 0) {
if (tree == NULL)
error->all(FLERR,"Per-atom compute in equal-style variable formula");
if (update->whichflag == 0) {
if (compute->invoked_peratom != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
compute->compute_peratom();
compute->invoked_flag |= INVOKED_PERATOM;
}
Tree *newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = compute->vector_atom;
newtree->nstride = 1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
// c_ID[i] = vector from per-atom array
} else if (nbracket == 1 && compute->peratom_flag &&
compute->size_peratom_cols > 0) {
if (tree == NULL)
error->all(FLERR,"Per-atom compute in equal-style variable formula");
if (index1 > compute->size_peratom_cols)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
if (update->whichflag == 0) {
if (compute->invoked_peratom != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs "
"is not current");
} else if (!(compute->invoked_flag & INVOKED_PERATOM)) {
compute->compute_peratom();
compute->invoked_flag |= INVOKED_PERATOM;
}
Tree *newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = &compute->array_atom[0][index1-1];
newtree->nstride = compute->size_peratom_cols;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else error->all(FLERR,"Mismatched compute in variable formula");
// ----------------
// fix
// ----------------
} else if (strncmp(word,"f_",2) == 0) {
if (domain->box_exist == 0)
error->all(FLERR,"Variable evaluation before simulation box is defined");
n = strlen(word) - 2 + 1;
char *id = new char[n];
strcpy(id,&word[2]);
int ifix = modify->find_fix(id);
if (ifix < 0) error->all(FLERR,"Invalid fix ID in variable formula");
Fix *fix = modify->fix[ifix];
delete [] id;
// parse zero or one or two trailing brackets
// point i beyond last bracket
// nbracket = # of bracket pairs
// index1,index2 = int inside each bracket pair
int nbracket,index1,index2;
if (str[i] != '[') nbracket = 0;
else {
nbracket = 1;
ptr = &str[i];
index1 = int_between_brackets(ptr);
i = ptr-str+1;
if (str[i] == '[') {
nbracket = 2;
ptr = &str[i];
index2 = int_between_brackets(ptr);
i = ptr-str+1;
}
}
// f_ID = scalar from global scalar
if (nbracket == 0 && fix->scalar_flag) {
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
value1 = fix->compute_scalar();
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// f_ID[i] = scalar from global vector
} else if (nbracket == 1 && fix->vector_flag) {
if (index1 > fix->size_vector)
error->all(FLERR,"Variable formula fix vector is accessed out-of-range");
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
value1 = fix->compute_vector(index1-1);
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// f_ID[i][j] = scalar from global array
} else if (nbracket == 2 && fix->array_flag) {
if (index1 > fix->size_array_rows)
error->all(FLERR,"Variable formula fix array is accessed out-of-range");
if (index2 > fix->size_array_cols)
error->all(FLERR,"Variable formula fix array is accessed out-of-range");
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
value1 = fix->compute_array(index1-1,index2-1);
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// f_ID[i] = scalar from per-atom vector
} else if (nbracket == 1 && fix->peratom_flag &&
fix->size_peratom_cols == 0) {
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
peratom2global(1,NULL,fix->vector_atom,1,index1,
tree,treestack,ntreestack,argstack,nargstack);
// f_ID[i][j] = scalar from per-atom array
} else if (nbracket == 2 && fix->peratom_flag &&
fix->size_peratom_cols > 0) {
if (index2 > fix->size_peratom_cols)
error->all(FLERR,"Variable formula fix array is accessed out-of-range");
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
peratom2global(1,NULL,&fix->array_atom[0][index2-1],
fix->size_peratom_cols,index1,
tree,treestack,ntreestack,argstack,nargstack);
// f_ID = vector from per-atom vector
} else if (nbracket == 0 && fix->peratom_flag &&
fix->size_peratom_cols == 0) {
if (tree == NULL)
error->all(FLERR,"Per-atom fix in equal-style variable formula");
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
Tree *newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = fix->vector_atom;
newtree->nstride = 1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
// f_ID[i] = vector from per-atom array
} else if (nbracket == 1 && fix->peratom_flag &&
fix->size_peratom_cols > 0) {
if (tree == NULL)
error->all(FLERR,"Per-atom fix in equal-style variable formula");
if (index1 > fix->size_peratom_cols)
error->all(FLERR,"Variable formula fix array is accessed out-of-range");
if (update->whichflag > 0 &&
update->ntimestep % fix->peratom_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
Tree *newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->array = &fix->array_atom[0][index1-1];
newtree->nstride = fix->size_peratom_cols;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else error->all(FLERR,"Mismatched fix in variable formula");
// ----------------
// variable
// ----------------
} else if (strncmp(word,"v_",2) == 0) {
n = strlen(word) - 2 + 1;
char *id = new char[n];
strcpy(id,&word[2]);
int ivar = find(id);
if (ivar < 0) error->all(FLERR,"Invalid variable name in variable formula");
// parse zero or one trailing brackets
// point i beyond last bracket
// nbracket = # of bracket pairs
// index = int inside bracket
int nbracket,index;
if (str[i] != '[') nbracket = 0;
else {
nbracket = 1;
ptr = &str[i];
index = int_between_brackets(ptr);
i = ptr-str+1;
}
// v_name = scalar from non atom-style global scalar
if (nbracket == 0 && style[ivar] != ATOM) {
char *var = retrieve(id);
if (var == NULL)
error->all(FLERR,"Invalid variable evaluation in variable formula");
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = atof(var);
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = atof(var);
// v_name = vector from atom-style per-atom vector
} else if (nbracket == 0 && style[ivar] == ATOM) {
if (tree == NULL)
error->all(FLERR,"Atom-style variable in equal-style variable formula");
Tree *newtree;
evaluate(data[ivar][0],&newtree);
treestack[ntreestack++] = newtree;
// v_name[N] = scalar from atom-style per-atom vector
// compute the per-atom variable in result
// use peratom2global to extract single value from result
} else if (nbracket && style[ivar] == ATOM) {
double *result;
memory->create(result,atom->nlocal,"variable:result");
compute_atom(ivar,0,result,1,0);
peratom2global(1,NULL,result,1,index,
tree,treestack,ntreestack,argstack,nargstack);
memory->destroy(result);
} else error->all(FLERR,"Mismatched variable in variable formula");
delete [] id;
// ----------------
// math/group/special function or atom value/vector or
// constant or thermo keyword
// ----------------
} else {
// ----------------
// math or group or special function
// ----------------
if (str[i] == '(') {
char *contents;
i = find_matching_paren(str,i,contents);
i++;
if (math_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
else if (group_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
else if (special_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
else error->all(FLERR,"Invalid math/group/special function "
"in variable formula");
delete [] contents;
// ----------------
// atom value
// ----------------
} else if (str[i] == '[') {
if (domain->box_exist == 0)
error->all(FLERR,"Variable evaluation before simulation box is defined");
ptr = &str[i];
int id = int_between_brackets(ptr);
i = ptr-str+1;
peratom2global(0,word,NULL,0,id,
tree,treestack,ntreestack,argstack,nargstack);
// ----------------
// atom vector
// ----------------
} else if (is_atom_vector(word)) {
if (domain->box_exist == 0)
error->all(FLERR,"Variable evaluation before simulation box is defined");
atom_vector(word,tree,treestack,ntreestack);
// ----------------
// constant
// ----------------
} else if (is_constant(word)) {
value1 = constant(word);
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
// ----------------
// thermo keyword
// ----------------
} else {
if (domain->box_exist == 0)
error->all(FLERR,"Variable evaluation before simulation box is defined");
int flag = output->thermo->evaluate_keyword(word,&value1);
if (flag) error->all(FLERR,"Invalid thermo keyword in variable formula");
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value1;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value1;
}
}
delete [] word;
// ----------------
// math operator, including end-of-string
// ----------------
} else if (strchr("+-*/^<>=!&|\0",onechar)) {
if (onechar == '+') op = ADD;
else if (onechar == '-') op = SUBTRACT;
else if (onechar == '*') op = MULTIPLY;
else if (onechar == '/') op = DIVIDE;
else if (onechar == '^') op = CARAT;
else if (onechar == '=') {
if (str[i+1] != '=') error->all(FLERR,"Invalid syntax in variable formula");
op = EQ;
i++;
} else if (onechar == '!') {
if (str[i+1] == '=') {
op = NE;
i++;
} else op = NOT;
} else if (onechar == '<') {
if (str[i+1] != '=') op = LT;
else {
op = LE;
i++;
}
} else if (onechar == '>') {
if (str[i+1] != '=') op = GT;
else {
op = GE;
i++;
}
} else if (onechar == '&') {
if (str[i+1] != '&') error->all(FLERR,"Invalid syntax in variable formula");
op = AND;
i++;
} else if (onechar == '|') {
if (str[i+1] != '|') error->all(FLERR,"Invalid syntax in variable formula");
op = OR;
i++;
} else op = DONE;
i++;
if (op == SUBTRACT && expect == ARG) {
opstack[nopstack++] = UNARY;
continue;
}
if (op == NOT && expect == ARG) {
opstack[nopstack++] = op;
continue;
}
if (expect == ARG) error->all(FLERR,"Invalid syntax in variable formula");
expect = ARG;
// evaluate stack as deep as possible while respecting precedence
// before pushing current op onto stack
while (nopstack && precedence[opstack[nopstack-1]] >= precedence[op]) {
opprevious = opstack[--nopstack];
if (tree) {
Tree *newtree = new Tree();
newtree->type = opprevious;
if (opprevious == UNARY) {
newtree->left = treestack[--ntreestack];
newtree->middle = newtree->right = NULL;
} else {
newtree->right = treestack[--ntreestack];
newtree->middle = NULL;
newtree->left = treestack[--ntreestack];
}
treestack[ntreestack++] = newtree;
} else {
value2 = argstack[--nargstack];
if (opprevious != UNARY && opprevious != NOT)
value1 = argstack[--nargstack];
if (opprevious == ADD)
argstack[nargstack++] = value1 + value2;
else if (opprevious == SUBTRACT)
argstack[nargstack++] = value1 - value2;
else if (opprevious == MULTIPLY)
argstack[nargstack++] = value1 * value2;
else if (opprevious == DIVIDE) {
if (value2 == 0.0) error->all(FLERR,"Divide by 0 in variable formula");
argstack[nargstack++] = value1 / value2;
} else if (opprevious == CARAT) {
if (value2 == 0.0) error->all(FLERR,"Power by 0 in variable formula");
argstack[nargstack++] = pow(value1,value2);
} else if (opprevious == UNARY) {
argstack[nargstack++] = -value2;
} else if (opprevious == NOT) {
if (value2 == 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == EQ) {
if (value1 == value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == NE) {
if (value1 != value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LT) {
if (value1 < value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LE) {
if (value1 <= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GT) {
if (value1 > value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GE) {
if (value1 >= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == AND) {
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == OR) {
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
}
}
}
// if end-of-string, break out of entire formula evaluation loop
if (op == DONE) break;
// push current operation onto stack
opstack[nopstack++] = op;
} else error->all(FLERR,"Invalid syntax in variable formula");
}
if (nopstack) error->all(FLERR,"Invalid syntax in variable formula");
// for atom-style variable, return remaining tree
// for equal-style variable, return remaining arg
if (tree) {
if (ntreestack != 1) error->all(FLERR,"Invalid syntax in variable formula");
*tree = treestack[0];
return 0.0;
} else {
if (nargstack != 1) error->all(FLERR,"Invalid syntax in variable formula");
return argstack[0];
}
}
/* ----------------------------------------------------------------------
one-time collapse of an atom-style variable parse tree
tree was created by one-time parsing of formula string via evaulate()
only keep tree nodes that depend on ATOMARRAY, TYPEARRAY, INTARRAY
remainder is converted to single VALUE
this enables optimal eval_tree loop over atoms
customize by adding a function:
sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
ramp(x,y),stagger(x,y),logfreq(x,y,z),
vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z),
gmask(x),rmask(x),grmask(x,y)
---------------------------------------------------------------------- */
double Variable::collapse_tree(Tree *tree)
{
double arg1,arg2;
if (tree->type == VALUE) return tree->value;
if (tree->type == ATOMARRAY) return 0.0;
if (tree->type == TYPEARRAY) return 0.0;
if (tree->type == INTARRAY) return 0.0;
if (tree->type == ADD) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = arg1 + arg2;
return tree->value;
}
if (tree->type == SUBTRACT) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = arg1 - arg2;
return tree->value;
}
if (tree->type == MULTIPLY) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = arg1 * arg2;
return tree->value;
}
if (tree->type == DIVIDE) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg2 == 0.0) error->one(FLERR,"Divide by 0 in variable formula");
tree->value = arg1 / arg2;
return tree->value;
}
if (tree->type == CARAT) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg2 == 0.0) error->one(FLERR,"Power by 0 in variable formula");
tree->value = pow(arg1,arg2);
return tree->value;
}
if (tree->type == UNARY) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = -arg1;
return tree->value;
}
if (tree->type == NOT) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 == 0.0) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == EQ) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 == arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == NE) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 != arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == LT) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 < arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == LE) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 <= arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == GT) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 > arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == GE) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 >= arg2) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == AND) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 != 0.0 && arg2 != 0.0) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == OR) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 != 0.0 || arg2 != 0.0) tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == SQRT) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 < 0.0) error->one(FLERR,"Sqrt of negative value in variable formula");
tree->value = sqrt(arg1);
return tree->value;
}
if (tree->type == EXP) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = exp(arg1);
return tree->value;
}
if (tree->type == LN) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 <= 0.0)
error->one(FLERR,"Log of zero/negative value in variable formula");
tree->value = log(arg1);
return tree->value;
}
if (tree->type == LOG) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 <= 0.0)
error->one(FLERR,"Log of zero/negative value in variable formula");
tree->value = log10(arg1);
return tree->value;
}
if (tree->type == SIN) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = sin(arg1);
return tree->value;
}
if (tree->type == COS) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = cos(arg1);
return tree->value;
}
if (tree->type == TAN) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = tan(arg1);
return tree->value;
}
if (tree->type == ASIN) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 < -1.0 || arg1 > 1.0)
error->one(FLERR,"Arcsin of invalid value in variable formula");
tree->value = asin(arg1);
return tree->value;
}
if (tree->type == ACOS) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg1 < -1.0 || arg1 > 1.0)
error->one(FLERR,"Arccos of invalid value in variable formula");
tree->value = acos(arg1);
return tree->value;
}
if (tree->type == ATAN) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = atan(arg1);
return tree->value;
}
if (tree->type == ATAN2) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = atan2(arg1,arg2);
return tree->value;
}
// random() or normal() do not become a single collapsed value
if (tree->type == RANDOM) {
collapse_tree(tree->left);
collapse_tree(tree->middle);
if (randomatom == NULL) {
int seed = static_cast<int> (collapse_tree(tree->right));
if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula");
randomatom = new RanMars(lmp,seed+me);
}
return 0.0;
}
if (tree->type == NORMAL) {
collapse_tree(tree->left);
double sigma = collapse_tree(tree->middle);
if (sigma < 0.0) error->one(FLERR,"Invalid math function in variable formula");
if (randomatom == NULL) {
int seed = static_cast<int> (collapse_tree(tree->right));
if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula");
randomatom = new RanMars(lmp,seed+me);
}
return 0.0;
}
if (tree->type == CEIL) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = ceil(arg1);
return tree->value;
}
if (tree->type == FLOOR) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = floor(arg1);
return tree->value;
}
if (tree->type == ROUND) {
arg1 = collapse_tree(tree->left);
if (tree->left->type != VALUE) return 0.0;
tree->type = VALUE;
tree->value = MYROUND(arg1);
return tree->value;
}
if (tree->type == RAMP) {
arg1 = collapse_tree(tree->left);
arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
tree->value = arg1 + delta*(arg2-arg1);
return tree->value;
}
if (tree->type == STAGGER) {
int ivalue1 = static_cast<int> (collapse_tree(tree->left));
int ivalue2 = static_cast<int> (collapse_tree(tree->right));
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
error->one(FLERR,"Invalid math function in variable formula");
int lower = update->ntimestep/ivalue1 * ivalue1;
int delta = update->ntimestep - lower;
if (delta < ivalue2) tree->value = lower+ivalue2;
else tree->value = lower+ivalue1;
return tree->value;
}
if (tree->type == LOGFREQ) {
int ivalue1 = static_cast<int> (collapse_tree(tree->left));
int ivalue2 = static_cast<int> (collapse_tree(tree->middle));
int ivalue3 = static_cast<int> (collapse_tree(tree->right));
if (tree->left->type != VALUE || tree->middle->type != VALUE ||
tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
error->one(FLERR,"Invalid math function in variable formula");
if (update->ntimestep < ivalue1) tree->value = ivalue1;
else {
int lower = ivalue1;
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
int multiple = update->ntimestep/lower;
if (multiple < ivalue2) tree->value = (multiple+1)*lower;
else tree->value = lower*ivalue3;
}
return tree->value;
}
if (tree->type == VDISPLACE) {
double arg1 = collapse_tree(tree->left);
double arg2 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
double delta = update->ntimestep - update->beginstep;
tree->value = arg1 + arg2*delta*update->dt;
return tree->value;
}
if (tree->type == SWIGGLE) {
double arg1 = collapse_tree(tree->left);
double arg2 = collapse_tree(tree->middle);
double arg3 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->middle->type != VALUE ||
tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/arg3;
tree->value = arg1 + arg2*sin(omega*delta*update->dt);
return tree->value;
}
if (tree->type == CWIGGLE) {
double arg1 = collapse_tree(tree->left);
double arg2 = collapse_tree(tree->middle);
double arg3 = collapse_tree(tree->right);
if (tree->left->type != VALUE || tree->middle->type != VALUE ||
tree->right->type != VALUE) return 0.0;
tree->type = VALUE;
if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/arg3;
tree->value = arg1 + arg2*(1.0-cos(omega*delta*update->dt));
return tree->value;
}
// mask functions do not become a single collapsed value
if (tree->type == GMASK) return 0.0;
if (tree->type == RMASK) return 0.0;
if (tree->type == GRMASK) return 0.0;
return 0.0;
}
/* ----------------------------------------------------------------------
evaluate an atom-style variable parse tree for atom I
tree was created by one-time parsing of formula string via evaulate()
customize by adding a function:
sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
ramp(x,y),stagger(x,y),logfreq(x,y,z),
vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z),
gmask(x),rmask(x),grmask(x,y)
---------------------------------------------------------------------- */
double Variable::eval_tree(Tree *tree, int i)
{
double arg,arg1,arg2,arg3;
if (tree->type == VALUE) return tree->value;
if (tree->type == ATOMARRAY) return tree->array[i*tree->nstride];
if (tree->type == TYPEARRAY) return tree->array[atom->type[i]];
if (tree->type == INTARRAY) return (double) tree->iarray[i*tree->nstride];
if (tree->type == ADD)
return eval_tree(tree->left,i) + eval_tree(tree->right,i);
if (tree->type == SUBTRACT)
return eval_tree(tree->left,i) - eval_tree(tree->right,i);
if (tree->type == MULTIPLY)
return eval_tree(tree->left,i) * eval_tree(tree->right,i);
if (tree->type == DIVIDE) {
double denom = eval_tree(tree->right,i);
if (denom == 0.0) error->one(FLERR,"Divide by 0 in variable formula");
return eval_tree(tree->left,i) / denom;
}
if (tree->type == CARAT) {
double exponent = eval_tree(tree->right,i);
if (exponent == 0.0) error->one(FLERR,"Power by 0 in variable formula");
return pow(eval_tree(tree->left,i),exponent);
}
if (tree->type == UNARY) return -eval_tree(tree->left,i);
if (tree->type == NOT) {
if (eval_tree(tree->left,i) == 0.0) return 1.0;
else return 0.0;
}
if (tree->type == EQ) {
if (eval_tree(tree->left,i) == eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == NE) {
if (eval_tree(tree->left,i) != eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == LT) {
if (eval_tree(tree->left,i) < eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == LE) {
if (eval_tree(tree->left,i) <= eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == GT) {
if (eval_tree(tree->left,i) > eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == GE) {
if (eval_tree(tree->left,i) >= eval_tree(tree->right,i)) return 1.0;
else return 0.0;
}
if (tree->type == AND) {
if (eval_tree(tree->left,i) != 0.0 && eval_tree(tree->right,i) != 0.0)
return 1.0;
else return 0.0;
}
if (tree->type == OR) {
if (eval_tree(tree->left,i) != 0.0 || eval_tree(tree->right,i) != 0.0)
return 1.0;
else return 0.0;
}
if (tree->type == SQRT) {
arg1 = eval_tree(tree->left,i);
if (arg1 < 0.0) error->one(FLERR,"Sqrt of negative value in variable formula");
return sqrt(arg1);
}
if (tree->type == EXP)
return exp(eval_tree(tree->left,i));
if (tree->type == LN) {
arg1 = eval_tree(tree->left,i);
if (arg1 <= 0.0)
error->one(FLERR,"Log of zero/negative value in variable formula");
return log(arg1);
}
if (tree->type == LOG) {
arg1 = eval_tree(tree->left,i);
if (arg1 <= 0.0)
error->one(FLERR,"Log of zero/negative value in variable formula");
return log10(arg1);
}
if (tree->type == SIN)
return sin(eval_tree(tree->left,i));
if (tree->type == COS)
return cos(eval_tree(tree->left,i));
if (tree->type == TAN)
return tan(eval_tree(tree->left,i));
if (tree->type == ASIN) {
arg1 = eval_tree(tree->left,i);
if (arg1 < -1.0 || arg1 > 1.0)
error->one(FLERR,"Arcsin of invalid value in variable formula");
return asin(arg1);
}
if (tree->type == ACOS) {
arg1 = eval_tree(tree->left,i);
if (arg1 < -1.0 || arg1 > 1.0)
error->one(FLERR,"Arccos of invalid value in variable formula");
return acos(arg1);
}
if (tree->type == ATAN)
return atan(eval_tree(tree->left,i));
if (tree->type == ATAN2)
return atan2(eval_tree(tree->left,i),eval_tree(tree->right,i));
if (tree->type == RANDOM) {
double lower = eval_tree(tree->left,i);
double upper = eval_tree(tree->middle,i);
if (randomatom == NULL) {
int seed = static_cast<int> (eval_tree(tree->right,i));
if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula");
randomatom = new RanMars(lmp,seed+me);
}
return randomatom->uniform()*(upper-lower)+lower;
}
if (tree->type == NORMAL) {
double mu = eval_tree(tree->left,i);
double sigma = eval_tree(tree->middle,i);
if (sigma < 0.0) error->one(FLERR,"Invalid math function in variable formula");
if (randomatom == NULL) {
int seed = static_cast<int> (eval_tree(tree->right,i));
if (seed <= 0) error->one(FLERR,"Invalid math function in variable formula");
randomatom = new RanMars(lmp,seed+me);
}
return mu + sigma*randomatom->gaussian();
}
if (tree->type == CEIL)
return ceil(eval_tree(tree->left,i));
if (tree->type == FLOOR)
return floor(eval_tree(tree->left,i));
if (tree->type == ROUND)
return MYROUND(eval_tree(tree->left,i));
if (tree->type == RAMP) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->right,i);
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
arg = arg1 + delta*(arg2-arg1);
return arg;
}
if (tree->type == STAGGER) {
int ivalue1 = static_cast<int> (eval_tree(tree->left,i));
int ivalue2 = static_cast<int> (eval_tree(tree->right,i));
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
error->one(FLERR,"Invalid math function in variable formula");
int lower = update->ntimestep/ivalue1 * ivalue1;
int delta = update->ntimestep - lower;
if (delta < ivalue2) arg = lower+ivalue2;
else arg = lower+ivalue1;
return arg;
}
if (tree->type == LOGFREQ) {
int ivalue1 = static_cast<int> (eval_tree(tree->left,i));
int ivalue2 = static_cast<int> (eval_tree(tree->middle,i));
int ivalue3 = static_cast<int> (eval_tree(tree->right,i));
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
error->one(FLERR,"Invalid math function in variable formula");
if (update->ntimestep < ivalue1) arg = ivalue1;
else {
int lower = ivalue1;
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
int multiple = update->ntimestep/lower;
if (multiple < ivalue2) arg = (multiple+1)*lower;
else arg = lower*ivalue3;
}
return arg;
}
if (tree->type == VDISPLACE) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->right,i);
double delta = update->ntimestep - update->beginstep;
arg = arg1 + arg2*delta*update->dt;
return arg;
}
if (tree->type == SWIGGLE) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->middle,i);
arg3 = eval_tree(tree->right,i);
if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/arg3;
arg = arg1 + arg2*sin(omega*delta*update->dt);
return arg;
}
if (tree->type == CWIGGLE) {
arg1 = eval_tree(tree->left,i);
arg2 = eval_tree(tree->middle,i);
arg3 = eval_tree(tree->right,i);
if (arg3 == 0.0) error->one(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/arg3;
arg = arg1 + arg2*(1.0-cos(omega*delta*update->dt));
return arg;
}
if (tree->type == GMASK) {
if (atom->mask[i] & tree->ivalue1) return 1.0;
else return 0.0;
}
if (tree->type == RMASK) {
if (domain->regions[tree->ivalue1]->inside(atom->x[i][0],
atom->x[i][1],
atom->x[i][2])) return 1.0;
else return 0.0;
}
if (tree->type == GRMASK) {
if ((atom->mask[i] & tree->ivalue1) &&
(domain->regions[tree->ivalue2]->inside(atom->x[i][0],
atom->x[i][1],
atom->x[i][2]))) return 1.0;
else return 0.0;
}
return 0.0;
}
/* ---------------------------------------------------------------------- */
void Variable::free_tree(Tree *tree)
{
if (tree->left) free_tree(tree->left);
if (tree->middle) free_tree(tree->middle);
if (tree->right) free_tree(tree->right);
delete tree;
}
/* ----------------------------------------------------------------------
find matching parenthesis in str, allocate contents = str between parens
i = left paren
return loc or right paren
------------------------------------------------------------------------- */
int Variable::find_matching_paren(char *str, int i,char *&contents)
{
// istop = matching ')' at same level, allowing for nested parens
int istart = i;
int ilevel = 0;
while (1) {
i++;
if (!str[i]) break;
if (str[i] == '(') ilevel++;
else if (str[i] == ')' && ilevel) ilevel--;
else if (str[i] == ')') break;
}
if (!str[i]) error->all(FLERR,"Invalid syntax in variable formula");
int istop = i;
int n = istop - istart - 1;
contents = new char[n+1];
strncpy(contents,&str[istart+1],n);
contents[n] = '\0';
return istop;
}
/* ----------------------------------------------------------------------
find int between brackets and return it
ptr initially points to left bracket
return it pointing to right bracket
error if no right bracket or brackets are empty
error if any between-bracket chars are non-digits or value == 0
------------------------------------------------------------------------- */
int Variable::int_between_brackets(char *&ptr)
{
char *start = ++ptr;
while (*ptr && *ptr != ']') {
if (!isdigit(*ptr))
error->all(FLERR,"Non digit character between brackets in variable");
ptr++;
}
if (*ptr != ']') error->all(FLERR,"Mismatched brackets in variable");
if (ptr == start) error->all(FLERR,"Empty brackets in variable");
*ptr = '\0';
int index = atoi(start);
*ptr = ']';
if (index == 0)
error->all(FLERR,"Index between variable brackets must be positive");
return index;
}
/* ----------------------------------------------------------------------
process a math function in formula
push result onto tree or arg stack
word = math function
contents = str between parentheses with one,two,three args
return 0 if not a match, 1 if successfully processed
customize by adding a math function:
sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
ramp(x,y),stagger(x,y),logfreq(x,y,z),
vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z)
------------------------------------------------------------------------- */
int Variable::math_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
{
// word not a match to any math function
if (strcmp(word,"sqrt") && strcmp(word,"exp") &&
strcmp(word,"ln") && strcmp(word,"log") &&
strcmp(word,"sin") && strcmp(word,"cos") &&
strcmp(word,"tan") && strcmp(word,"asin") &&
strcmp(word,"acos") && strcmp(word,"atan") &&
strcmp(word,"atan2") && strcmp(word,"random") &&
strcmp(word,"normal") && strcmp(word,"ceil") &&
strcmp(word,"floor") && strcmp(word,"round") &&
strcmp(word,"ramp") && strcmp(word,"stagger") &&
strcmp(word,"logfreq") && strcmp(word,"vdisplace") &&
strcmp(word,"swiggle") && strcmp(word,"cwiggle"))
return 0;
// parse contents for arg1,arg2,arg3 separated by commas
// ptr1,ptr2 = location of 1st and 2nd comma, NULL if none
char *arg1,*arg2,*arg3;
char *ptr1,*ptr2;
ptr1 = find_next_comma(contents);
if (ptr1) {
*ptr1 = '\0';
ptr2 = find_next_comma(ptr1+1);
if (ptr2) *ptr2 = '\0';
} else ptr2 = NULL;
int n = strlen(contents) + 1;
arg1 = new char[n];
strcpy(arg1,contents);
int narg = 1;
if (ptr1) {
n = strlen(ptr1+1) + 1;
arg2 = new char[n];
strcpy(arg2,ptr1+1);
narg = 2;
} else arg2 = NULL;
if (ptr2) {
n = strlen(ptr2+1) + 1;
arg3 = new char[n];
strcpy(arg3,ptr2+1);
narg = 3;
} else arg3 = NULL;
// evaluate args
Tree *newtree;
double tmp,value1,value2,value3;
if (tree) {
newtree = new Tree();
Tree *argtree;
if (narg == 1) {
tmp = evaluate(arg1,&argtree);
newtree->left = argtree;
newtree->middle = newtree->right = NULL;
} else if (narg == 2) {
tmp = evaluate(arg1,&argtree);
newtree->left = argtree;
newtree->middle = NULL;
tmp = evaluate(arg2,&argtree);
newtree->right = argtree;
} else if (narg == 3) {
tmp = evaluate(arg1,&argtree);
newtree->left = argtree;
tmp = evaluate(arg2,&argtree);
newtree->middle = argtree;
tmp = evaluate(arg3,&argtree);
newtree->right = argtree;
}
treestack[ntreestack++] = newtree;
} else {
if (narg == 1) {
value1 = evaluate(arg1,NULL);
} else if (narg == 2) {
value1 = evaluate(arg1,NULL);
value2 = evaluate(arg2,NULL);
} else if (narg == 3) {
value1 = evaluate(arg1,NULL);
value2 = evaluate(arg2,NULL);
value3 = evaluate(arg3,NULL);
}
}
if (strcmp(word,"sqrt") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = SQRT;
else {
if (value1 < 0.0)
error->all(FLERR,"Sqrt of negative value in variable formula");
argstack[nargstack++] = sqrt(value1);
}
} else if (strcmp(word,"exp") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = EXP;
else argstack[nargstack++] = exp(value1);
} else if (strcmp(word,"ln") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = LN;
else {
if (value1 <= 0.0)
error->all(FLERR,"Log of zero/negative value in variable formula");
argstack[nargstack++] = log(value1);
}
} else if (strcmp(word,"log") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = LOG;
else {
if (value1 <= 0.0)
error->all(FLERR,"Log of zero/negative value in variable formula");
argstack[nargstack++] = log10(value1);
}
} else if (strcmp(word,"sin") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = SIN;
else argstack[nargstack++] = sin(value1);
} else if (strcmp(word,"cos") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = COS;
else argstack[nargstack++] = cos(value1);
} else if (strcmp(word,"tan") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = TAN;
else argstack[nargstack++] = tan(value1);
} else if (strcmp(word,"asin") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = ASIN;
else {
if (value1 < -1.0 || value1 > 1.0)
error->all(FLERR,"Arcsin of invalid value in variable formula");
argstack[nargstack++] = asin(value1);
}
} else if (strcmp(word,"acos") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = ACOS;
else {
if (value1 < -1.0 || value1 > 1.0)
error->all(FLERR,"Arccos of invalid value in variable formula");
argstack[nargstack++] = acos(value1);
}
} else if (strcmp(word,"atan") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = ATAN;
else argstack[nargstack++] = atan(value1);
} else if (strcmp(word,"atan2") == 0) {
if (narg != 2) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = ATAN2;
else argstack[nargstack++] = atan2(value1,value2);
} else if (strcmp(word,"random") == 0) {
if (narg != 3) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = RANDOM;
else {
if (randomequal == NULL) {
int seed = static_cast<int> (value3);
if (seed <= 0) error->all(FLERR,"Invalid math function in variable formula");
randomequal = new RanMars(lmp,seed);
}
argstack[nargstack++] = randomequal->uniform()*(value2-value1) + value1;
}
} else if (strcmp(word,"normal") == 0) {
if (narg != 3) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = NORMAL;
else {
if (value2 < 0.0)
error->all(FLERR,"Invalid math function in variable formula");
if (randomequal == NULL) {
int seed = static_cast<int> (value3);
if (seed <= 0) error->all(FLERR,"Invalid math function in variable formula");
randomequal = new RanMars(lmp,seed);
}
argstack[nargstack++] = value1 + value2*randomequal->gaussian();
}
} else if (strcmp(word,"ceil") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = CEIL;
else argstack[nargstack++] = ceil(value1);
} else if (strcmp(word,"floor") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = FLOOR;
else argstack[nargstack++] = floor(value1);
} else if (strcmp(word,"round") == 0) {
if (narg != 1) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = ROUND;
else argstack[nargstack++] = MYROUND(value1);
} else if (strcmp(word,"ramp") == 0) {
if (narg != 2) error->all(FLERR,"Invalid math function in variable formula");
if (update->whichflag == 0)
error->all(FLERR,"Cannot use ramp in variable formula between runs");
if (tree) newtree->type = RAMP;
else {
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
double value = value1 + delta*(value2-value1);
argstack[nargstack++] = value;
}
} else if (strcmp(word,"stagger") == 0) {
if (narg != 2) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = STAGGER;
else {
int ivalue1 = static_cast<int> (value1);
int ivalue2 = static_cast<int> (value2);
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
error->all(FLERR,"Invalid math function in variable formula");
int lower = update->ntimestep/ivalue1 * ivalue1;
int delta = update->ntimestep - lower;
double value;
if (delta < ivalue2) value = lower+ivalue2;
else value = lower+ivalue1;
argstack[nargstack++] = value;
}
} else if (strcmp(word,"logfreq") == 0) {
if (narg != 3) error->all(FLERR,"Invalid math function in variable formula");
if (tree) newtree->type = LOGFREQ;
else {
int ivalue1 = static_cast<int> (value1);
int ivalue2 = static_cast<int> (value2);
int ivalue3 = static_cast<int> (value3);
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
error->all(FLERR,"Invalid math function in variable formula");
double value;
if (update->ntimestep < ivalue1) value = ivalue1;
else {
int lower = ivalue1;
while (update->ntimestep >= ivalue3*lower) lower *= ivalue3;
int multiple = update->ntimestep/lower;
if (multiple < ivalue2) value = (multiple+1)*lower;
else value = lower*ivalue3;
}
argstack[nargstack++] = value;
}
} else if (strcmp(word,"vdisplace") == 0) {
if (narg != 2) error->all(FLERR,"Invalid math function in variable formula");
if (update->whichflag == 0)
error->all(FLERR,"Cannot use vdisplace in variable formula between runs");
if (tree) newtree->type = VDISPLACE;
else {
double delta = update->ntimestep - update->beginstep;
double value = value1 + value2*delta*update->dt;
argstack[nargstack++] = value;
}
} else if (strcmp(word,"swiggle") == 0) {
if (narg != 3) error->all(FLERR,"Invalid math function in variable formula");
if (update->whichflag == 0)
error->all(FLERR,"Cannot use swiggle in variable formula between runs");
if (tree) newtree->type = CWIGGLE;
else {
if (value3 == 0.0)
error->all(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/value3;
double value = value1 + value2*sin(omega*delta*update->dt);
argstack[nargstack++] = value;
}
} else if (strcmp(word,"cwiggle") == 0) {
if (narg != 3) error->all(FLERR,"Invalid math function in variable formula");
if (update->whichflag == 0)
error->all(FLERR,"Cannot use cwiggle in variable formula between runs");
if (tree) newtree->type = CWIGGLE;
else {
if (value3 == 0.0)
error->all(FLERR,"Invalid math function in variable formula");
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/value3;
double value = value1 + value2*(1.0-cos(omega*delta*update->dt));
argstack[nargstack++] = value;
}
}
delete [] arg1;
delete [] arg2;
delete [] arg3;
return 1;
}
/* ----------------------------------------------------------------------
process a group function in formula with optional region arg
push result onto tree or arg stack
word = group function
contents = str between parentheses with one,two,three args
return 0 if not a match, 1 if successfully processed
customize by adding a group function with optional region arg:
count(group),mass(group),charge(group),
xcm(group,dim),vcm(group,dim),fcm(group,dim),
bound(group,xmin),gyration(group),ke(group),angmom(group,dim),
torque(group,dim),inertia(group,dim),omega(group,dim)
------------------------------------------------------------------------- */
int Variable::group_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
{
// word not a match to any group function
if (strcmp(word,"count") && strcmp(word,"mass") &&
strcmp(word,"charge") && strcmp(word,"xcm") &&
strcmp(word,"vcm") && strcmp(word,"fcm") &&
strcmp(word,"bound") && strcmp(word,"gyration") &&
strcmp(word,"ke") && strcmp(word,"angmom") &&
strcmp(word,"torque") && strcmp(word,"inertia") &&
strcmp(word,"omega"))
return 0;
// parse contents for arg1,arg2,arg3 separated by commas
// ptr1,ptr2 = location of 1st and 2nd comma, NULL if none
char *arg1,*arg2,*arg3;
char *ptr1,*ptr2;
ptr1 = find_next_comma(contents);
if (ptr1) {
*ptr1 = '\0';
ptr2 = find_next_comma(ptr1+1);
if (ptr2) *ptr2 = '\0';
} else ptr2 = NULL;
int n = strlen(contents) + 1;
arg1 = new char[n];
strcpy(arg1,contents);
int narg = 1;
if (ptr1) {
n = strlen(ptr1+1) + 1;
arg2 = new char[n];
strcpy(arg2,ptr1+1);
narg = 2;
} else arg2 = NULL;
if (ptr2) {
n = strlen(ptr2+1) + 1;
arg3 = new char[n];
strcpy(arg3,ptr2+1);
narg = 3;
} else arg3 = NULL;
// group to operate on
int igroup = group->find(arg1);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
// match word to group function
double value;
if (strcmp(word,"count") == 0) {
if (narg == 1) value = group->count(igroup);
else if (narg == 2) value = group->count(igroup,region_function(arg2));
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"mass") == 0) {
if (narg == 1) value = group->mass(igroup);
else if (narg == 2) value = group->mass(igroup,region_function(arg2));
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"charge") == 0) {
if (narg == 1) value = group->charge(igroup);
else if (narg == 2) value = group->charge(igroup,region_function(arg2));
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"xcm") == 0) {
atom->check_mass();
double xcm[3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = xcm[0];
else if (strcmp(arg2,"y") == 0) value = xcm[1];
else if (strcmp(arg2,"z") == 0) value = xcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"vcm") == 0) {
atom->check_mass();
double vcm[3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->vcm(igroup,masstotal,vcm);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->vcm(igroup,masstotal,vcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = vcm[0];
else if (strcmp(arg2,"y") == 0) value = vcm[1];
else if (strcmp(arg2,"z") == 0) value = vcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"fcm") == 0) {
double fcm[3];
if (narg == 2) group->fcm(igroup,fcm);
else if (narg == 3) group->fcm(igroup,fcm,region_function(arg3));
else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = fcm[0];
else if (strcmp(arg2,"y") == 0) value = fcm[1];
else if (strcmp(arg2,"z") == 0) value = fcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"bound") == 0) {
double minmax[6];
if (narg == 2) group->bounds(igroup,minmax);
else if (narg == 3) group->bounds(igroup,minmax,region_function(arg3));
else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"xmin") == 0) value = minmax[0];
else if (strcmp(arg2,"xmax") == 0) value = minmax[1];
else if (strcmp(arg2,"ymin") == 0) value = minmax[2];
else if (strcmp(arg2,"ymax") == 0) value = minmax[3];
else if (strcmp(arg2,"zmin") == 0) value = minmax[4];
else if (strcmp(arg2,"zmax") == 0) value = minmax[5];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"gyration") == 0) {
atom->check_mass();
double xcm[3];
if (narg == 1) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
value = group->gyration(igroup,masstotal,xcm);
} else if (narg == 2) {
int iregion = region_function(arg2);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
value = group->gyration(igroup,masstotal,xcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"ke") == 0) {
if (narg == 1) value = group->ke(igroup);
else if (narg == 2) value = group->ke(igroup,region_function(arg2));
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"angmom") == 0) {
atom->check_mass();
double xcm[3],lmom[3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
group->angmom(igroup,xcm,lmom);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->angmom(igroup,xcm,lmom,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = lmom[0];
else if (strcmp(arg2,"y") == 0) value = lmom[1];
else if (strcmp(arg2,"z") == 0) value = lmom[2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"torque") == 0) {
atom->check_mass();
double xcm[3],tq[3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
group->torque(igroup,xcm,tq);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->torque(igroup,xcm,tq,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = tq[0];
else if (strcmp(arg2,"y") == 0) value = tq[1];
else if (strcmp(arg2,"z") == 0) value = tq[2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"inertia") == 0) {
atom->check_mass();
double xcm[3],inertia[3][3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
group->inertia(igroup,xcm,inertia);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->inertia(igroup,xcm,inertia,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"xx") == 0) value = inertia[0][0];
else if (strcmp(arg2,"yy") == 0) value = inertia[1][1];
else if (strcmp(arg2,"zz") == 0) value = inertia[2][2];
else if (strcmp(arg2,"xy") == 0) value = inertia[0][1];
else if (strcmp(arg2,"yz") == 0) value = inertia[1][2];
else if (strcmp(arg2,"xz") == 0) value = inertia[0][2];
else error->all(FLERR,"Invalid group function in variable formula");
} else if (strcmp(word,"omega") == 0) {
atom->check_mass();
double xcm[3],angmom[3],inertia[3][3],omega[3];
if (narg == 2) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
group->angmom(igroup,xcm,angmom);
group->inertia(igroup,xcm,inertia);
group->omega(angmom,inertia,omega);
} else if (narg == 3) {
int iregion = region_function(arg3);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->angmom(igroup,xcm,angmom,iregion);
group->inertia(igroup,xcm,inertia,iregion);
group->omega(angmom,inertia,omega);
} else error->all(FLERR,"Invalid group function in variable formula");
if (strcmp(arg2,"x") == 0) value = omega[0];
else if (strcmp(arg2,"y") == 0) value = omega[1];
else if (strcmp(arg2,"z") == 0) value = omega[2];
else error->all(FLERR,"Invalid group function in variable formula");
}
delete [] arg1;
delete [] arg2;
delete [] arg3;
// save value in tree or on argstack
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value;
return 1;
}
/* ---------------------------------------------------------------------- */
int Variable::region_function(char *id)
{
int iregion = domain->find_region(id);
if (iregion == -1)
error->all(FLERR,"Region ID in variable formula does not exist");
return iregion;
}
/* ----------------------------------------------------------------------
process a special function in formula
push result onto tree or arg stack
word = special function
contents = str between parentheses with one,two,three args
return 0 if not a match, 1 if successfully processed
customize by adding a special function:
sum(x),min(x),max(x),ave(x),trap(x),gmask(x),rmask(x),grmask(x,y)
------------------------------------------------------------------------- */
int Variable::special_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
{
// word not a match to any special function
if (strcmp(word,"sum") && strcmp(word,"min") && strcmp(word,"max") &&
strcmp(word,"ave") && strcmp(word,"trap") && strcmp(word,"gmask") &&
strcmp(word,"rmask") && strcmp(word,"grmask"))
return 0;
// parse contents for arg1,arg2,arg3 separated by commas
// ptr1,ptr2 = location of 1st and 2nd comma, NULL if none
char *arg1,*arg2,*arg3;
char *ptr1,*ptr2;
ptr1 = find_next_comma(contents);
if (ptr1) {
*ptr1 = '\0';
ptr2 = find_next_comma(ptr1+1);
if (ptr2) *ptr2 = '\0';
} else ptr2 = NULL;
int n = strlen(contents) + 1;
arg1 = new char[n];
strcpy(arg1,contents);
int narg = 1;
if (ptr1) {
n = strlen(ptr1+1) + 1;
arg2 = new char[n];
strcpy(arg2,ptr1+1);
narg = 2;
} else arg2 = NULL;
if (ptr2) {
n = strlen(ptr2+1) + 1;
arg3 = new char[n];
strcpy(arg3,ptr2+1);
narg = 3;
} else arg3 = NULL;
// special functions that operate on global vectors
if (strcmp(word,"sum") == 0 || strcmp(word,"min") == 0 ||
strcmp(word,"max") == 0 || strcmp(word,"ave") == 0 ||
strcmp(word,"trap") == 0) {
int method;
if (strcmp(word,"sum") == 0) method = SUM;
else if (strcmp(word,"min") == 0) method = XMIN;
else if (strcmp(word,"max") == 0) method = XMAX;
else if (strcmp(word,"ave") == 0) method = AVE;
else if (strcmp(word,"trap") == 0) method = TRAP;
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
Compute *compute = NULL;
Fix *fix = NULL;
int index,nvec,nstride;
if (strstr(arg1,"c_") == arg1) {
ptr1 = strchr(arg1,'[');
if (ptr1) {
ptr2 = ptr1;
index = int_between_brackets(ptr2);
*ptr1 = '\0';
} else index = 0;
int icompute = modify->find_compute(&arg1[2]);
if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula");
compute = modify->compute[icompute];
if (index == 0 && compute->vector_flag) {
if (update->whichflag == 0) {
if (compute->invoked_vector != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs is not current");
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
compute->compute_vector();
compute->invoked_flag |= INVOKED_VECTOR;
}
nvec = compute->size_vector;
nstride = 1;
} else if (index && compute->array_flag) {
if (index > compute->size_array_cols)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
if (update->whichflag == 0) {
if (compute->invoked_array != update->ntimestep)
error->all(FLERR,"Compute used in variable between runs is not current");
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
compute->compute_array();
compute->invoked_flag |= INVOKED_ARRAY;
}
nvec = compute->size_array_rows;
nstride = compute->size_array_cols;
} else error->all(FLERR,"Mismatched compute in variable formula");
} else if (strstr(arg1,"f_") == arg1) {
ptr1 = strchr(arg1,'[');
if (ptr1) {
ptr2 = ptr1;
index = int_between_brackets(ptr2);
*ptr1 = '\0';
} else index = 0;
int ifix = modify->find_fix(&arg1[2]);
if (ifix < 0) error->all(FLERR,"Invalid fix ID in variable formula");
fix = modify->fix[ifix];
if (index == 0 && fix->vector_flag) {
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
nvec = fix->size_vector;
nstride = 1;
} else if (index && fix->array_flag) {
if (index > fix->size_array_cols)
error->all(FLERR,"Variable formula fix array is accessed out-of-range");
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
nvec = fix->size_array_rows;
nstride = fix->size_array_cols;
} else error->all(FLERR,"Mismatched fix in variable formula");
} else error->all(FLERR,"Invalid special function in variable formula");
double value = 0.0;
if (method == XMIN) value = BIG;
if (method == XMAX) value = -BIG;
if (compute) {
double *vec;
if (index) vec = &compute->array[0][index-1];
else vec = compute->vector;
int j = 0;
for (int i = 0; i < nvec; i++) {
if (method == SUM) value += vec[j];
else if (method == XMIN) value = MIN(value,vec[j]);
else if (method == XMAX) value = MAX(value,vec[j]);
else if (method == AVE) value += vec[j];
else if (method == TRAP) {
if (i > 0 && i < nvec-1) value += vec[j];
else value += 0.5*vec[j];
}
j += nstride;
}
}
if (fix) {
double one;
for (int i = 0; i < nvec; i++) {
if (index) one = fix->compute_array(i,index-1);
else one = fix->compute_vector(i);
if (method == SUM) value += one;
else if (method == XMIN) value = MIN(value,one);
else if (method == XMAX) value = MAX(value,one);
else if (method == AVE) value += one;
else if (method == TRAP) {
if (i > 1 && i < nvec) value += one;
else value += 0.5*one;
}
}
}
if (method == AVE) value /= nvec;
delete [] arg1;
delete [] arg2;
delete [] arg3;
// save value in tree or on argstack
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value;
// mask special functions
} else if (strcmp(word,"gmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Gmask function in equal-style variable formula");
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
int igroup = group->find(arg1);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
Tree *newtree = new Tree();
newtree->type = GMASK;
newtree->ivalue1 = group->bitmask[igroup];
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else if (strcmp(word,"rmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Rmask function in equal-style variable formula");
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
int iregion = region_function(arg1);
Tree *newtree = new Tree();
newtree->type = RMASK;
newtree->ivalue1 = iregion;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else if (strcmp(word,"grmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Grmask function in equal-style variable formula");
if (narg != 2) error->all(FLERR,"Invalid special function in variable formula");
int igroup = group->find(arg1);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
int iregion = region_function(arg2);
Tree *newtree = new Tree();
newtree->type = RMASK;
newtree->ivalue1 = group->bitmask[igroup];
newtree->ivalue2 = iregion;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
}
return 1;
}
/* ----------------------------------------------------------------------
extract a global value from a per-atom quantity in a formula
flag = 0 -> word is an atom vector
flag = 1 -> vector is a per-atom compute or fix quantity with nstride
id = positive global ID of atom, converted to local index
push result onto tree or arg stack
customize by adding an atom vector:
mass,type,x,y,z,vx,vy,vz,fx,fy,fz
------------------------------------------------------------------------- */
void Variable::peratom2global(int flag, char *word,
double *vector, int nstride, int id,
Tree **tree, Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
{
if (atom->map_style == 0)
error->all(FLERR,"Indexed per-atom vector in variable formula without atom map");
int index = atom->map(id);
double mine;
if (index >= 0 && index < atom->nlocal) {
if (flag == 0) {
if (strcmp(word,"mass") == 0) {
if (atom->rmass) mine = atom->rmass[index];
else mine = atom->mass[atom->type[index]];
}
else if (strcmp(word,"type") == 0) mine = atom->type[index];
else if (strcmp(word,"x") == 0) mine = atom->x[index][0];
else if (strcmp(word,"y") == 0) mine = atom->x[index][1];
else if (strcmp(word,"z") == 0) mine = atom->x[index][2];
else if (strcmp(word,"vx") == 0) mine = atom->v[index][0];
else if (strcmp(word,"vy") == 0) mine = atom->v[index][1];
else if (strcmp(word,"vz") == 0) mine = atom->v[index][2];
else if (strcmp(word,"fx") == 0) mine = atom->f[index][0];
else if (strcmp(word,"fy") == 0) mine = atom->f[index][1];
else if (strcmp(word,"fz") == 0) mine = atom->f[index][2];
else error->one(FLERR,"Invalid atom vector in variable formula");
} else mine = vector[index*nstride];
} else mine = 0.0;
double value;
MPI_Allreduce(&mine,&value,1,MPI_DOUBLE,MPI_SUM,world);
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value;
}
/* ----------------------------------------------------------------------
check if word matches an atom vector
return 1 if yes, else 0
customize by adding an atom vector:
mass,type,x,y,z,vx,vy,vz,fx,fy,fz
------------------------------------------------------------------------- */
int Variable::is_atom_vector(char *word)
{
if (strcmp(word,"mass") == 0) return 1;
if (strcmp(word,"type") == 0) return 1;
if (strcmp(word,"x") == 0) return 1;
if (strcmp(word,"y") == 0) return 1;
if (strcmp(word,"z") == 0) return 1;
if (strcmp(word,"vx") == 0) return 1;
if (strcmp(word,"vy") == 0) return 1;
if (strcmp(word,"vz") == 0) return 1;
if (strcmp(word,"fx") == 0) return 1;
if (strcmp(word,"fy") == 0) return 1;
if (strcmp(word,"fz") == 0) return 1;
return 0;
}
/* ----------------------------------------------------------------------
process an atom vector in formula
push result onto tree
word = atom vector
customize by adding an atom vector:
mass,type,x,y,z,vx,vy,vz,fx,fy,fz
------------------------------------------------------------------------- */
void Variable::atom_vector(char *word, Tree **tree,
Tree **treestack, int &ntreestack)
{
if (tree == NULL)
error->all(FLERR,"Atom vector in equal-style variable formula");
Tree *newtree = new Tree();
newtree->type = ATOMARRAY;
newtree->nstride = 3;
newtree->left = newtree->middle = newtree->right = NULL;
treestack[ntreestack++] = newtree;
if (strcmp(word,"mass") == 0) {
if (atom->rmass) {
newtree->nstride = 1;
newtree->array = atom->rmass;
} else {
newtree->type = TYPEARRAY;
newtree->array = atom->mass;
}
} else if (strcmp(word,"type") == 0) {
newtree->type = INTARRAY;
newtree->nstride = 1;
newtree->iarray = atom->type;
}
else if (strcmp(word,"x") == 0) newtree->array = &atom->x[0][0];
else if (strcmp(word,"y") == 0) newtree->array = &atom->x[0][1];
else if (strcmp(word,"z") == 0) newtree->array = &atom->x[0][2];
else if (strcmp(word,"vx") == 0) newtree->array = &atom->v[0][0];
else if (strcmp(word,"vy") == 0) newtree->array = &atom->v[0][1];
else if (strcmp(word,"vz") == 0) newtree->array = &atom->v[0][2];
else if (strcmp(word,"fx") == 0) newtree->array = &atom->f[0][0];
else if (strcmp(word,"fy") == 0) newtree->array = &atom->f[0][1];
else if (strcmp(word,"fz") == 0) newtree->array = &atom->f[0][2];
}
/* ----------------------------------------------------------------------
check if word matches a constant
return 1 if yes, else 0
customize by adding a constant: PI
------------------------------------------------------------------------- */
int Variable::is_constant(char *word)
{
if (strcmp(word,"PI") == 0) return 1;
return 0;
}
/* ----------------------------------------------------------------------
process a constant in formula
customize by adding a constant: PI
------------------------------------------------------------------------- */
double Variable::constant(char *word)
{
if (strcmp(word,"PI") == 0) return MY_PI;
return 0.0;
}
/* ----------------------------------------------------------------------
read a floating point value from a string
generate an error if not a legitimate floating point value
------------------------------------------------------------------------- */
double Variable::numeric(char *str)
{
int n = strlen(str);
for (int i = 0; i < n; i++) {
if (isdigit(str[i])) continue;
if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue;
if (str[i] == 'e' || str[i] == 'E') continue;
error->all(FLERR,"Expected floating point parameter in variable definition");
}
return atof(str);
}
/* ----------------------------------------------------------------------
read an integer value from a string
generate an error if not a legitimate integer value
------------------------------------------------------------------------- */
int Variable::inumeric(char *str)
{
int n = strlen(str);
for (int i = 0; i < n; i++) {
if (isdigit(str[i]) || str[i] == '-' || str[i] == '+') continue;
error->all(FLERR,"Expected integer parameter in variable definition");
}
return atoi(str);
}
/* ----------------------------------------------------------------------
find next comma in str
skip commas inside one or more nested parenthesis
only return ptr to comma at level 0, else NULL if not found
------------------------------------------------------------------------- */
char *Variable::find_next_comma(char *str)
{
int level = 0;
for (char *p = str; *p; ++p) {
if ('(' == *p) level++;
else if (')' == *p) level--;
else if (',' == *p && !level) return p;
}
return NULL;
}
/* ----------------------------------------------------------------------
debug routine for printing formula tree recursively
------------------------------------------------------------------------- */
void Variable::print_tree(Tree *tree, int level)
{
printf("TREE %d: %d %g\n",level,tree->type,tree->value);
if (tree->left) print_tree(tree->left,level+1);
if (tree->middle) print_tree(tree->middle,level+1);
if (tree->right) print_tree(tree->right,level+1);
return;
}
/* ----------------------------------------------------------------------
recursive evaluation of string str
called from "if" command in input script
str is a boolean expression containing one or more items:
number = 0.0, -5.45, 2.8e-4, ...
math operation = (),x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y
------------------------------------------------------------------------- */
double Variable::evaluate_boolean(char *str)
{
int op,opprevious;
double value1,value2;
char onechar;
double argstack[MAXLEVEL];
int opstack[MAXLEVEL];
int nargstack = 0;
int nopstack = 0;
int i = 0;
int expect = ARG;
while (1) {
onechar = str[i];
// whitespace: just skip
if (isspace(onechar)) i++;
// ----------------
// parentheses: recursively evaluate contents of parens
// ----------------
else if (onechar == '(') {
if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command");
expect = OP;
char *contents;
i = find_matching_paren(str,i,contents);
i++;
// evaluate contents and push on stack
argstack[nargstack++] = evaluate_boolean(contents);
delete [] contents;
// ----------------
// number: push value onto stack
// ----------------
} else if (isdigit(onechar) || onechar == '.' || onechar == '-') {
if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command");
expect = OP;
// istop = end of number, including scientific notation
int istart = i++;
while (isdigit(str[i]) || str[i] == '.') i++;
if (str[i] == 'e' || str[i] == 'E') {
i++;
if (str[i] == '+' || str[i] == '-') i++;
while (isdigit(str[i])) i++;
}
int istop = i - 1;
int n = istop - istart + 1;
char *number = new char[n+1];
strncpy(number,&str[istart],n);
number[n] = '\0';
argstack[nargstack++] = atof(number);
delete [] number;
// ----------------
// Boolean operator, including end-of-string
// ----------------
} else if (strchr("<>=!&|\0",onechar)) {
if (onechar == '=') {
if (str[i+1] != '=')
error->all(FLERR,"Invalid Boolean syntax in if command");
op = EQ;
i++;
} else if (onechar == '!') {
if (str[i+1] == '=') {
op = NE;
i++;
} else op = NOT;
} else if (onechar == '<') {
if (str[i+1] != '=') op = LT;
else {
op = LE;
i++;
}
} else if (onechar == '>') {
if (str[i+1] != '=') op = GT;
else {
op = GE;
i++;
}
} else if (onechar == '&') {
if (str[i+1] != '&')
error->all(FLERR,"Invalid Boolean syntax in if command");
op = AND;
i++;
} else if (onechar == '|') {
if (str[i+1] != '|')
error->all(FLERR,"Invalid Boolean syntax in if command");
op = OR;
i++;
} else op = DONE;
i++;
if (op == NOT && expect == ARG) {
opstack[nopstack++] = op;
continue;
}
if (expect == ARG) error->all(FLERR,"Invalid Boolean syntax in if command");
expect = ARG;
// evaluate stack as deep as possible while respecting precedence
// before pushing current op onto stack
while (nopstack && precedence[opstack[nopstack-1]] >= precedence[op]) {
opprevious = opstack[--nopstack];
value2 = argstack[--nargstack];
if (opprevious != NOT) value1 = argstack[--nargstack];
if (opprevious == NOT) {
if (value2 == 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == EQ) {
if (value1 == value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == NE) {
if (value1 != value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LT) {
if (value1 < value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LE) {
if (value1 <= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GT) {
if (value1 > value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GE) {
if (value1 >= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == AND) {
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == OR) {
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
}
}
// if end-of-string, break out of entire formula evaluation loop
if (op == DONE) break;
// push current operation onto stack
opstack[nopstack++] = op;
} else error->all(FLERR,"Invalid Boolean syntax in if command");
}
if (nopstack) error->all(FLERR,"Invalid Boolean syntax in if command");
if (nargstack != 1) error->all(FLERR,"Invalid Boolean syntax in if command");
return argstack[0];
}
diff --git a/src/verlet.cpp b/src/verlet.cpp
index c6d53e524..223f02c95 100644
--- a/src/verlet.cpp
+++ b/src/verlet.cpp
@@ -1,425 +1,410 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "string.h"
#include "verlet.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "atom.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "kspace.h"
#include "output.h"
#include "update.h"
#include "modify.h"
#include "compute.h"
#include "fix.h"
#include "timer.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Verlet::Verlet(LAMMPS *lmp, int narg, char **arg) :
Integrate(lmp, narg, arg) {}
/* ----------------------------------------------------------------------
initialization before run
------------------------------------------------------------------------- */
void Verlet::init()
{
// warn if no fixes
if (modify->nfix == 0 && comm->me == 0)
error->warning(FLERR,"No fixes defined, atoms won't move");
// virial_style:
// 1 if computed explicitly by pair->compute via sum over pair interactions
// 2 if computed implicitly by pair->virial_fdotr_compute via sum over ghosts
if (force->newton_pair) virial_style = 2;
else virial_style = 1;
// setup lists of computes for global and per-atom PE and pressure
ev_setup();
+ // detect if fix omp is present for clearing force arrays
+
+ int ifix = modify->find_fix("package_omp");
+ if (ifix >= 0) external_force_clear = 1;
+
// set flags for what arrays to clear in force_clear()
// need to clear additionals arrays if they exist
torqueflag = 0;
if (atom->torque_flag) torqueflag = 1;
erforceflag = 0;
if (atom->erforce_flag) erforceflag = 1;
e_flag = 0;
if (atom->e_flag) e_flag = 1;
rho_flag = 0;
if (atom->rho_flag) rho_flag = 1;
// orthogonal vs triclinic simulation box
triclinic = domain->triclinic;
}
/* ----------------------------------------------------------------------
setup before run
------------------------------------------------------------------------- */
void Verlet::setup()
{
if (comm->me == 0 && screen) fprintf(screen,"Setting up run ...\n");
update->setupflag = 1;
// setup domain, communication and neighboring
// acquire ghosts
// build neighbor lists
atom->setup();
modify->setup_pre_exchange();
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
comm->exchange();
if (atom->sortfreq > 0) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build();
neighbor->ncalls = 0;
// compute all forces
ev_set(update->ntimestep);
force_clear();
modify->setup_pre_force(vflag);
if (force->pair) force->pair->compute(eflag,vflag);
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
}
if (force->newton) comm->reverse_comm();
modify->setup(vflag);
output->setup(1);
update->setupflag = 0;
}
/* ----------------------------------------------------------------------
setup without output
flag = 0 = just force calculation
flag = 1 = reneighbor and force calculation
------------------------------------------------------------------------- */
void Verlet::setup_minimal(int flag)
{
update->setupflag = 1;
// setup domain, communication and neighboring
// acquire ghosts
// build neighbor lists
if (flag) {
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
comm->exchange();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
neighbor->build();
neighbor->ncalls = 0;
}
// compute all forces
ev_set(update->ntimestep);
force_clear();
modify->setup_pre_force(vflag);
if (force->pair) force->pair->compute(eflag,vflag);
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
}
if (force->kspace) {
force->kspace->setup();
force->kspace->compute(eflag,vflag);
}
if (force->newton) comm->reverse_comm();
modify->setup(vflag);
update->setupflag = 0;
}
/* ----------------------------------------------------------------------
run for N steps
------------------------------------------------------------------------- */
void Verlet::run(int n)
{
bigint ntimestep;
int nflag,sortflag;
int n_post_integrate = modify->n_post_integrate;
int n_pre_exchange = modify->n_pre_exchange;
int n_pre_neighbor = modify->n_pre_neighbor;
int n_pre_force = modify->n_pre_force;
int n_post_force = modify->n_post_force;
int n_end_of_step = modify->n_end_of_step;
if (atom->sortfreq > 0) sortflag = 1;
else sortflag = 0;
for (int i = 0; i < n; i++) {
ntimestep = ++update->ntimestep;
ev_set(ntimestep);
// initial time integration
modify->initial_integrate(vflag);
if (n_post_integrate) modify->post_integrate();
// regular communication vs neighbor list rebuild
nflag = neighbor->decide();
if (nflag == 0) {
timer->stamp();
comm->forward_comm();
timer->stamp(TIME_COMM);
} else {
if (n_pre_exchange) modify->pre_exchange();
if (triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
if (domain->box_change) {
domain->reset_box();
comm->setup();
if (neighbor->style) neighbor->setup_bins();
}
timer->stamp();
comm->exchange();
if (sortflag && ntimestep >= atom->nextsort) atom->sort();
comm->borders();
if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
timer->stamp(TIME_COMM);
if (n_pre_neighbor) modify->pre_neighbor();
neighbor->build();
timer->stamp(TIME_NEIGHBOR);
}
// force computations
force_clear();
if (n_pre_force) modify->pre_force(vflag);
timer->stamp();
if (force->pair) {
force->pair->compute(eflag,vflag);
timer->stamp(TIME_PAIR);
}
if (atom->molecular) {
if (force->bond) force->bond->compute(eflag,vflag);
if (force->angle) force->angle->compute(eflag,vflag);
if (force->dihedral) force->dihedral->compute(eflag,vflag);
if (force->improper) force->improper->compute(eflag,vflag);
timer->stamp(TIME_BOND);
}
if (force->kspace) {
force->kspace->compute(eflag,vflag);
timer->stamp(TIME_KSPACE);
}
// reverse communication of forces
if (force->newton) {
comm->reverse_comm();
timer->stamp(TIME_COMM);
}
// force modifications, final time integration, diagnostics
if (n_post_force) modify->post_force(vflag);
modify->final_integrate();
if (n_end_of_step) modify->end_of_step();
// all output
if (ntimestep == output->next) {
timer->stamp();
output->write(ntimestep);
timer->stamp(TIME_OUTPUT);
}
}
}
/* ---------------------------------------------------------------------- */
void Verlet::cleanup()
{
modify->post_run();
}
/* ----------------------------------------------------------------------
clear force on own & ghost atoms
setup and clear other arrays as needed
------------------------------------------------------------------------- */
void Verlet::force_clear()
{
+ if (external_force_clear) return;
int i;
if (external_force_clear) return;
// clear force on all particles
// if either newton flag is set, also include ghosts
+ // when using threads always clear all forces.
if (neighbor->includegroup == 0) {
int nall;
if (force->newton) nall = atom->nlocal + atom->nghost;
else nall = atom->nlocal;
- int ntot = nall * comm->nthreads;
-
- double **f = atom->f;
- for (i = 0; i < ntot; i++) {
- f[i][0] = 0.0;
- f[i][1] = 0.0;
- f[i][2] = 0.0;
- }
-
- if (torqueflag) {
- double **torque = atom->torque;
- for (i = 0; i < nall; i++) {
- torque[i][0] = 0.0;
- torque[i][1] = 0.0;
- torque[i][2] = 0.0;
- }
- }
- if (erforceflag) {
- double *erforce = atom->erforce;
- for (i = 0; i < nall; i++) erforce[i] = 0.0;
- }
+ size_t nbytes = sizeof(double) * nall;
- if (e_flag) {
- double *de = atom->de;
- for (i = 0; i < nall; i++) de[i] = 0.0;
- }
-
- if (rho_flag) {
- double *drho = atom->drho;
- for (i = 0; i < nall; i++) drho[i] = 0.0;
+ if (nbytes) {
+ memset(&(atom->f[0][0]),0,3*nbytes);
+ if (torqueflag) memset(&(atom->torque[0][0]),0,3*nbytes);
+ if (erforceflag) memset(&(atom->erforce[0]), 0, nbytes);
+ if (e_flag) memset(&(atom->de[0]), 0, nbytes);
+ if (rho_flag) memset(&(atom->drho[0]), 0, nbytes);
}
// neighbor includegroup flag is set
// clear force only on initial nfirst particles
// if either newton flag is set, also include ghosts
} else {
int nall = atom->nfirst;
double **f = atom->f;
for (i = 0; i < nall; i++) {
f[i][0] = 0.0;
f[i][1] = 0.0;
f[i][2] = 0.0;
}
if (torqueflag) {
double **torque = atom->torque;
for (i = 0; i < nall; i++) {
torque[i][0] = 0.0;
torque[i][1] = 0.0;
torque[i][2] = 0.0;
}
}
if (erforceflag) {
double *erforce = atom->erforce;
for (i = 0; i < nall; i++) erforce[i] = 0.0;
}
if (e_flag) {
double *de = atom->de;
for (i = 0; i < nall; i++) de[i] = 0.0;
}
if (rho_flag) {
double *drho = atom->drho;
for (i = 0; i < nall; i++) drho[i] = 0.0;
}
if (force->newton) {
nall = atom->nlocal + atom->nghost;
for (i = atom->nlocal; i < nall; i++) {
f[i][0] = 0.0;
f[i][1] = 0.0;
f[i][2] = 0.0;
}
if (torqueflag) {
double **torque = atom->torque;
for (i = atom->nlocal; i < nall; i++) {
torque[i][0] = 0.0;
torque[i][1] = 0.0;
torque[i][2] = 0.0;
}
}
if (erforceflag) {
double *erforce = atom->erforce;
for (i = atom->nlocal; i < nall; i++) erforce[i] = 0.0;
}
if (e_flag) {
double *de = atom->de;
for (i = 0; i < nall; i++) de[i] = 0.0;
}
if (rho_flag) {
double *drho = atom->drho;
for (i = 0; i < nall; i++) drho[i] = 0.0;
}
}
}
}
diff --git a/src/verlet.h b/src/verlet.h
index 327f72b83..3004b8650 100644
--- a/src/verlet.h
+++ b/src/verlet.h
@@ -1,48 +1,48 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef INTEGRATE_CLASS
IntegrateStyle(verlet,Verlet)
#else
#ifndef LMP_VERLET_H
#define LMP_VERLET_H
#include "integrate.h"
namespace LAMMPS_NS {
class Verlet : public Integrate {
public:
Verlet(class LAMMPS *, int, char **);
virtual ~Verlet() {}
- void init();
- void setup();
- void setup_minimal(int);
- void run(int);
+ virtual void init();
+ virtual void setup();
+ virtual void setup_minimal(int);
+ virtual void run(int);
void cleanup();
protected:
int triclinic; // 0 if domain is orthog, 1 if triclinic
int torqueflag,erforceflag;
int e_flag,rho_flag;
void force_clear();
};
}
#endif
#endif
diff --git a/src/version.h b/src/version.h
index 90bc9b3fe..86983c6d9 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "9 Nov 2011"
+#define LAMMPS_VERSION "13 Dec 2011"

Event Timeline